Skip to content

Commit faeaf4a

Browse files
committed
Compute diagnostics of a field body iff it has one
1 parent 2622160 commit faeaf4a

File tree

10 files changed

+64
-22
lines changed

10 files changed

+64
-22
lines changed

src/tools/rust-analyzer/crates/hir-def/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ pub type LocalModuleId = Idx<nameres::ModuleData>;
519519
pub struct FieldId {
520520
pub parent: VariantId,
521521
pub local_id: LocalFieldId,
522+
pub has_default: bool,
522523
}
523524

524525
impl FieldId {

src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,9 +1167,11 @@ impl InferenceContext<'_> {
11671167
};
11681168
let mut p = place.clone();
11691169
self.current_capture_span_stack.push(MirSpan::PatId(arg));
1170+
let has_default = vd.fields()[local_id].has_default;
11701171
p.projections.push(ProjectionElem::Field(Either::Left(FieldId {
11711172
parent: variant,
11721173
local_id,
1174+
has_default,
11731175
})));
11741176
self.consume_with_pat(p, arg);
11751177
self.current_capture_span_stack.pop();
@@ -1219,12 +1221,13 @@ impl InferenceContext<'_> {
12191221
.iter()
12201222
.zip(fields.clone())
12211223
.chain(ar.iter().rev().zip(fields.rev()));
1222-
for (&arg, (i, _)) in it {
1224+
for (&arg, (i, d)) in it {
12231225
let mut p = place.clone();
12241226
self.current_capture_span_stack.push(MirSpan::PatId(arg));
12251227
p.projections.push(ProjectionElem::Field(Either::Left(FieldId {
12261228
parent: variant,
12271229
local_id: i,
1230+
has_default: d.has_default,
12281231
})));
12291232
self.consume_with_pat(p, arg);
12301233
self.current_capture_span_stack.pop();

src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,13 +1746,17 @@ impl InferenceContext<'_> {
17461746
});
17471747
}
17481748
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
1749-
let local_id = self.db.struct_data(*s).variant_data.field(name)?;
1750-
let field = FieldId { parent: (*s).into(), local_id };
1749+
let vd = &self.db.struct_data(*s).variant_data;
1750+
let local_id = vd.field(name)?;
1751+
let has_default = vd.fields()[local_id].has_default;
1752+
let field = FieldId { parent: (*s).into(), local_id, has_default };
17511753
(field, parameters.clone())
17521754
}
17531755
TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
1754-
let local_id = self.db.union_data(*u).variant_data.field(name)?;
1755-
let field = FieldId { parent: (*u).into(), local_id };
1756+
let vd = &self.db.union_data(*u).variant_data;
1757+
let local_id = vd.field(name)?;
1758+
let has_default = vd.fields()[local_id].has_default;
1759+
let field = FieldId { parent: (*u).into(), local_id, has_default };
17561760
(field, parameters.clone())
17571761
}
17581762
_ => return None,

