Make assoc_resolutions always have a Substitution

This commit is contained in:
Florian Diebold 2022-12-10 17:05:33 +01:00
parent a3ea20a142
commit d3cb032f7e
4 changed files with 16 additions and 26 deletions

View file

@ -356,11 +356,12 @@ pub fn eval_const(
hir_def::AssocItemId::FunctionId(_) => { hir_def::AssocItemId::FunctionId(_) => {
Err(ConstEvalError::NotSupported("assoc function")) Err(ConstEvalError::NotSupported("assoc function"))
} }
// FIXME use actual impl for trait assoc const
hir_def::AssocItemId::ConstId(c) => ctx.db.const_eval(c), hir_def::AssocItemId::ConstId(c) => ctx.db.const_eval(c),
hir_def::AssocItemId::TypeAliasId(_) => { hir_def::AssocItemId::TypeAliasId(_) => {
Err(ConstEvalError::NotSupported("assoc type alias")) Err(ConstEvalError::NotSupported("assoc type alias"))
} }
} };
} }
}; };
match pr { match pr {

View file

@ -349,7 +349,7 @@ pub struct InferenceResult {
/// For each struct literal or pattern, records the variant it resolves to. /// For each struct literal or pattern, records the variant it resolves to.
variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
/// For each associated item record what it resolves to /// For each associated item record what it resolves to
assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Option<Substitution>)>, assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Substitution)>,
pub diagnostics: Vec<InferenceDiagnostic>, pub diagnostics: Vec<InferenceDiagnostic>,
pub type_of_expr: ArenaMap<ExprId, Ty>, pub type_of_expr: ArenaMap<ExprId, Ty>,
/// For each pattern record the type it resolves to. /// For each pattern record the type it resolves to.
@ -379,16 +379,10 @@ impl InferenceResult {
pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> { pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
self.variant_resolutions.get(&id.into()).copied() self.variant_resolutions.get(&id.into()).copied()
} }
pub fn assoc_resolutions_for_expr( pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)> {
&self,
id: ExprId,
) -> Option<(AssocItemId, Option<Substitution>)> {
self.assoc_resolutions.get(&id.into()).cloned() self.assoc_resolutions.get(&id.into()).cloned()
} }
pub fn assoc_resolutions_for_pat( pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)> {
&self,
id: PatId,
) -> Option<(AssocItemId, Option<Substitution>)> {
self.assoc_resolutions.get(&id.into()).cloned() self.assoc_resolutions.get(&id.into()).cloned()
} }
pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
@ -653,12 +647,7 @@ impl<'a> InferenceContext<'a> {
self.result.variant_resolutions.insert(id, variant); self.result.variant_resolutions.insert(id, variant);
} }
fn write_assoc_resolution( fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution) {
&mut self,
id: ExprOrPatId,
item: AssocItemId,
subs: Option<Substitution>,
) {
self.result.assoc_resolutions.insert(id, (item, subs)); self.result.assoc_resolutions.insert(id, (item, subs));
} }

View file

@ -7,6 +7,7 @@ use hir_def::{
AdtId, AssocItemId, EnumVariantId, ItemContainerId, Lookup, AdtId, AssocItemId, EnumVariantId, ItemContainerId, Lookup,
}; };
use hir_expand::name::Name; use hir_expand::name::Name;
use stdx::never;
use crate::{ use crate::{
builder::ParamKind, builder::ParamKind,
@ -212,7 +213,7 @@ impl<'a> InferenceContext<'a> {
AssocItemId::TypeAliasId(_) => unreachable!(), AssocItemId::TypeAliasId(_) => unreachable!(),
}; };
self.write_assoc_resolution(id, item, Some(trait_ref.substitution.clone())); self.write_assoc_resolution(id, item, trait_ref.substitution.clone());
Some((def, Some(trait_ref.substitution))) Some((def, Some(trait_ref.substitution)))
} }
@ -259,7 +260,7 @@ impl<'a> InferenceContext<'a> {
let impl_self_ty = let impl_self_ty =
self.db.impl_self_ty(impl_id).substitute(Interner, &impl_substs); self.db.impl_self_ty(impl_id).substitute(Interner, &impl_substs);
self.unify(&impl_self_ty, &ty); self.unify(&impl_self_ty, &ty);
Some(impl_substs) impl_substs
} }
ItemContainerId::TraitId(trait_) => { ItemContainerId::TraitId(trait_) => {
// we're picking this method // we're picking this method
@ -268,13 +269,16 @@ impl<'a> InferenceContext<'a> {
.fill_with_inference_vars(&mut self.table) .fill_with_inference_vars(&mut self.table)
.build(); .build();
self.push_obligation(trait_ref.clone().cast(Interner)); self.push_obligation(trait_ref.clone().cast(Interner));
Some(trait_ref.substitution) trait_ref.substitution
}
ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
never!("assoc item contained in module/extern block");
return None;
} }
ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
}; };
self.write_assoc_resolution(id, item, substs.clone()); self.write_assoc_resolution(id, item, substs.clone());
Some((def, substs)) Some((def, Some(substs)))
}, },
) )
} }

View file

@ -502,11 +502,7 @@ impl SourceAnalyzer {
} }
} }
AssocItemId::ConstId(const_id) => { AssocItemId::ConstId(const_id) => {
if let Some(subs) = subs { self.resolve_impl_const_or_trait_def(db, const_id, subs).into()
self.resolve_impl_const_or_trait_def(db, const_id, subs).into()
} else {
assoc
}
} }
_ => assoc, _ => assoc,
}; };