Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,12 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
}
_ => return,
};

// Projecting `dyn Trait` is only valid when `Trait` is dyn-compatible.
if data.principal_def_id().is_some_and(|def_id| !tcx.is_dyn_compatible(def_id)) {
return;
}

let env_predicates = data
.projection_bounds()
.filter(|bound| bound.item_def_id() == obligation.predicate.def_id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait Foo: Deref<Target = W> {
fn test(x: &dyn Foo) {
//~^ ERROR the trait `Foo` is not dyn compatible
x.method();
//~^ ERROR the trait `Foo` is not dyn compatible
//~^ ERROR no method named `method` found for reference `&dyn Foo`
Copy link
Copy Markdown
Contributor

@lcnr lcnr Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

that's annoying :< ideally we'd silence method errors if the self type is not well-formed, tracking that is non-trivial and I don't know how we'd do so myself rn

}

fn main() {}
19 changes: 5 additions & 14 deletions tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,16 @@ LL | fn method(self: &W) {}
= note: type of `self` must be `Self` or a type that dereferences to it
= 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`)

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

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0038, E0307.
Some errors have detailed explanations: E0038, E0307, E0599.
For more information about an error, try `rustc --explain E0038`.
3 changes: 2 additions & 1 deletion tests/ui/traits/ice-with-dyn-pointee-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
fn raw_pointer_in(x: &dyn Pointee<Metadata = ()>) {
//~^ ERROR the trait `Pointee` is not dyn compatible
unknown_sized_object_ptr_in(x)
//~^ ERROR the trait `Pointee` is not dyn compatible
//~^ ERROR type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::Metadata == ()`
//~| ERROR the trait `Pointee` is not dyn compatible
}

fn main() {
Expand Down
23 changes: 20 additions & 3 deletions tests/ui/traits/ice-with-dyn-pointee-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ note: for a trait to be dyn compatible it needs to allow building a vtable
|
= note: the trait is not dyn compatible because it opted out of dyn-compatibility

error[E0271]: type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::Metadata == ()`
--> $DIR/ice-with-dyn-pointee-errors.rs:10:33
|
LL | unknown_sized_object_ptr_in(x)
| --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ()>>`
| |
| required by a bound introduced by this call
|
= note: expected unit type `()`
found struct `DynMetadata<dyn Pointee<Metadata = ()>>`
note: required by a bound in `unknown_sized_object_ptr_in`
--> $DIR/ice-with-dyn-pointee-errors.rs:6:50
|
LL | fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
| ^^^^^^^^^^^^^ required by this bound in `unknown_sized_object_ptr_in`

error[E0038]: the trait `Pointee` is not dyn compatible
--> $DIR/ice-with-dyn-pointee-errors.rs:10:5
|
Expand All @@ -23,7 +39,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable
= note: the trait is not dyn compatible because it opted out of dyn-compatibility

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

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

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