Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index bd1e8278d5..54f35cf0a6 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2440,7 +2440,7 @@ impl Impl { #[derive(Clone, PartialEq, Eq, Debug)] pub struct Type { - krate: CrateId, + krate: CrateId, // FIXME this is probably redundant with the TraitEnvironment env: Arc<TraitEnvironment>, ty: Ty, } @@ -2533,12 +2533,9 @@ impl Type { /// Checks that particular type `ty` implements `std::future::Future`. /// This function is used in `.await` syntax completion. pub fn impls_future(&self, db: &dyn HirDatabase) -> bool { - // No special case for the type of async block, since Chalk can figure it out. - - let krate = self.krate; - - let std_future_trait = - db.lang_item(krate, SmolStr::new_inline("future_trait")).and_then(|it| it.as_trait()); + let std_future_trait = db + .lang_item(self.krate, SmolStr::new_inline("future_trait")) + .and_then(|it| it.as_trait()); let std_future_trait = match std_future_trait { Some(it) => it, None => return false, @@ -2546,13 +2543,7 @@ impl Type { let canonical_ty = Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) }; - method_resolution::implements_trait( - &canonical_ty, - db, - self.env.clone(), - krate, - std_future_trait, - ) + method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), std_future_trait) } /// Checks that particular type `ty` implements `std::ops::FnOnce`. @@ -2560,9 +2551,7 @@ impl Type { /// This function can be used to check if a particular type is callable, since FnOnce is a /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce. pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool { - let krate = self.krate; - - let fnonce_trait = match FnTrait::FnOnce.get_id(db, krate) { + let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.krate) { Some(it) => it, None => return false, }; @@ -2573,7 +2562,6 @@ impl Type { &canonical_ty, db, self.env.clone(), - krate, fnonce_trait, ) } @@ -2744,9 +2732,8 @@ impl Type { pub fn autoderef_<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Ty> + 'a { // There should be no inference vars in types passed here let canonical = hir_ty::replace_errors_with_variables(&self.ty); - let environment = self.env.env.clone(); - let ty = InEnvironment { goal: canonical, environment }; - autoderef(db, Some(self.krate), ty).map(|canonical| canonical.value) + let environment = self.env.clone(); + autoderef(db, environment, canonical).map(|canonical| canonical.value) } // This would be nicer if it just returned an iterator, but that runs into @@ -2801,24 +2788,26 @@ impl Type { pub fn iterate_method_candidates<T>( &self, db: &dyn HirDatabase, - krate: Crate, + scope: &SemanticsScope, + // FIXME this can be retrieved from `scope`, except autoimport uses this + // to specify a different set, so the method needs to be split traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, - mut callback: impl FnMut(Type, Function) -> Option<T>, + mut callback: impl FnMut(Function) -> Option<T>, ) -> Option<T> { let _p = profile::span("iterate_method_candidates"); let mut slot = None; self.iterate_method_candidates_dyn( db, - krate, + scope, traits_in_scope, with_local_impls, name, - &mut |ty, assoc_item_id| { + &mut |assoc_item_id| { if let AssocItemId::FunctionId(func) = assoc_item_id { - if let Some(res) = callback(self.derived(ty.clone()), func.into()) { + if let Some(res) = callback(func.into()) { slot = Some(res); return ControlFlow::Break(()); } @@ -2832,50 +2821,55 @@ impl Type { fn iterate_method_candidates_dyn( &self, db: &dyn HirDatabase, - krate: Crate, + scope: &SemanticsScope, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, - callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>, + callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>, ) { // There should be no inference vars in types passed here let canonical = hir_ty::replace_errors_with_variables(&self.ty); - let env = self.env.clone(); - let krate = krate.id; + let krate = match scope.krate() { + Some(k) => k, + None => return, + }; + let environment = scope.resolver().generic_def().map_or_else( + || Arc::new(TraitEnvironment::empty(krate.id)), + |d| db.trait_environment(d), + ); method_resolution::iterate_method_candidates_dyn( &canonical, db, - env, - krate, + environment, traits_in_scope, with_local_impls.and_then(|b| b.id.containing_block()).into(), name, method_resolution::LookupMode::MethodCall, - &mut |ty, id| callback(&ty.value, id), + &mut |_adj, id| callback(id), ); } pub fn iterate_path_candidates<T>( &self, db: &dyn HirDatabase, - krate: Crate, + scope: &SemanticsScope, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, - mut callback: impl FnMut(Type, AssocItem) -> Option<T>, + mut callback: impl FnMut(AssocItem) -> Option<T>, ) -> Option<T> { let _p = profile::span("iterate_path_candidates"); let mut slot = None; self.iterate_path_candidates_dyn( db, - krate, + scope, traits_in_scope, with_local_impls, name, - &mut |ty, assoc_item_id| { - if let Some(res) = callback(self.derived(ty.clone()), assoc_item_id.into()) { + &mut |assoc_item_id| { + if let Some(res) = callback(assoc_item_id.into()) { slot = Some(res); return ControlFlow::Break(()); } @@ -2888,27 +2882,31 @@ impl Type { fn iterate_path_candidates_dyn( &self, db: &dyn HirDatabase, - krate: Crate, + scope: &SemanticsScope, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, - callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>, + callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>, ) { let canonical = hir_ty::replace_errors_with_variables(&self.ty); - let env = self.env.clone(); - let krate = krate.id; + let krate = match scope.krate() { + Some(k) => k, + None => return, + }; + let environment = scope.resolver().generic_def().map_or_else( + || Arc::new(TraitEnvironment::empty(krate.id)), + |d| db.trait_environment(d), + ); - method_resolution::iterate_method_candidates_dyn( + method_resolution::iterate_path_candidates( &canonical, db, - env, - krate, + environment, traits_in_scope, with_local_impls.and_then(|b| b.id.containing_block()).into(), name, - method_resolution::LookupMode::Path, - &mut |ty, id| callback(&ty.value, id), + &mut |id| callback(id), ); } |