From 55d385182055b655e7d807eb473dcbc32f1fb17f Mon Sep 17 00:00:00 2001 From: David Barsky Date: Mon, 27 Jan 2025 17:20:11 -0500 Subject: [PATCH] Back out "Remove `has_default` from `FieldId`" This backs out commit 8aa6c09fcee6270c787a6f00615d76343fbe5c07. --- crates/hir-def/src/lib.rs | 1 + crates/hir-ty/src/infer/closure.rs | 5 ++- crates/hir-ty/src/infer/expr.rs | 6 ++-- crates/hir-ty/src/mir/lower.rs | 5 +++ .../hir-ty/src/mir/lower/pattern_matching.rs | 10 ++++-- crates/hir-ty/src/tests.rs | 8 ++--- crates/hir/src/display.rs | 4 +-- crates/hir/src/from_id.rs | 4 +-- crates/hir/src/lib.rs | 34 +++++++++---------- crates/hir/src/semantics/child_by_source.rs | 6 +++- crates/hir/src/source_analyzer.rs | 16 +++++++-- 11 files changed, 64 insertions(+), 35 deletions(-) diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 6bc8741c33..80aa551660 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -519,6 +519,7 @@ pub type LocalModuleId = Idx; pub struct FieldId { pub parent: VariantId, pub local_id: LocalFieldId, + pub has_default: bool, } impl FieldId { diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 0e9aed4160..def0cb705d 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -1167,9 +1167,11 @@ impl InferenceContext<'_> { }; let mut p = place.clone(); self.current_capture_span_stack.push(MirSpan::PatId(arg)); + let has_default = vd.fields()[local_id].has_default; p.projections.push(ProjectionElem::Field(Either::Left(FieldId { parent: variant, local_id, + has_default, }))); self.consume_with_pat(p, arg); self.current_capture_span_stack.pop(); @@ -1219,12 +1221,13 @@ impl InferenceContext<'_> { .iter() .zip(fields.clone()) .chain(ar.iter().rev().zip(fields.rev())); - for (&arg, (i, _)) in it { + for (&arg, (i, d)) in it { let mut p = place.clone(); self.current_capture_span_stack.push(MirSpan::PatId(arg)); p.projections.push(ProjectionElem::Field(Either::Left(FieldId { parent: variant, local_id: i, + has_default: d.has_default, }))); self.consume_with_pat(p, arg); self.current_capture_span_stack.pop(); diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 179565440c..b91f32b09e 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -1748,13 +1748,15 @@ impl InferenceContext<'_> { TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { let vd = &self.db.struct_data(*s).variant_data; let local_id = vd.field(name)?; - let field = FieldId { parent: (*s).into(), local_id }; + let has_default = vd.fields()[local_id].has_default; + let field = FieldId { parent: (*s).into(), local_id, has_default }; (field, parameters.clone()) } TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { let vd = &self.db.union_data(*u).variant_data; let local_id = vd.field(name)?; - let field = FieldId { parent: (*u).into(), local_id }; + let has_default = vd.fields()[local_id].has_default; + let field = FieldId { parent: (*u).into(), local_id, has_default }; (field, parameters.clone()) } _ => return None, diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 940d992001..b254bc8e54 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -872,10 +872,13 @@ impl<'ctx> MirLowerCtx<'ctx> { None => { let local_id = LocalFieldId::from_raw(RawIdx::from(i as u32)); + let has_default = + variant_data.fields()[local_id].has_default; let p = sp.project( ProjectionElem::Field(Either::Left(FieldId { parent: variant_id, local_id, + has_default, })), &mut self.result.projection_store, ); @@ -897,10 +900,12 @@ impl<'ctx> MirLowerCtx<'ctx> { }; let local_id = variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?; + let has_default = variant_data.fields()[local_id].has_default; let place = place.project( PlaceElem::Field(Either::Left(FieldId { parent: union_id.into(), local_id, + has_default, })), &mut self.result.projection_store, ); diff --git a/crates/hir-ty/src/mir/lower/pattern_matching.rs b/crates/hir-ty/src/mir/lower/pattern_matching.rs index 2ffea34c85..43e6eb8898 100644 --- a/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -632,10 +632,12 @@ impl MirLowerCtx<'_> { .map(|x| { let field_id = variant_data.field(&x.name).ok_or(MirLowerError::UnresolvedField)?; + let has_default = variant_data.fields()[field_id].has_default; Ok(( PlaceElem::Field(Either::Left(FieldId { parent: v, local_id: field_id, + has_default, })), x.pat, )) @@ -644,8 +646,12 @@ impl MirLowerCtx<'_> { self.pattern_match_adt(current, current_else, it.into_iter(), cond_place, mode)? } AdtPatternShape::Tuple { args, ellipsis } => { - let fields = variant_data.fields().iter().map(|(x, _)| { - PlaceElem::Field(Either::Left(FieldId { parent: v, local_id: x })) + let fields = variant_data.fields().iter().map(|(x, d)| { + PlaceElem::Field(Either::Left(FieldId { + parent: v, + local_id: x, + has_default: d.has_default, + })) }); self.pattern_match_tuple_like( current, diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs index 96e7130ecf..56b7e6cba0 100644 --- a/crates/hir-ty/src/tests.rs +++ b/crates/hir-ty/src/tests.rs @@ -143,7 +143,7 @@ fn check_impl( let vd = db.variant_data(variant_id); defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| { if fd.has_default { - let field = FieldId { parent: variant_id, local_id }; + let field = FieldId { parent: variant_id, local_id, has_default: true }; Some(DefWithBodyId::FieldId(field)) } else { None @@ -161,7 +161,7 @@ fn check_impl( let vd = db.variant_data(variant_id); defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| { if fd.has_default { - let field = FieldId { parent: variant_id, local_id }; + let field = FieldId { parent: variant_id, local_id, has_default: true }; Some(DefWithBodyId::FieldId(field)) } else { None @@ -433,7 +433,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let vd = db.variant_data(variant_id); defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| { if fd.has_default { - let field = FieldId { parent: variant_id, local_id }; + let field = FieldId { parent: variant_id, local_id, has_default: true }; Some(DefWithBodyId::FieldId(field)) } else { None @@ -451,7 +451,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let vd = db.variant_data(variant_id); defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| { if fd.has_default { - let field = FieldId { parent: variant_id, local_id }; + let field = FieldId { parent: variant_id, local_id, has_default: true }; Some(DefWithBodyId::FieldId(field)) } else { None diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 6f4168ab08..7bd80442f0 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -252,8 +252,8 @@ impl HirDisplay for Struct { f.write_char('(')?; let mut it = variant_data.fields().iter().peekable(); - while let Some((id, _)) = it.next() { - let field = Field { parent: (*self).into(), id }; + while let Some((id, d)) = it.next() { + let field = Field { parent: (*self).into(), id, has_default: d.has_default }; write_visibility(module_id, field.visibility(f.db), f)?; field.ty(f.db).hir_fmt(f)?; if it.peek().is_some() { diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index dd26e894d7..5c12cf21da 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs @@ -237,13 +237,13 @@ impl From for VariantId { impl From for FieldId { fn from(def: Field) -> Self { - FieldId { parent: def.parent.into(), local_id: def.id } + FieldId { parent: def.parent.into(), local_id: def.id, has_default: def.has_default } } } impl From for Field { fn from(def: FieldId) -> Self { - Field { parent: def.parent.into(), id: def.local_id } + Field { parent: def.parent.into(), id: def.local_id, has_default: def.has_default } } } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index a38c0211e8..42e4483789 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -415,24 +415,18 @@ impl ModuleDef { def.diagnostics(db, &mut acc); } - let vd: Option<(VariantDef, Arc)> = match self { - ModuleDef::Adt(Adt::Struct(it)) => { - Some((it.into(), db.struct_data(it.id).variant_data.clone())) - } - ModuleDef::Adt(Adt::Union(it)) => { - Some((it.into(), db.union_data(it.id).variant_data.clone())) - } - ModuleDef::Variant(it) => { - Some((it.into(), db.enum_variant_data(it.id).variant_data.clone())) - } + let fields = match self { + ModuleDef::Adt(Adt::Struct(it)) => Some(it.fields(db)), + ModuleDef::Adt(Adt::Union(it)) => Some(it.fields(db)), + ModuleDef::Variant(it) => Some(it.fields(db)), _ => None, }; - if let Some((parent, vd)) = vd { - for (id, fd) in vd.fields().iter() { - if !fd.has_default { + if let Some(fields) = fields { + for field in fields { + if !field.has_default { continue; } - let def: DefWithBody = DefWithBody::Field(Field { parent, id }); + let def: DefWithBody = field.into(); def.diagnostics(db, &mut acc, style_lints); } } @@ -1258,6 +1252,7 @@ impl From<&Field> for DefWithBodyId { pub struct Field { pub(crate) parent: VariantDef, pub(crate) id: LocalFieldId, + pub(crate) has_default: bool, } #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -1423,7 +1418,7 @@ impl Struct { .variant_data .fields() .iter() - .map(|(id, _)| Field { parent: self.into(), id }) + .map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default }) .collect() } @@ -1485,7 +1480,7 @@ impl Union { .variant_data .fields() .iter() - .map(|(id, _)| Field { parent: self.into(), id }) + .map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default }) .collect() } @@ -1615,7 +1610,7 @@ impl Variant { self.variant_data(db) .fields() .iter() - .map(|(id, _)| Field { parent: self.into(), id }) + .map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default }) .collect() } @@ -5203,10 +5198,13 @@ impl Type { _ => return Vec::new(), }; + let var_data = db.variant_data(variant_id); + let fields = var_data.fields(); db.field_types(variant_id) .iter() .map(|(local_id, ty)| { - let def = Field { parent: variant_id.into(), id: local_id }; + let has_default = fields[local_id].has_default; + let def = Field { parent: variant_id.into(), id: local_id, has_default }; let ty = ty.clone().substitute(Interner, substs); (def, self.derived(ty)) }) diff --git a/crates/hir/src/semantics/child_by_source.rs b/crates/hir/src/semantics/child_by_source.rs index d5dfb98571..ef10a4e148 100644 --- a/crates/hir/src/semantics/child_by_source.rs +++ b/crates/hir/src/semantics/child_by_source.rs @@ -160,7 +160,11 @@ impl ChildBySource for VariantId { let arena_map = arena_map.as_ref(); let parent = *self; for (local_id, source) in arena_map.value.iter() { - let id = FieldId { parent, local_id }; + let has_default = match source { + Either::Left(_) => false, + Either::Right(rec) => rec.expr().is_some(), + }; + let id = FieldId { parent, local_id, has_default }; match source.clone() { Either::Left(source) => res[keys::TUPLE_FIELD].insert(AstPtr::new(&source), id), Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id), diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 7d6f110181..671a4603c2 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -630,8 +630,10 @@ impl SourceAnalyzer { let (adt, subst) = self.infer.as_ref()?.type_of_expr_or_pat(expr_id)?.as_adt()?; let variant = self.infer.as_ref()?.variant_resolution_for_expr_or_pat(expr_id)?; let variant_data = variant.variant_data(db.upcast()); + let fields = variant_data.fields(); let local_id = variant_data.field(&local_name)?; - let field = FieldId { parent: variant, local_id }; + let field = + FieldId { parent: variant, local_id, has_default: fields[local_id].has_default }; let field_ty = db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst); Some(( @@ -652,8 +654,10 @@ impl SourceAnalyzer { let pat_id = self.pat_id(&record_pat.into())?; let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?; let variant_data = variant.variant_data(db.upcast()); + let fields = variant_data.fields(); let local_id = variant_data.field(&field_name)?; - let field = FieldId { parent: variant, local_id }; + let field = + FieldId { parent: variant, local_id, has_default: fields[local_id].has_default }; let (adt, subst) = self.infer.as_ref()?.type_of_pat.get(pat_id)?.as_adt()?; let field_ty = db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst); @@ -1062,11 +1066,17 @@ impl SourceAnalyzer { missing_fields: Vec, ) -> Vec<(Field, Type)> { let field_types = db.field_types(variant); + let var_data = db.variant_data(variant); + let fields = var_data.fields(); missing_fields .into_iter() .map(|local_id| { - let field = FieldId { parent: variant, local_id }; + let field = FieldId { + parent: variant, + local_id, + has_default: fields[local_id].has_default, + }; let ty = field_types[local_id].clone().substitute(Interner, substs); (field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty)) })