3215: Exclude methods from non-parameter types introduced by generic constraints r=flodiebold a=lnicola

Fixes #3184.

r? @flodiebold

Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
This commit is contained in:
bors[bot] 2020-02-19 19:46:37 +00:00 committed by GitHub
commit e00b9ca3c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 6 deletions

View file

@ -377,12 +377,17 @@ fn iterate_trait_method_candidates<T>(
) -> Option<T> {
// 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);

View file

@ -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>(T);
fn foo<T>(t: Wrapper<T>)
where
Wrapper<T>: 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