Salsa idiomize VariantFields query

This commit is contained in:
Lukas Wirth 2025-06-26 12:55:55 +02:00
parent 332434aecd
commit 889d84a1be
33 changed files with 201 additions and 131 deletions

View file

@ -801,7 +801,7 @@ pub(crate) fn adt_datum_query(
// this slows down rust-analyzer by quite a bit unfortunately, so enabling this is currently not worth it
let _variant_id_to_fields = |id: VariantId| {
let variant_data = &id.variant_data(db);
let variant_data = &id.fields(db);
let fields = if variant_data.fields().is_empty() {
vec![]
} else {

View file

@ -307,7 +307,7 @@ impl<'a> DeclValidator<'a> {
/// Check incorrect names for struct fields.
fn validate_struct_fields(&mut self, struct_id: StructId) {
let data = self.db.variant_fields(struct_id.into());
let data = struct_id.fields(self.db);
if data.shape != FieldsShape::Record {
return;
};
@ -468,7 +468,7 @@ impl<'a> DeclValidator<'a> {
/// Check incorrect names for fields of enum variant.
fn validate_enum_variant_fields(&mut self, variant_id: EnumVariantId) {
let variant_data = self.db.variant_fields(variant_id.into());
let variant_data = variant_id.fields(self.db);
if variant_data.shape != FieldsShape::Record {
return;
};

View file

@ -558,7 +558,7 @@ pub fn record_literal_missing_fields(
return None;
}
let variant_data = variant_def.variant_data(db);
let variant_data = variant_def.fields(db);
let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
let missed_fields: Vec<LocalFieldId> = variant_data
@ -588,7 +588,7 @@ pub fn record_pattern_missing_fields(
return None;
}
let variant_data = variant_def.variant_data(db);
let variant_data = variant_def.fields(db);
let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
let missed_fields: Vec<LocalFieldId> = variant_data

View file

@ -169,13 +169,13 @@ impl<'a> PatCtxt<'a> {
}
hir_def::hir::Pat::TupleStruct { ref args, ellipsis, .. } if variant.is_some() => {
let expected_len = variant.unwrap().variant_data(self.db).fields().len();
let expected_len = variant.unwrap().fields(self.db).fields().len();
let subpatterns = self.lower_tuple_subpats(args, expected_len, ellipsis);
self.lower_variant_or_leaf(pat, ty, subpatterns)
}
hir_def::hir::Pat::Record { ref args, .. } if variant.is_some() => {
let variant_data = variant.unwrap().variant_data(self.db);
let variant_data = variant.unwrap().fields(self.db);
let subpatterns = args
.iter()
.map(|field| {
@ -345,7 +345,7 @@ impl HirDisplay for Pat {
)?,
};
let variant_data = variant.variant_data(f.db);
let variant_data = variant.fields(f.db);
if variant_data.shape == FieldsShape::Record {
write!(f, " {{ ")?;
@ -377,7 +377,7 @@ impl HirDisplay for Pat {
}
let num_fields =
variant.map_or(subpatterns.len(), |v| v.variant_data(f.db).fields().len());
variant.map_or(subpatterns.len(), |v| v.fields(f.db).fields().len());
if num_fields != 0 || variant.is_none() {
write!(f, "(")?;
let subpats = (0..num_fields).map(|i| {

View file

@ -146,7 +146,7 @@ impl<'db> MatchCheckCtx<'db> {
let (_, substs) = ty.as_adt().unwrap();
let field_tys = self.db.field_types(variant);
let fields_len = variant.variant_data(self.db).fields().len() as u32;
let fields_len = variant.fields(self.db).fields().len() as u32;
(0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).map(move |fid| {
let ty = field_tys[fid].clone().substitute(Interner, substs);
@ -229,7 +229,7 @@ impl<'db> MatchCheckCtx<'db> {
}
};
let variant = Self::variant_id_for_adt(self.db, &ctor, adt).unwrap();
arity = variant.variant_data(self.db).fields().len();
arity = variant.fields(self.db).fields().len();
}
_ => {
never!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, &pat.ty);
@ -349,7 +349,7 @@ impl PatCx for MatchCheckCtx<'_> {
1
} else {
let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap();
variant.variant_data(self.db).fields().len()
variant.fields(self.db).fields().len()
}
}
_ => {

View file

@ -888,7 +888,7 @@ fn render_const_scalar(
write!(f, "{}", data.name.display(f.db, f.edition()))?;
let field_types = f.db.field_types(s.into());
render_variant_after_name(
&f.db.variant_fields(s.into()),
s.fields(f.db),
f,
&field_types,
f.db.trait_environment(adt.0.into()),
@ -920,7 +920,7 @@ fn render_const_scalar(
)?;
let field_types = f.db.field_types(var_id.into());
render_variant_after_name(
&f.db.variant_fields(var_id.into()),
var_id.fields(f.db),
f,
&field_types,
f.db.trait_environment(adt.0.into()),

View file

@ -382,7 +382,7 @@ fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result<Option<Pointe
return Err(());
};
let struct_data = table.db.variant_fields(id.into());
let struct_data = id.fields(table.db);
if let Some((last_field, _)) = struct_data.fields().iter().last() {
let last_field_ty =
table.db.field_types(id.into())[last_field].clone().substitute(Interner, subst);

View file

@ -677,7 +677,7 @@ impl CapturedItem {
match proj {
ProjectionElem::Deref => {}
ProjectionElem::Field(Either::Left(f)) => {
let variant_data = f.parent.variant_data(db);
let variant_data = f.parent.fields(db);
match variant_data.shape {
FieldsShape::Record => {
result.push('_');
@ -720,7 +720,7 @@ impl CapturedItem {
// In source code autoderef kicks in.
ProjectionElem::Deref => {}
ProjectionElem::Field(Either::Left(f)) => {
let variant_data = f.parent.variant_data(db);
let variant_data = f.parent.fields(db);
match variant_data.shape {
FieldsShape::Record => format_to!(
result,
@ -782,7 +782,7 @@ impl CapturedItem {
if field_need_paren {
result = format!("({result})");
}
let variant_data = f.parent.variant_data(db);
let variant_data = f.parent.fields(db);
let field = match variant_data.shape {
FieldsShape::Record => {
variant_data.fields()[f.local_id].name.as_str().to_owned()
@ -1559,7 +1559,7 @@ impl InferenceContext<'_> {
self.consume_place(place)
}
VariantId::StructId(s) => {
let vd = &*self.db.variant_fields(s.into());
let vd = s.fields(self.db);
for field_pat in args.iter() {
let arg = field_pat.pat;
let Some(local_id) = vd.field(&field_pat.name) else {
@ -1611,7 +1611,7 @@ impl InferenceContext<'_> {
self.consume_place(place)
}
VariantId::StructId(s) => {
let vd = &*self.db.variant_fields(s.into());
let vd = s.fields(self.db);
let (al, ar) =
args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
let fields = vd.fields().iter();

View file

@ -542,7 +542,7 @@ impl InferenceContext<'_> {
_ if fields.is_empty() => {}
Some(def) => {
let field_types = self.db.field_types(def);
let variant_data = def.variant_data(self.db);
let variant_data = def.fields(self.db);
let visibilities = self.db.field_visibilities(def);
for field in fields.iter() {
let field_def = {
@ -1566,12 +1566,12 @@ impl InferenceContext<'_> {
});
}
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref parameters) => {
let local_id = self.db.variant_fields(s.into()).field(name)?;
let local_id = s.fields(self.db).field(name)?;
let field = FieldId { parent: s.into(), local_id };
(field, parameters.clone())
}
&TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), ref parameters) => {
let local_id = self.db.variant_fields(u.into()).field(name)?;
let local_id = u.fields(self.db).field(name)?;
let field = FieldId { parent: u.into(), local_id };
(field, parameters.clone())
}

View file

@ -38,7 +38,7 @@ impl InferenceContext<'_> {
decl: Option<DeclContext>,
) -> Ty {
let (ty, def) = self.resolve_variant(id.into(), path, true);
let var_data = def.map(|it| it.variant_data(self.db));
let var_data = def.map(|it| it.fields(self.db));
if let Some(variant) = def {
self.write_variant_resolution(id.into(), variant);
}
@ -60,7 +60,7 @@ impl InferenceContext<'_> {
_ if subs.is_empty() => {}
Some(def) => {
let field_types = self.db.field_types(def);
let variant_data = def.variant_data(self.db);
let variant_data = def.fields(self.db);
let visibilities = self.db.field_visibilities(def);
let (pre, post) = match ellipsis {
@ -129,7 +129,7 @@ impl InferenceContext<'_> {
_ if subs.len() == 0 => {}
Some(def) => {
let field_types = self.db.field_types(def);
let variant_data = def.variant_data(self.db);
let variant_data = def.fields(self.db);
let visibilities = self.db.field_visibilities(def);
let substs = ty.as_adt().map(TupleExt::tail);

View file

@ -1001,7 +1001,7 @@ impl<'a> InferenceTable<'a> {
// Must use a loop here and not recursion because otherwise users will conduct completely
// artificial examples of structs that have themselves as the tail field and complain r-a crashes.
while let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
let struct_data = self.db.variant_fields(id.into());
let struct_data = id.fields(self.db);
if let Some((last_field, _)) = struct_data.fields().iter().next_back() {
let last_field_ty = self.db.field_types(id.into())[last_field]
.clone()

View file

@ -132,7 +132,7 @@ impl UninhabitedFrom<'_> {
variant: VariantId,
subst: &Substitution,
) -> ControlFlow<VisiblyUninhabited> {
let variant_data = self.db.variant_fields(variant);
let variant_data = variant.fields(self.db);
let fields = variant_data.fields();
if fields.is_empty() {
return CONTINUE_OPAQUELY_INHABITED;

View file

@ -375,7 +375,7 @@ pub(crate) fn layout_of_ty_cycle_result(
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
match pointee.kind(Interner) {
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), ref subst) => {
let data = db.variant_fields(i.into());
let data = i.fields(db);
let mut it = data.fields().iter().rev();
match it.next() {
Some((f, _)) => {

View file

@ -42,7 +42,7 @@ pub fn layout_of_adt_query(
AdtId::StructId(s) => {
let sig = db.struct_signature(s);
let mut r = SmallVec::<[_; 1]>::new();
r.push(handle_variant(s.into(), &db.variant_fields(s.into()))?);
r.push(handle_variant(s.into(), s.fields(db))?);
(
r,
sig.repr.unwrap_or_default(),
@ -52,7 +52,7 @@ pub fn layout_of_adt_query(
AdtId::UnionId(id) => {
let data = db.union_signature(id);
let mut r = SmallVec::new();
r.push(handle_variant(id.into(), &db.variant_fields(id.into()))?);
r.push(handle_variant(id.into(), id.fields(db))?);
(r, data.repr.unwrap_or_default(), false)
}
AdtId::EnumId(e) => {
@ -60,7 +60,7 @@ pub fn layout_of_adt_query(
let r = variants
.variants
.iter()
.map(|&(v, _, _)| handle_variant(v.into(), &db.variant_fields(v.into())))
.map(|&(v, _, _)| handle_variant(v.into(), v.fields(db)))
.collect::<Result<SmallVec<_>, _>>()?;
(r, db.enum_signature(e).repr.unwrap_or_default(), false)
}

View file

@ -883,7 +883,7 @@ pub(crate) fn field_types_with_diagnostics_query(
db: &dyn HirDatabase,
variant_id: VariantId,
) -> (Arc<ArenaMap<LocalFieldId, Binders<Ty>>>, Diagnostics) {
let var_data = db.variant_fields(variant_id);
let var_data = variant_id.fields(db);
let fields = var_data.fields();
if fields.is_empty() {
return (Arc::new(ArenaMap::default()), None);
@ -1435,7 +1435,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
/// Build the type of a tuple struct constructor.
fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> {
let struct_data = db.variant_fields(def.into());
let struct_data = def.fields(db);
match struct_data.shape {
FieldsShape::Record => None,
FieldsShape::Unit => Some(type_for_adt(db, def.into())),
@ -1468,7 +1468,7 @@ fn type_for_enum_variant_constructor(
def: EnumVariantId,
) -> Option<Binders<Ty>> {
let e = def.lookup(db).parent;
match db.variant_fields(def.into()).shape {
match def.fields(db).shape {
FieldsShape::Record => None,
FieldsShape::Unit => Some(type_for_adt(db, e.into())),
FieldsShape::Tuple => {

View file

@ -1749,8 +1749,7 @@ impl Evaluator<'_> {
AdtId::UnionId(_) => not_supported!("unsizing unions"),
AdtId::EnumId(_) => not_supported!("unsizing enums"),
};
let Some((last_field, _)) =
self.db.variant_fields(id.into()).fields().iter().next_back()
let Some((last_field, _)) = id.fields(self.db).fields().iter().next_back()
else {
not_supported!("unsizing struct without field");
};
@ -2232,7 +2231,7 @@ impl Evaluator<'_> {
}
chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
AdtId::StructId(s) => {
let data = this.db.variant_fields(s.into());
let data = s.fields(this.db);
let layout = this.layout(ty)?;
let field_types = this.db.field_types(s.into());
for (f, _) in data.fields().iter() {
@ -2261,7 +2260,7 @@ impl Evaluator<'_> {
bytes,
e,
) {
let data = &this.db.variant_fields(v.into());
let data = v.fields(this.db);
let field_types = this.db.field_types(v.into());
for (f, _) in data.fields().iter() {
let offset =
@ -2838,7 +2837,7 @@ impl Evaluator<'_> {
return Ok(());
}
let layout = self.layout_adt(id.0, subst.clone())?;
let variant_fields = self.db.variant_fields(s.into());
let variant_fields = s.fields(self.db);
match variant_fields.shape {
FieldsShape::Record | FieldsShape::Tuple => {
let field_types = self.db.field_types(s.into());

View file

@ -31,7 +31,7 @@ impl Evaluator<'_> {
Some(len) => len,
_ => {
if let AdtId::StructId(id) = id.0 {
let struct_data = self.db.variant_fields(id.into());
let struct_data = id.fields(self.db);
let fields = struct_data.fields();
let Some((first_field, _)) = fields.iter().next() else {
not_supported!("simd type with no field");

View file

@ -503,7 +503,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
Ok(Some(current))
}
ValueNs::EnumVariantId(variant_id) => {
let variant_fields = &self.db.variant_fields(variant_id.into());
let variant_fields = variant_id.fields(self.db);
if variant_fields.shape == FieldsShape::Unit {
let ty = self.infer.type_of_expr[expr_id].clone();
current = self.lower_enum_variant(
@ -856,7 +856,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
TyKind::Adt(_, s) => s.clone(),
_ => not_supported!("Non ADT record literal"),
};
let variant_fields = self.db.variant_fields(variant_id);
let variant_fields = variant_id.fields(self.db);
match variant_id {
VariantId::EnumVariantId(_) | VariantId::StructId(_) => {
let mut operands = vec![None; variant_fields.fields().len()];
@ -1176,8 +1176,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
place,
Rvalue::Aggregate(
AggregateKind::Adt(st.into(), subst.clone()),
self.db
.variant_fields(st.into())
st.fields(self.db)
.fields()
.iter()
.map(|it| {

View file

@ -609,7 +609,7 @@ impl MirLowerCtx<'_> {
}
self.pattern_matching_variant_fields(
shape,
&self.db.variant_fields(v.into()),
v.fields(self.db),
variant,
current,
current_else,
@ -619,7 +619,7 @@ impl MirLowerCtx<'_> {
}
VariantId::StructId(s) => self.pattern_matching_variant_fields(
shape,
&self.db.variant_fields(s.into()),
s.fields(self.db),
variant,
current,
current_else,

View file

@ -326,7 +326,7 @@ impl<'a> MirPrettyCtx<'a> {
w!(this, ")");
}
ProjectionElem::Field(Either::Left(field)) => {
let variant_fields = this.db.variant_fields(field.parent);
let variant_fields = field.parent.fields(this.db);
let name = &variant_fields.fields()[field.local_id].name;
match field.parent {
hir_def::VariantId::EnumVariantId(e) => {

View file

@ -596,8 +596,7 @@ fn main() {
"struct_signature_with_source_map_shim",
"generic_predicates_shim",
"value_ty_shim",
"variant_fields_shim",
"variant_fields_with_source_map_shim",
"query_",
"lang_item",
"inherent_impls_in_crate_shim",
"impl_signature_shim",
@ -697,7 +696,7 @@ fn main() {
"function_signature_with_source_map_shim",
"expr_scopes_shim",
"struct_signature_with_source_map_shim",
"variant_fields_with_source_map_shim",
"query_",
"inherent_impls_in_crate_shim",
"impl_signature_with_source_map_shim",
"impl_signature_shim",