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 <flodiebold@gmail.com>
This commit is contained in:
commit
8944a9b35a
@ -808,15 +808,13 @@ impl Ty {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
}
|
||||
}
|
||||
|
@ -408,8 +408,9 @@ fn iterate_trait_method_candidates<T>(
|
||||
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)
|
||||
@ -601,11 +602,6 @@ pub fn implements_trait(
|
||||
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);
|
||||
|
||||
|
@ -1096,3 +1096,34 @@ fn test() { (S {}).method()<|>; }
|
||||
);
|
||||
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
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user