Skip to content

Commit

Permalink
Merge #4484
Browse files Browse the repository at this point in the history
4484: Allow calling dyn trait super trait methods without the super trait in scope r=flodiebold a=flodiebold

This also removes some vestiges of the old impl trait support which I think aren't currently in use.

Co-authored-by: Florian Diebold <flodiebold@gmail.com>
  • Loading branch information
bors[bot] and flodiebold authored May 16, 2020
2 parents ebaa05a + 811d25b commit 8944a9b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 15 deletions.
14 changes: 6 additions & 8 deletions crates/ra_hir_ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,15 +808,13 @@ impl Ty {
}
}

/// If this is an `impl Trait` or `dyn Trait`, returns that trait.
pub fn inherent_trait(&self) -> Option<TraitId> {
/// If this is a `dyn Trait`, returns that trait.
pub fn dyn_trait(&self) -> Option<TraitId> {
match self {
Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
predicates.iter().find_map(|pred| match pred {
GenericPredicate::Implemented(tr) => Some(tr.trait_),
_ => None,
})
}
Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred {
GenericPredicate::Implemented(tr) => Some(tr.trait_),
_ => None,
}),
_ => None,
}
}
Expand Down
10 changes: 3 additions & 7 deletions crates/ra_hir_ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,9 @@ fn iterate_trait_method_candidates<T>(
receiver_ty: Option<&Canonical<Ty>>,
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<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 ty is `dyn Trait`, the trait doesn't need to be in scope
let inherent_trait =
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
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)
Expand Down Expand Up @@ -601,11 +602,6 @@ pub fn implements_trait(
krate: CrateId,
trait_: TraitId,
) -> bool {
if ty.value.inherent_trait() == Some(trait_) {
// FIXME this is a bit of a hack, since Chalk should say the same thing
// anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
return true;
}
let goal = generic_implements_goal(db, env, trait_, ty.clone());
let solution = db.trait_solve(krate, goal);

Expand Down
31 changes: 31 additions & 0 deletions crates/ra_hir_ty/src/tests/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,3 +1096,34 @@ fn test() { (S {}).method()<|>; }
);
assert_eq!(t, "()");
}

#[test]
fn dyn_trait_super_trait_not_in_scope() {
assert_snapshot!(
infer(r#"
mod m {
pub trait SuperTrait {
fn foo(&self) -> u32 { 0 }
}
}
trait Trait: m::SuperTrait {}
struct S;
impl m::SuperTrait for S {}
impl Trait for S {}
fn test(d: &dyn Trait) {
d.foo();
}
"#),
@r###"
52..56 'self': &Self
65..70 '{ 0 }': u32
67..68 '0': u32
177..178 'd': &dyn Trait
192..208 '{ ...o(); }': ()
198..199 'd': &dyn Trait
198..205 'd.foo()': u32
"###
);
}

0 comments on commit 8944a9b

Please sign in to comment.