}
}
- /// 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,
}
}
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)
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);
);
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
+ "###
+ );
+}