Skip to content

Commit 811d25b

Browse files
committed
Allow calling dyn trait super trait methods without the super trait in scope
This also removes some vestiges of the old impl trait support which I think aren't currently in use.
1 parent 9322790 commit 811d25b

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

crates/ra_hir_ty/src/lib.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -808,15 +808,13 @@ impl Ty {
808808
}
809809
}
810810

811-
/// If this is an `impl Trait` or `dyn Trait`, returns that trait.
812-
pub fn inherent_trait(&self) -> Option<TraitId> {
811+
/// If this is a `dyn Trait`, returns that trait.
812+
pub fn dyn_trait(&self) -> Option<TraitId> {
813813
match self {
814-
Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
815-
predicates.iter().find_map(|pred| match pred {
816-
GenericPredicate::Implemented(tr) => Some(tr.trait_),
817-
_ => None,
818-
})
819-
}
814+
Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred {
815+
GenericPredicate::Implemented(tr) => Some(tr.trait_),
816+
_ => None,
817+
}),
820818
_ => None,
821819
}
822820
}

crates/ra_hir_ty/src/method_resolution.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,9 @@ fn iterate_trait_method_candidates<T>(
408408
receiver_ty: Option<&Canonical<Ty>>,
409409
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
410410
) -> Option<T> {
411-
// if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
412-
let inherent_trait = self_ty.value.inherent_trait().into_iter();
411+
// if ty is `dyn Trait`, the trait doesn't need to be in scope
412+
let inherent_trait =
413+
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
413414
let env_traits = if let Ty::Placeholder(_) = self_ty.value {
414415
// if we have `T: Trait` in the param env, the trait doesn't need to be in scope
415416
env.trait_predicates_for_self_ty(&self_ty.value)
@@ -601,11 +602,6 @@ pub fn implements_trait(
601602
krate: CrateId,
602603
trait_: TraitId,
603604
) -> bool {
604-
if ty.value.inherent_trait() == Some(trait_) {
605-
// FIXME this is a bit of a hack, since Chalk should say the same thing
606-
// anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
607-
return true;
608-
}
609605
let goal = generic_implements_goal(db, env, trait_, ty.clone());
610606
let solution = db.trait_solve(krate, goal);
611607

crates/ra_hir_ty/src/tests/method_resolution.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,3 +1096,34 @@ fn test() { (S {}).method()<|>; }
10961096
);
10971097
assert_eq!(t, "()");
10981098
}
1099+
1100+
#[test]
1101+
fn dyn_trait_super_trait_not_in_scope() {
1102+
assert_snapshot!(
1103+
infer(r#"
1104+
mod m {
1105+
pub trait SuperTrait {
1106+
fn foo(&self) -> u32 { 0 }
1107+
}
1108+
}
1109+
trait Trait: m::SuperTrait {}
1110+
1111+
struct S;
1112+
impl m::SuperTrait for S {}
1113+
impl Trait for S {}
1114+
1115+
fn test(d: &dyn Trait) {
1116+
d.foo();
1117+
}
1118+
"#),
1119+
@r###"
1120+
52..56 'self': &Self
1121+
65..70 '{ 0 }': u32
1122+
67..68 '0': u32
1123+
177..178 'd': &dyn Trait
1124+
192..208 '{ ...o(); }': ()
1125+
198..199 'd': &dyn Trait
1126+
198..205 'd.foo()': u32
1127+
"###
1128+
);
1129+
}

0 commit comments

Comments
 (0)