infer: remove record_field_resolutions field

It stores no useful data, since we can derive all fields from
`variant_resolutions`
This commit is contained in:
Jonas Schievink 2021-04-06 17:59:18 +02:00
parent 74711deb72
commit e9752308bb
8 changed files with 35 additions and 40 deletions

View file

@ -161,14 +161,15 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
field: &ast::RecordExprField,
) -> Option<(Field, Option<Local>)> {
let expr_id =
self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?;
let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
let expr = ast::Expr::from(record_expr);
let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?;
let local_name = field.field_name()?.as_name();
let local = if field.name_ref().is_some() {
None
} else {
let local_name = field.field_name()?.as_name();
let path = ModPath::from_segments(PathKind::Plain, once(local_name));
let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone()));
match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
Some(ValueNs::LocalBinding(pat_id)) => {
Some(Local { pat_id, parent: self.resolver.body_owner()? })
@ -176,8 +177,10 @@ impl SourceAnalyzer {
_ => None,
}
};
let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?;
Some((struct_field.into(), local))
let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?;
let variant_data = variant.variant_data(db.upcast());
let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
Some((field.into(), local))
}
pub(crate) fn resolve_record_pat_field(

View file

@ -56,6 +56,7 @@ use std::{
sync::Arc,
};
use adt::VariantData;
use base_db::{impl_intern_key, salsa, CrateId};
use hir_expand::{
ast_id_map::FileAstId,
@ -442,6 +443,18 @@ pub enum VariantId {
}
impl_from!(EnumVariantId, StructId, UnionId for VariantId);
impl VariantId {
pub fn variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData> {
match self {
VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
VariantId::EnumVariantId(it) => {
db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
}
}
}
}
trait Intern {
type ID;
fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;

View file

@ -14,7 +14,6 @@ use crate::{
MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
MissingPatFields, RemoveThisSemicolon,
},
utils::variant_data,
AdtId, InferenceResult, Interner, TyExt, TyKind,
};
@ -104,7 +103,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
let root = source_ptr.file_syntax(db.upcast());
if let ast::Expr::RecordExpr(record_expr) = &source_ptr.value.to_node(&root) {
if let Some(_) = record_expr.record_expr_field_list() {
let variant_data = variant_data(db.upcast(), variant_def);
let variant_data = variant_def.variant_data(db.upcast());
let missed_fields = missed_fields
.into_iter()
.map(|idx| variant_data.fields()[idx].name.clone())
@ -135,7 +134,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
let root = source_ptr.file_syntax(db.upcast());
if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
if let Some(_) = record_pat.record_pat_field_list() {
let variant_data = variant_data(db.upcast(), variant_def);
let variant_data = variant_def.variant_data(db.upcast());
let missed_fields = missed_fields
.into_iter()
.map(|idx| variant_data.fields()[idx].name.clone())
@ -453,7 +452,7 @@ pub fn record_literal_missing_fields(
return None;
}
let variant_data = variant_data(db.upcast(), variant_def);
let variant_data = variant_def.variant_data(db.upcast());
let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
let missed_fields: Vec<LocalFieldId> = variant_data
@ -483,7 +482,7 @@ pub fn record_pattern_missing_fields(
return None;
}
let variant_data = variant_data(db.upcast(), variant_def);
let variant_data = variant_def.variant_data(db.upcast());
let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
let missed_fields: Vec<LocalFieldId> = variant_data

View file

@ -131,8 +131,6 @@ pub struct InferenceResult {
method_resolutions: FxHashMap<ExprId, FunctionId>,
/// For each field access expr, records the field it resolves to.
field_resolutions: FxHashMap<ExprId, FieldId>,
/// For each field in record literal, records the field it resolves to.
record_field_resolutions: FxHashMap<ExprId, FieldId>,
record_pat_field_resolutions: FxHashMap<PatId, FieldId>,
/// For each struct literal, records the variant it resolves to.
variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
@ -153,9 +151,6 @@ impl InferenceResult {
pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
self.field_resolutions.get(&expr).copied()
}
pub fn record_field_resolution(&self, expr: ExprId) -> Option<FieldId> {
self.record_field_resolutions.get(&expr).copied()
}
pub fn record_pat_field_resolution(&self, pat: PatId) -> Option<FieldId> {
self.record_pat_field_resolutions.get(&pat).copied()
}

View file

@ -21,7 +21,7 @@ use crate::{
primitive::{self, UintTy},
static_lifetime, to_chalk_trait_id,
traits::{chalk::from_chalk, FnTrait},
utils::{generics, variant_data, Generics},
utils::{generics, Generics},
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
TypeWalk,
@ -414,7 +414,7 @@ impl<'a> InferenceContext<'a> {
let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
for field in fields.iter() {
let field_def =
variant_data.as_ref().and_then(|it| match it.field(&field.name) {
@ -426,9 +426,6 @@ impl<'a> InferenceContext<'a> {
None
}
});
if let Some(field_def) = field_def {
self.result.record_field_resolutions.insert(field.expr, field_def);
}
let field_ty = field_def.map_or(self.err_ty(), |it| {
field_types[it.local_id].clone().substitute(&Interner, &substs)
});

View file

@ -13,8 +13,8 @@ use hir_expand::name::Name;
use super::{BindingMode, Expectation, InferenceContext};
use crate::{
lower::lower_to_chalk_mutability, static_lifetime, utils::variant_data, Interner, Substitution,
Ty, TyBuilder, TyExt, TyKind,
lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
TyExt, TyKind,
};
impl<'a> InferenceContext<'a> {
@ -28,7 +28,7 @@ impl<'a> InferenceContext<'a> {
ellipsis: Option<usize>,
) -> Ty {
let (ty, def) = self.resolve_variant(path);
let var_data = def.map(|it| variant_data(self.db.upcast(), it));
let var_data = def.map(|it| it.variant_data(self.db.upcast()));
if let Some(variant) = def {
self.write_variant_resolution(id.into(), variant);
}
@ -68,7 +68,7 @@ impl<'a> InferenceContext<'a> {
id: PatId,
) -> Ty {
let (ty, def) = self.resolve_variant(path);
let var_data = def.map(|it| variant_data(self.db.upcast(), it));
let var_data = def.map(|it| it.variant_data(self.db.upcast()));
if let Some(variant) = def {
self.write_variant_resolution(id.into(), variant);
}

View file

@ -30,8 +30,7 @@ use crate::{
dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
traits::chalk::{Interner, ToChalk},
utils::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
variant_data, Generics,
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
},
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
@ -879,7 +878,7 @@ pub(crate) fn field_types_query(
db: &dyn HirDatabase,
variant_id: VariantId,
) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
let var_data = variant_data(db.upcast(), variant_id);
let var_data = variant_id.variant_data(db.upcast());
let (resolver, def): (_, GenericDefId) = match variant_id {
VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),

View file

@ -4,7 +4,6 @@ use std::sync::Arc;
use chalk_ir::{BoundVar, DebruijnIndex};
use hir_def::{
adt::VariantData,
db::DefDatabase,
generics::{
GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
@ -13,7 +12,7 @@ use hir_def::{
path::Path,
resolver::{HasResolver, TypeNs},
type_ref::TypeRef,
AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId,
AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId,
};
use hir_expand::name::{name, Name};
@ -136,16 +135,6 @@ pub(super) fn associated_type_by_name_including_super_traits(
})
}
pub(super) fn variant_data(db: &dyn DefDatabase, var: VariantId) -> Arc<VariantData> {
match var {
VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
VariantId::EnumVariantId(it) => {
db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
}
}
}
/// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices).
/// The underlying values are cloned if there are other strong references.
pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] {