Skip to content

Commit a611f2a

Browse files
committed
Auto merge of #154992 - spirali:fix-dyn-projection, r=<try>
Error on projection of dyn noncompat type in old trait solver
2 parents 1fe72d3 + 8aaa286 commit a611f2a

5 files changed

Lines changed: 34 additions & 19 deletions

File tree

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,12 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
813813
}
814814
_ => return,
815815
};
816+
817+
// Projecting `dyn Trait` is only valid when `Trait` is dyn-compatible.
818+
if data.principal_def_id().is_some_and(|def_id| !tcx.is_dyn_compatible(def_id)) {
819+
return;
820+
}
821+
816822
let env_predicates = data
817823
.projection_bounds()
818824
.filter(|bound| bound.item_def_id() == obligation.predicate.def_id)

tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ trait Foo: Deref<Target = W> {
1212
fn test(x: &dyn Foo) {
1313
//~^ ERROR the trait `Foo` is not dyn compatible
1414
x.method();
15-
//~^ ERROR the trait `Foo` is not dyn compatible
15+
//~^ ERROR no method named `method` found for reference `&dyn Foo`
1616
}
1717

1818
fn main() {}

tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.stderr

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,16 @@ LL | fn method(self: &W) {}
2525
= note: type of `self` must be `Self` or a type that dereferences to it
2626
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
2727

28-
error[E0038]: the trait `Foo` is not dyn compatible
29-
--> $DIR/dispatch-dyn-incompatible-that-does-not-deref.rs:14:5
28+
error[E0599]: no method named `method` found for reference `&dyn Foo` in the current scope
29+
--> $DIR/dispatch-dyn-incompatible-that-does-not-deref.rs:14:7
3030
|
3131
LL | fn method(self: &W) {}
32-
| -- help: consider changing method `method`'s `self` parameter to be `&self`: `&Self`
32+
| -- the method might not be found because of this arbitrary self type
3333
...
3434
LL | x.method();
35-
| ^^^^^^^^^^ `Foo` is not dyn compatible
36-
|
37-
note: for a trait to be dyn compatible it needs to allow building a vtable
38-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
39-
--> $DIR/dispatch-dyn-incompatible-that-does-not-deref.rs:8:21
40-
|
41-
LL | trait Foo: Deref<Target = W> {
42-
| --- this trait is not dyn compatible...
43-
LL | fn method(self: &W) {}
44-
| ^^ ...because method `method`'s `self` parameter cannot be dispatched on
35+
| ^^^^^^ method not found in `&dyn Foo`
4536

4637
error: aborting due to 3 previous errors
4738

48-
Some errors have detailed explanations: E0038, E0307.
39+
Some errors have detailed explanations: E0038, E0307, E0599.
4940
For more information about an error, try `rustc --explain E0038`.

tests/ui/traits/ice-with-dyn-pointee-errors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
88
fn raw_pointer_in(x: &dyn Pointee<Metadata = ()>) {
99
//~^ ERROR the trait `Pointee` is not dyn compatible
1010
unknown_sized_object_ptr_in(x)
11-
//~^ ERROR the trait `Pointee` is not dyn compatible
11+
//~^ ERROR type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::Metadata == ()`
12+
//~| ERROR the trait `Pointee` is not dyn compatible
1213
}
1314

1415
fn main() {

tests/ui/traits/ice-with-dyn-pointee-errors.stderr

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ note: for a trait to be dyn compatible it needs to allow building a vtable
1010
|
1111
= note: the trait is not dyn compatible because it opted out of dyn-compatibility
1212

13+
error[E0271]: type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::Metadata == ()`
14+
--> $DIR/ice-with-dyn-pointee-errors.rs:10:33
15+
|
16+
LL | unknown_sized_object_ptr_in(x)
17+
| --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ()>>`
18+
| |
19+
| required by a bound introduced by this call
20+
|
21+
= note: expected unit type `()`
22+
found struct `DynMetadata<dyn Pointee<Metadata = ()>>`
23+
note: required by a bound in `unknown_sized_object_ptr_in`
24+
--> $DIR/ice-with-dyn-pointee-errors.rs:6:50
25+
|
26+
LL | fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
27+
| ^^^^^^^^^^^^^ required by this bound in `unknown_sized_object_ptr_in`
28+
1329
error[E0038]: the trait `Pointee` is not dyn compatible
1430
--> $DIR/ice-with-dyn-pointee-errors.rs:10:5
1531
|
@@ -23,7 +39,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable
2339
= note: the trait is not dyn compatible because it opted out of dyn-compatibility
2440

2541
error[E0038]: the trait `Pointee` is not dyn compatible
26-
--> $DIR/ice-with-dyn-pointee-errors.rs:15:20
42+
--> $DIR/ice-with-dyn-pointee-errors.rs:16:20
2743
|
2844
LL | raw_pointer_in(&42)
2945
| ^^^ `Pointee` is not dyn compatible
@@ -34,6 +50,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable
3450
|
3551
= note: the trait is not dyn compatible because it opted out of dyn-compatibility
3652

37-
error: aborting due to 3 previous errors
53+
error: aborting due to 4 previous errors
3854

39-
For more information about this error, try `rustc --explain E0038`.
55+
Some errors have detailed explanations: E0038, E0271.
56+
For more information about an error, try `rustc --explain E0038`.

0 commit comments

Comments
 (0)