aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-05-16 17:32:15 +0100
committerFlorian Diebold <[email protected]>2020-05-16 17:37:05 +0100
commit811d25b7237cfb74a312369a7820bf6fbb81483e (patch)
tree83934cff398526185a237937140716d18a9c6744
parent9322790066fe86056965332078bed74ff7f77293 (diff)
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.
-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}