Do not try to confirm non-dyn compatible method

This commit is contained in:
Michael Goulet 2025-05-23 11:27:07 +00:00
parent 52bf0cf795
commit d0413436d5
23 changed files with 91 additions and 304 deletions

View file

@ -291,6 +291,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
probe::ObjectPick => {
let trait_def_id = pick.item.container_id(self.tcx);
// If the trait is not object safe (specifically, we care about when
// the receiver is not valid), then there's a chance that we will not
// actually be able to recover the object by derefing the receiver like
// we should if it were valid.
if !self.tcx.is_dyn_compatible(trait_def_id) {
return ty::GenericArgs::extend_with_error(self.tcx, trait_def_id, &[]);
}
// This shouldn't happen for non-region error kinds, but may occur
// when we have error regions. Specifically, since we canonicalize
// during method steps, we may successfully deref when we assemble

View file

@ -42,30 +42,6 @@ LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
= help: consider moving `async_dispatch` to another trait
= note: required for the cast from `Pin<&mut {async block@$DIR/mut-is-pointer-like.rs:32:32: 32:37}>` to `Pin<&mut dyn AsyncTrait<Output = ()>>`
error[E0277]: the trait bound `dyn AsyncTrait<Output = ()>: AsyncTrait` is not satisfied
--> $DIR/mut-is-pointer-like.rs:36:11
|
LL | x.async_dispatch().await;
| ^^^^^^^^^^^^^^ the trait `AsyncTrait` is not implemented for `dyn AsyncTrait<Output = ()>`
error: aborting due to 2 previous errors; 1 warning emitted
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/mut-is-pointer-like.rs:36:9
|
LL | x.async_dispatch().await;
| ^^^^^^^^^^^^^^^^^^ `AsyncTrait` 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/mut-is-pointer-like.rs:16:14
|
LL | trait AsyncTrait {
| ---------- this trait is not dyn compatible...
...
LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
error: aborting due to 4 previous errors; 1 warning emitted
Some errors have detailed explanations: E0038, E0277.
For more information about an error, try `rustc --explain E0038`.
For more information about this error, try `rustc --explain E0038`.

View file

@ -42,40 +42,6 @@ LL | async fn async_dispatch(&self);
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/works.rs:28:11
|
LL | x.async_dispatch().await;
| ^^^^^^^^^^^^^^ `AsyncTrait` 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/works.rs:14:14
|
LL | trait AsyncTrait {
| ---------- this trait is not dyn compatible...
LL | async fn async_dispatch(&self);
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/works.rs:28:9
|
LL | x.async_dispatch().await;
| ^^^^^^^^^^^^^^^^^^ `AsyncTrait` 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/works.rs:14:14
|
LL | trait AsyncTrait {
| ---------- this trait is not dyn compatible...
LL | async fn async_dispatch(&self);
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
error: aborting due to 4 previous errors; 1 warning emitted
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0038`.

View file

@ -15,7 +15,7 @@ impl Foo for () {
}
fn use_dyn(v: &dyn Foo) { //~ERROR the trait `Foo` is not dyn compatible
v.test(); //~ERROR the trait `Foo` is not dyn compatible
v.test();
}
fn main() {}

View file

@ -17,25 +17,6 @@ LL | fn test(&self) -> [u8; bar::<Self>()];
= help: consider moving `test` to another trait
= help: only type `()` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dyn-compatibility-err-ret.rs:18:5
|
LL | v.test();
| ^^^^^^^^ `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/dyn-compatibility-err-ret.rs:8:8
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn test(&self) -> [u8; bar::<Self>()];
| ^^^^ ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
| |
| ...because method `test` references the `Self` type in its `where` clause
= help: consider moving `test` to another trait
= help: only type `()` implements `Foo`; consider using it directly instead.
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -15,7 +15,6 @@ impl Foo for () {
fn use_dyn(v: &dyn Foo) {
//~^ ERROR the trait `Foo` is not dyn compatible
v.test();
//~^ ERROR the trait `Foo` is not dyn compatible
}
fn main() {}

View file

@ -15,23 +15,6 @@ LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
= help: consider moving `test` to another trait
= help: only type `()` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dyn-compatibility-err-where-bounds.rs:17:5
|
LL | v.test();
| ^^^^^^^^ `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/dyn-compatibility-err-where-bounds.rs:8:8
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
| ^^^^ ...because method `test` references the `Self` type in its `where` clause
= help: consider moving `test` to another trait
= help: only type `()` implements `Foo`; consider using it directly instead.
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -25,5 +25,4 @@ pub fn foo() {
let fetcher = fetcher();
//~^ ERROR the trait `Fetcher` is not dyn compatible
let _ = fetcher.get();
//~^ ERROR the trait `Fetcher` is not dyn compatible
}

View file

@ -34,24 +34,6 @@ LL | pub trait Fetcher: Send + Sync {
LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
| ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
error[E0038]: the trait `Fetcher` is not dyn compatible
--> $DIR/undispatchable-receiver-and-wc-references-Self.rs:27:13
|
LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
| ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self`
...
LL | let _ = fetcher.get();
| ^^^^^^^^^^^^^ `Fetcher` 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/undispatchable-receiver-and-wc-references-Self.rs:11:22
|
LL | pub trait Fetcher: Send + Sync {
| ------- this trait is not dyn compatible...
LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
| ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -5,8 +5,6 @@ trait Trait {
fn call_foo(x: Box<dyn Trait>) {
//~^ ERROR E0038
let y = x.foo();
//~^ ERROR E0038
//~| ERROR E0277
}
fn main() {

View file

@ -14,33 +14,6 @@ LL | fn foo(&self) -> Self;
| ^^^^ ...because method `foo` references the `Self` type in its return type
= help: consider moving `foo` to another trait
error[E0038]: the trait `Trait` is not dyn compatible
--> $DIR/E0038.rs:7:13
|
LL | let y = x.foo();
| ^^^^^^^ `Trait` 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/E0038.rs:2:22
|
LL | trait Trait {
| ----- this trait is not dyn compatible...
LL | fn foo(&self) -> Self;
| ^^^^ ...because method `foo` references the `Self` type in its return type
= help: consider moving `foo` to another trait
error: aborting due to 1 previous error
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
--> $DIR/E0038.rs:7:9
|
LL | let y = x.foo();
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Trait`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0038, E0277.
For more information about an error, try `rustc --explain E0038`.
For more information about this error, try `rustc --explain E0038`.

View file

@ -7,8 +7,6 @@ trait Foo {
async fn takes_dyn_trait(x: &dyn Foo) {
//~^ ERROR the trait `Foo` is not dyn compatible
x.bar().await;
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
}
fn main() {}

View file

@ -14,38 +14,6 @@ LL | async fn bar(&self);
| ^^^ ...because method `bar` is `async`
= help: consider moving `bar` to another trait
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:7
|
LL | x.bar().await;
| ^^^ `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/feature-gate-async-fn-in-dyn-trait.rs:4:14
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | async fn bar(&self);
| ^^^ ...because method `bar` is `async`
= help: consider moving `bar` to another trait
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:5
|
LL | x.bar().await;
| ^^^^^^^ `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/feature-gate-async-fn-in-dyn-trait.rs:4:14
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | async fn bar(&self);
| ^^^ ...because method `bar` is `async`
= help: consider moving `bar` to another trait
error: aborting due to 3 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -8,8 +8,6 @@ trait StreamingIterator {
fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
//~^ ERROR the trait `StreamingIterator` is not dyn compatible
x.size_hint().0
//~^ ERROR the trait `StreamingIterator` is not dyn compatible
//~| ERROR the trait `StreamingIterator` is not dyn compatible
}
fn main() {}

View file

@ -14,38 +14,6 @@ LL | type Item<'a> where Self: 'a;
| ^^^^ ...because it contains the generic associated type `Item`
= help: consider moving `Item` to another trait
error[E0038]: the trait `StreamingIterator` is not dyn compatible
--> $DIR/trait-objects.rs:10:7
|
LL | x.size_hint().0
| ^^^^^^^^^ `StreamingIterator` 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/trait-objects.rs:2:10
|
LL | trait StreamingIterator {
| ----------------- this trait is not dyn compatible...
LL | type Item<'a> where Self: 'a;
| ^^^^ ...because it contains the generic associated type `Item`
= help: consider moving `Item` to another trait
error[E0038]: the trait `StreamingIterator` is not dyn compatible
--> $DIR/trait-objects.rs:10:5
|
LL | x.size_hint().0
| ^^^^^^^^^^^^^ `StreamingIterator` 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/trait-objects.rs:2:10
|
LL | trait StreamingIterator {
| ----------------- this trait is not dyn compatible...
LL | type Item<'a> where Self: 'a;
| ^^^^ ...because it contains the generic associated type `Item`
= help: consider moving `Item` to another trait
error: aborting due to 3 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -15,6 +15,4 @@ fn main() {
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
let s = i.baz();
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
}

View file

@ -15,40 +15,6 @@ LL | fn baz(&self) -> impl Debug;
= help: consider moving `baz` to another trait
= help: only type `u32` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dyn-compatibility.rs:17:15
|
LL | let s = i.baz();
| ^^^ `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/dyn-compatibility.rs:4:22
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn baz(&self) -> impl Debug;
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
= help: only type `u32` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dyn-compatibility.rs:17:13
|
LL | let s = i.baz();
| ^^^^^^^ `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/dyn-compatibility.rs:4:22
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn baz(&self) -> impl Debug;
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
= help: only type `u32` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dyn-compatibility.rs:14:13
|
@ -67,6 +33,6 @@ LL | fn baz(&self) -> impl Debug;
= help: only type `u32` implements `Foo`; consider using it directly instead.
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -11,7 +11,6 @@ impl Foo for Thing {
fn foo(b: &dyn Bar) {
//~^ ERROR E0038
b.foo(&0)
//~^ ERROR E0038
}
fn main() {

View file

@ -15,23 +15,7 @@ LL | pub trait Bar: Foo { }
= help: consider moving `foo` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/issue-18959.rs:13:5
|
LL | b.foo(&0)
| ^^^^^^^^^ `Bar` 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/issue-18959.rs:1:20
|
LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
| ^^^ ...because method `foo` has generic type parameters
LL | pub trait Bar: Foo { }
| --- this trait is not dyn compatible...
= help: consider moving `foo` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/issue-18959.rs:19:26
--> $DIR/issue-18959.rs:18:26
|
LL | let test: &dyn Bar = &mut thing;
| ^^^^^^^^^^ `Bar` is not dyn compatible
@ -48,7 +32,7 @@ LL | pub trait Bar: Foo { }
= note: required for the cast from `&mut Thing` to `&dyn Bar`
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/issue-18959.rs:19:15
--> $DIR/issue-18959.rs:18:15
|
LL | let test: &dyn Bar = &mut thing;
| ^^^^^^^^ `Bar` is not dyn compatible
@ -63,6 +47,6 @@ LL | pub trait Bar: Foo { }
| --- this trait is not dyn compatible...
= help: consider moving `foo` to another trait
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -0,0 +1,18 @@
// Regression test for <https://github.com/rust-lang/rust/issues/141419>.
use std::ops::Deref;
struct W;
trait Foo: Deref<Target = W> {
fn method(self: &W) {}
//~^ ERROR invalid `self` parameter type: `&W`
}
fn test(x: &dyn Foo) {
//~^ ERROR the trait `Foo` is not dyn compatible
x.method();
//~^ ERROR the trait `Foo` is not dyn compatible
}
fn main() {}

View file

@ -0,0 +1,49 @@
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dispatch-dyn-incompatible-that-does-not-deref.rs:12:13
|
LL | fn method(self: &W) {}
| -- help: consider changing method `method`'s `self` parameter to be `&self`: `&Self`
...
LL | fn test(x: &dyn Foo) {
| ^^^^^^^ `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
error[E0307]: invalid `self` parameter type: `&W`
--> $DIR/dispatch-dyn-incompatible-that-does-not-deref.rs:8:21
|
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
|
LL | fn method(self: &W) {}
| -- help: consider changing method `method`'s `self` parameter to be `&self`: `&Self`
...
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
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0038, E0307.
For more information about an error, try `rustc --explain E0038`.

View file

@ -13,5 +13,4 @@ fn main() {
(Box::new(10) as Box<dyn bar>).dup();
//~^ ERROR E0038
//~| ERROR E0038
//~| ERROR E0038
}

View file

@ -49,29 +49,6 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
consider defining an enum where each variant holds one of these types,
implementing `bar` for this new enum and using it instead
error[E0038]: the trait `bar` is not dyn compatible
--> $DIR/test-2.rs:13:5
|
LL | (Box::new(10) as Box<dyn bar>).dup();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `bar` 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/test-2.rs:4:30
|
LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
| --- ^^^^ ^^^^ ...because method `blah` has generic type parameters
| | |
| | ...because method `dup` references the `Self` type in its return type
| this trait is not dyn compatible...
= help: consider moving `dup` to another trait
= help: consider moving `blah` to another trait
= help: the following types implement `bar`:
i32
u32
consider defining an enum where each variant holds one of these types,
implementing `bar` for this new enum and using it instead
error[E0038]: the trait `bar` is not dyn compatible
--> $DIR/test-2.rs:13:6
|
@ -96,7 +73,7 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
implementing `bar` for this new enum and using it instead
= note: required for the cast from `Box<{integer}>` to `Box<dyn bar>`
error: aborting due to 5 previous errors
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.