Skip to content

Commit 8944a9b

Browse files
Merge #4484
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 <[email protected]>
2 parents ebaa05a + 811d25b commit 8944a9b

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)