src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -870,12 +870,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
870870
.map(|(i, it)| match it {
871871
Some(it) => it,
872872
None => {
873+
let local_id =
874+
LocalFieldId::from_raw(RawIdx::from(i as u32));
875+
let has_default =
876+
variant_data.fields()[local_id].has_default;
873877
let p = sp.project(
874878
ProjectionElem::Field(Either::Left(FieldId {
875879
parent: variant_id,
876-
local_id: LocalFieldId::from_raw(RawIdx::from(
877-
i as u32,
878-
)),
880+
local_id,
881+
has_default,
879882
})),
880883
&mut self.result.projection_store,
881884
);
@@ -897,10 +900,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
897900
};
898901
let local_id =
899902
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
903+
let has_default = variant_data.fields()[local_id].has_default;
900904
let place = place.project(
901905
PlaceElem::Field(Either::Left(FieldId {
902906
parent: union_id.into(),
903907
local_id,
908+
has_default,
904909
})),
905910
&mut self.result.projection_store,
906911
);

src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,12 @@ impl MirLowerCtx<'_> {
632632
.map(|x| {
633633
let field_id =
634634
variant_data.field(&x.name).ok_or(MirLowerError::UnresolvedField)?;
635+
let has_default = variant_data.fields()[field_id].has_default;
635636
Ok((
636637
PlaceElem::Field(Either::Left(FieldId {
637638
parent: v,
638639
local_id: field_id,
640+
has_default,
639641
})),
640642
x.pat,
641643
))
@@ -644,8 +646,12 @@ impl MirLowerCtx<'_> {
644646
self.pattern_match_adt(current, current_else, it.into_iter(), cond_place, mode)?
645647
}
646648
AdtPatternShape::Tuple { args, ellipsis } => {
647-
let fields = variant_data.fields().iter().map(|(x, _)| {
648-
PlaceElem::Field(Either::Left(FieldId { parent: v, local_id: x }))
649+
let fields = variant_data.fields().iter().map(|(x, d)| {
650+
PlaceElem::Field(Either::Left(FieldId {
651+
parent: v,
652+
local_id: x,
653+
has_default: d.has_default,
654+
}))
649655
});
650656
self.pattern_match_tuple_like(
651657
current,

src/tools/rust-analyzer/crates/hir/src/display.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ impl HirDisplay for Struct {
252252
f.write_char('(')?;
253253
let mut it = variant_data.fields().iter().peekable();
254254

255-
while let Some((id, _)) = it.next() {
256-
let field = Field { parent: (*self).into(), id };
255+
while let Some((id, d)) = it.next() {
256+
let field = Field { parent: (*self).into(), id, has_default: d.has_default };
257257
write_visibility(module_id, field.visibility(f.db), f)?;
258258
field.ty(f.db).hir_fmt(f)?;
259259
if it.peek().is_some() {

src/tools/rust-analyzer/crates/hir/src/from_id.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,13 @@ impl From<VariantDef> for VariantId {
237237

238238
impl From<Field> for FieldId {
239239
fn from(def: Field) -> Self {
240-
FieldId { parent: def.parent.into(), local_id: def.id }
240+
FieldId { parent: def.parent.into(), local_id: def.id, has_default: def.has_default }
241241
}
242242
}
243243

244244
impl From<FieldId> for Field {
245245
fn from(def: FieldId) -> Self {
246-
Field { parent: def.parent.into(), id: def.local_id }
246+
Field { parent: def.parent.into(), id: def.local_id, has_default: def.has_default }
247247
}
248248
}
249249

src/tools/rust-analyzer/crates/hir/src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ impl ModuleDef {
423423
};
424424
if let Some(fields) = fields {
425425
for field in fields {
426+
if !field.has_default {
427+
continue;
428+
}
426429
let def: DefWithBody = field.into();
427430
def.diagnostics(db, &mut acc, style_lints);
428431
}
@@ -1249,6 +1252,7 @@ impl From<&Field> for DefWithBodyId {
12491252
pub struct Field {
12501253
pub(crate) parent: VariantDef,
12511254
pub(crate) id: LocalFieldId,
1255+
pub(crate) has_default: bool,
12521256
}
12531257

12541258
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
@@ -1414,7 +1418,7 @@ impl Struct {
14141418
.variant_data
14151419
.fields()
14161420
.iter()
1417-
.map(|(id, _)| Field { parent: self.into(), id })
1421+
.map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default })
14181422
.collect()
14191423
}
14201424

@@ -1476,7 +1480,7 @@ impl Union {
14761480
.variant_data
14771481
.fields()
14781482
.iter()
1479-
.map(|(id, _)| Field { parent: self.into(), id })
1483+
.map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default })
14801484
.collect()
14811485
}
14821486

@@ -1606,7 +1610,7 @@ impl Variant {
16061610
self.variant_data(db)
16071611
.fields()
16081612
.iter()
1609-
.map(|(id, _)| Field { parent: self.into(), id })
1613+
.map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default })
16101614
.collect()
16111615
}
16121616

@@ -5162,10 +5166,13 @@ impl Type {
51625166
_ => return Vec::new(),
51635167
};
51645168

5169+
let var_data = db.variant_data(variant_id);
5170+
let fields = var_data.fields();
51655171
db.field_types(variant_id)
51665172
.iter()
51675173
.map(|(local_id, ty)| {
5168-
let def = Field { parent: variant_id.into(), id: local_id };
5174+
let has_default = fields[local_id].has_default;
5175+
let def = Field { parent: variant_id.into(), id: local_id, has_default };
51695176
let ty = ty.clone().substitute(Interner, substs);
51705177
(def, self.derived(ty))
51715178
})

src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ impl ChildBySource for VariantId {
160160
let arena_map = arena_map.as_ref();
161161
let parent = *self;
162162
for (local_id, source) in arena_map.value.iter() {
163-
let id = FieldId { parent, local_id };
163+
let has_default = match source {
164+
Either::Left(_) => false,
165+
Either::Right(rec) => rec.expr().is_some(),
166+
};
167+
let id = FieldId { parent, local_id, has_default };
164168
match source.clone() {
165169
Either::Left(source) => res[keys::TUPLE_FIELD].insert(AstPtr::new(&source), id),
166170
Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id),

src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,10 @@ impl SourceAnalyzer {
630630
let (adt, subst) = self.infer.as_ref()?.type_of_expr_or_pat(expr_id)?.as_adt()?;
631631
let variant = self.infer.as_ref()?.variant_resolution_for_expr_or_pat(expr_id)?;
632632
let variant_data = variant.variant_data(db.upcast());
633-
let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
633+
let fields = variant_data.fields();
634+
let local_id = variant_data.field(&local_name)?;
635+
let field =
636+
FieldId { parent: variant, local_id, has_default: fields[local_id].has_default };
634637
let field_ty =
635638
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
636639
Some((
@@ -651,7 +654,10 @@ impl SourceAnalyzer {
651654
let pat_id = self.pat_id(&record_pat.into())?;
652655
let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?;
653656
let variant_data = variant.variant_data(db.upcast());
654-
let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
657+
let fields = variant_data.fields();
658+
let local_id = variant_data.field(&field_name)?;
659+
let field =
660+
FieldId { parent: variant, local_id, has_default: fields[local_id].has_default };
655661
let (adt, subst) = self.infer.as_ref()?.type_of_pat.get(pat_id)?.as_adt()?;
656662
let field_ty =
657663
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
@@ -1060,11 +1066,17 @@ impl SourceAnalyzer {
10601066
missing_fields: Vec<LocalFieldId>,
10611067
) -> Vec<(Field, Type)> {
10621068
let field_types = db.field_types(variant);
1069+
let var_data = db.variant_data(variant);
1070+
let fields = var_data.fields();
10631071

10641072
missing_fields
10651073
.into_iter()
10661074
.map(|local_id| {
1067-
let field = FieldId { parent: variant, local_id };
1075+
let field = FieldId {
1076+
parent: variant,
1077+
local_id,
1078+
has_default: fields[local_id].has_default,
1079+
};
10681080
let ty = field_types[local_id].clone().substitute(Interner, substs);
10691081
(field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty))
10701082
})

0 commit comments

Comments
 (0)