aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_ty/src/lib.rs14
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs10
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs31
3 files changed, 40 insertions, 15 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index ccc4348f4..daea02f88 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -808,15 +808,13 @@ impl Ty {
808 } 808 }
809 } 809 }
810 810
811 /// If this is an `impl Trait` or `dyn Trait`, returns that trait. 811 /// If this is a `dyn Trait`, returns that trait.
812 pub fn inherent_trait(&self) -> Option<TraitId> { 812 pub fn dyn_trait(&self) -> Option<TraitId> {
813 match self { 813 match self {
814 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 814 Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred {
815 predicates.iter().find_map(|pred| match pred { 815 GenericPredicate::Implemented(tr) => Some(tr.trait_),
816 GenericPredicate::Implemented(tr) => Some(tr.trait_), 816 _ => None,
817 _ => None, 817 }),
818 })
819 }
820 _ => None, 818 _ => None,
821 } 819 }
822 } 820 }
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 657284fd0..0851e16a8 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -408,8 +408,9 @@ fn iterate_trait_method_candidates<T>(
408 receiver_ty: Option<&Canonical<Ty>>, 408 receiver_ty: Option<&Canonical<Ty>>,
409 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 409 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
410) -> Option<T> { 410) -> Option<T> {
411 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope 411 // if ty is `dyn Trait`, the trait doesn't need to be in scope
412 let inherent_trait = self_ty.value.inherent_trait().into_iter(); 412 let inherent_trait =
413 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
413 let env_traits = if let Ty::Placeholder(_) = self_ty.value { 414 let env_traits = if let Ty::Placeholder(_) = self_ty.value {
414 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 415 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
415 env.trait_predicates_for_self_ty(&self_ty.value) 416 env.trait_predicates_for_self_ty(&self_ty.value)
@@ -601,11 +602,6 @@ pub fn implements_trait(
601 krate: CrateId, 602 krate: CrateId,
602 trait_: TraitId, 603 trait_: TraitId,
603) -> bool { 604) -> 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 }
609 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 605 let goal = generic_implements_goal(db, env, trait_, ty.clone());
610 let solution = db.trait_solve(krate, goal); 606 let solution = db.trait_solve(krate, goal);
611 607
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 67f964ab5..9c2c9e1d2 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -1096,3 +1096,34 @@ fn test() { (S {}).method()<|>; }
1096 ); 1096 );
1097 assert_eq!(t, "()"); 1097 assert_eq!(t, "()");
1098} 1098}
1099
1100#[test]
1101fn dyn_trait_super_trait_not_in_scope() {
1102 assert_snapshot!(
1103 infer(r#"
1104mod m {
1105 pub trait SuperTrait {
1106 fn foo(&self) -> u32 { 0 }
1107 }
1108}
1109trait Trait: m::SuperTrait {}
1110
1111struct S;
1112impl m::SuperTrait for S {}
1113impl Trait for S {}
1114
1115fn 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}