Skip to content

Do not try to confirm non-dyn compatible method #141438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
8 changes: 8 additions & 0 deletions compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 2 additions & 26 deletions tests/ui/async-await/dyn/mut-is-pointer-like.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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[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
error: aborting due to 2 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`.
36 changes: 1 addition & 35 deletions tests/ui/async-await/dyn/works.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
2 changes: 0 additions & 2 deletions tests/ui/error-codes/E0038.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
31 changes: 2 additions & 29 deletions tests/ui/error-codes/E0038.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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[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
error: aborting due to 1 previous error

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`.
2 changes: 0 additions & 2 deletions tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
34 changes: 1 addition & 33 deletions tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
2 changes: 0 additions & 2 deletions tests/ui/generic-associated-types/trait-objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
34 changes: 1 addition & 33 deletions tests/ui/generic-associated-types/trait-objects.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
2 changes: 0 additions & 2 deletions tests/ui/impl-trait/in-trait/dyn-compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
36 changes: 1 addition & 35 deletions tests/ui/impl-trait/in-trait/dyn-compatibility.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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`.
1 change: 0 additions & 1 deletion tests/ui/issues/issue-18959.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ impl Foo for Thing {
fn foo(b: &dyn Bar) {
//~^ ERROR E0038
b.foo(&0)
//~^ ERROR E0038
}

fn main() {
Expand Down
Loading
Loading