Skip to content

Commit 29fef56

Browse files
Elaborate trait assumption in receiver_is_dispatchable
1 parent 03eb454 commit 29fef56

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,8 @@ fn receiver_is_dispatchable<'tcx>(
579579
let unsized_receiver_ty =
580580
receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id);
581581

582-
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
583-
// `U: ?Sized` is already implied here
582+
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
583+
// its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
584584
let param_env = {
585585
let param_env = tcx.param_env(method.def_id);
586586

@@ -598,8 +598,10 @@ fn receiver_is_dispatchable<'tcx>(
598598
ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
599599
};
600600

601-
let caller_bounds =
602-
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
601+
let caller_bounds = param_env
602+
.caller_bounds()
603+
.iter()
604+
.chain(elaborate(tcx, [unsize_predicate, trait_predicate]));
603605

604606
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds))
605607
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//@ check-pass
2+
3+
#![feature(derive_coerce_pointee)]
4+
#![feature(arbitrary_self_types)]
5+
6+
use std::ops::Deref;
7+
use std::marker::CoercePointee;
8+
use std::sync::Arc;
9+
10+
trait MyTrait {}
11+
12+
#[derive(CoercePointee)]
13+
#[repr(transparent)]
14+
struct MyArc<T>
15+
where
16+
T: MyTrait + ?Sized,
17+
{
18+
inner: Arc<T>
19+
}
20+
21+
impl<T: MyTrait + ?Sized> Deref for MyArc<T> {
22+
type Target = T;
23+
fn deref(&self) -> &T {
24+
&self.inner
25+
}
26+
}
27+
28+
// Proving that `MyArc<Self>` is dyn-dispatchable requires proving `MyArc<T>` implements
29+
// `DispatchFromDyn<MyArc<U>>`. The `DispatchFromDyn` impl that is generated from the
30+
// `CoercePointee` implementation requires the pointee impls `MyTrait`, but previously we
31+
// were only assuming the pointee impl'd `MyOtherTrait`. Elaboration comes to the rescue here.
32+
trait MyOtherTrait: MyTrait {
33+
fn foo(self: MyArc<Self>);
34+
}
35+
36+
fn test(_: MyArc<dyn MyOtherTrait>) {}
37+
38+
fn main() {}

0 commit comments

Comments
 (0)