Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/path.rs')
-rw-r--r--crates/hir-ty/src/infer/path.rs40
1 files changed, 30 insertions, 10 deletions
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index ebe9d6fb5e..8bd17c0f39 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -7,13 +7,15 @@ use hir_def::{
AdtId, AssocItemId, EnumVariantId, ItemContainerId, Lookup,
};
use hir_expand::name::Name;
+use stdx::never;
use crate::{
builder::ParamKind,
consteval,
method_resolution::{self, VisibleFromModule},
utils::generics,
- Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, ValueTyDefId,
+ InferenceDiagnostic, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
+ ValueTyDefId,
};
use super::{ExprOrPatId, InferenceContext, TraitRef};
@@ -212,7 +214,7 @@ impl<'a> InferenceContext<'a> {
AssocItemId::TypeAliasId(_) => unreachable!(),
};
- self.write_assoc_resolution(id, item);
+ self.write_assoc_resolution(id, item, trait_ref.substitution.clone());
Some((def, Some(trait_ref.substitution)))
}
@@ -233,7 +235,8 @@ impl<'a> InferenceContext<'a> {
let canonical_ty = self.canonicalize(ty.clone());
let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast());
- method_resolution::iterate_method_candidates(
+ let mut not_visible = None;
+ let res = method_resolution::iterate_method_candidates(
&canonical_ty.value,
self.db,
self.table.trait_env.clone(),
@@ -241,7 +244,7 @@ impl<'a> InferenceContext<'a> {
VisibleFromModule::Filter(self.resolver.module()),
Some(name),
method_resolution::LookupMode::Path,
- move |_ty, item| {
+ |_ty, item, visible| {
let (def, container) = match item {
AssocItemId::FunctionId(f) => {
(ValueNs::FunctionId(f), f.lookup(self.db.upcast()).container)
@@ -259,7 +262,7 @@ impl<'a> InferenceContext<'a> {
let impl_self_ty =
self.db.impl_self_ty(impl_id).substitute(Interner, &impl_substs);
self.unify(&impl_self_ty, &ty);
- Some(impl_substs)
+ impl_substs
}
ItemContainerId::TraitId(trait_) => {
// we're picking this method
@@ -268,15 +271,32 @@ impl<'a> InferenceContext<'a> {
.fill_with_inference_vars(&mut self.table)
.build();
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);
- Some((def, substs))
+ if visible {
+ Some((def, item, Some(substs), true))
+ } else {
+ if not_visible.is_none() {
+ not_visible = Some((def, item, Some(substs), false));
+ }
+ None
+ }
},
- )
+ );
+ let res = res.or(not_visible);
+ if let Some((_, item, Some(ref substs), visible)) = res {
+ self.write_assoc_resolution(id, item, substs.clone());
+ if !visible {
+ self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem { id, item })
+ }
+ }
+ res.map(|(def, _, substs, _)| (def, substs))
}
fn resolve_enum_variant_on_ty(