From 5b05209744ce7dcd15f814482babbfd163553b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Tue, 18 Feb 2020 13:26:00 +0200 Subject: Exclude methods from non-parameter types introduced by generic constraints --- crates/ra_hir_ty/src/method_resolution.rs | 17 +++++++++++------ crates/ra_hir_ty/src/tests/method_resolution.rs | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 964acdb09..988d83af5 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -377,12 +377,17 @@ fn iterate_trait_method_candidates( ) -> Option { // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope let inherent_trait = self_ty.value.inherent_trait().into_iter(); - // if we have `T: Trait` in the param env, the trait doesn't need to be in scope - let traits_from_env = env - .trait_predicates_for_self_ty(&self_ty.value) - .map(|tr| tr.trait_) - .flat_map(|t| all_super_traits(db, t)); - let traits = inherent_trait.chain(traits_from_env).chain(traits_in_scope.iter().copied()); + let env_traits = if let Ty::Placeholder(_) = self_ty.value { + // if we have `T: Trait` in the param env, the trait doesn't need to be in scope + env.trait_predicates_for_self_ty(&self_ty.value) + .map(|tr| tr.trait_) + .flat_map(|t| all_super_traits(db, t)) + .collect() + } else { + Vec::new() + }; + let traits = + inherent_trait.chain(env_traits.into_iter()).chain(traits_in_scope.iter().copied()); 'traits: for t in traits { let data = db.trait_data(t); diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 1f767d324..644d59e17 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -1007,6 +1007,29 @@ fn test() { foo.call()<|>; } ); } +#[test] +fn method_resolution_non_parameter_type() { + let t = type_at( + r#" +//- /main.rs +mod a { + pub trait Foo { + fn foo(&self); + } +} + +struct Wrapper(T); +fn foo(t: Wrapper) +where + Wrapper: a::Foo, +{ + t.foo()<|>; +} +"#, + ); + assert_eq!(t, "{unknown}"); +} + #[test] fn method_resolution_slow() { // this can get quite slow if we set the solver size limit too high -- cgit v1.2.3