Skip to content

Commit c42041b

Browse files
authored
Rollup merge of rust-lang#141438 - compiler-errors:dyn-compatible-call, r=lcnr
Do not try to confirm non-dyn compatible method See the comment I left in `compiler/rustc_hir_typeck/src/method/confirm.rs`. If we have a receiver that does not deref to the `dyn Trait` we're assembling the method from, then we used to ICE, but that's something that is possible to encounter with arbitrary self types. r? oli-obk Fixes rust-lang#141419
2 parents 08d42f0 + d041343 commit c42041b

23 files changed

+91
-304
lines changed

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
291291
probe::ObjectPick => {
292292
let trait_def_id = pick.item.container_id(self.tcx);
293293

294+
// If the trait is not object safe (specifically, we care about when
295+
// the receiver is not valid), then there's a chance that we will not
296+
// actually be able to recover the object by derefing the receiver like
297+
// we should if it were valid.
298+
if !self.tcx.is_dyn_compatible(trait_def_id) {
299+
return ty::GenericArgs::extend_with_error(self.tcx, trait_def_id, &[]);
300+
}
301+
294302
// This shouldn't happen for non-region error kinds, but may occur
295303
// when we have error regions. Specifically, since we canonicalize
296304
// during method steps, we may successfully deref when we assemble

tests/ui/async-await/dyn/mut-is-pointer-like.stderr

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,6 @@ LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
4242
= help: consider moving `async_dispatch` to another trait
4343
= 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 = ()>>`
4444

45-
error[E0277]: the trait bound `dyn AsyncTrait<Output = ()>: AsyncTrait` is not satisfied
46-
--> $DIR/mut-is-pointer-like.rs:36:11
47-
|
48-
LL | x.async_dispatch().await;
49-
| ^^^^^^^^^^^^^^ the trait `AsyncTrait` is not implemented for `dyn AsyncTrait<Output = ()>`
50-
51-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
52-
--> $DIR/mut-is-pointer-like.rs:36:9
53-
|
54-
LL | x.async_dispatch().await;
55-
| ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
56-
|
57-
note: for a trait to be dyn compatible it needs to allow building a vtable
58-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
59-
--> $DIR/mut-is-pointer-like.rs:16:14
60-
|
61-
LL | trait AsyncTrait {
62-
| ---------- this trait is not dyn compatible...
63-
...
64-
LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
65-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
66-
= help: consider moving `async_dispatch` to another trait
67-
68-
error: aborting due to 4 previous errors; 1 warning emitted
45+
error: aborting due to 2 previous errors; 1 warning emitted
6946

70-
Some errors have detailed explanations: E0038, E0277.
71-
For more information about an error, try `rustc --explain E0038`.
47+
For more information about this error, try `rustc --explain E0038`.

tests/ui/async-await/dyn/works.stderr

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,40 +42,6 @@ LL | async fn async_dispatch(&self);
4242
= help: consider moving `async_dispatch` to another trait
4343
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
4444

45-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
46-
--> $DIR/works.rs:28:11
47-
|
48-
LL | x.async_dispatch().await;
49-
| ^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
50-
|
51-
note: for a trait to be dyn compatible it needs to allow building a vtable
52-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
53-
--> $DIR/works.rs:14:14
54-
|
55-
LL | trait AsyncTrait {
56-
| ---------- this trait is not dyn compatible...
57-
LL | async fn async_dispatch(&self);
58-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
59-
= help: consider moving `async_dispatch` to another trait
60-
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
61-
62-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
63-
--> $DIR/works.rs:28:9
64-
|
65-
LL | x.async_dispatch().await;
66-
| ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
67-
|
68-
note: for a trait to be dyn compatible it needs to allow building a vtable
69-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
70-
--> $DIR/works.rs:14:14
71-
|
72-
LL | trait AsyncTrait {
73-
| ---------- this trait is not dyn compatible...
74-
LL | async fn async_dispatch(&self);
75-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
76-
= help: consider moving `async_dispatch` to another trait
77-
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
78-
79-
error: aborting due to 4 previous errors; 1 warning emitted
45+
error: aborting due to 2 previous errors; 1 warning emitted
8046

8147
For more information about this error, try `rustc --explain E0038`.

tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl Foo for () {
1515
}
1616

1717
fn use_dyn(v: &dyn Foo) { //~ERROR the trait `Foo` is not dyn compatible
18-
v.test(); //~ERROR the trait `Foo` is not dyn compatible
18+
v.test();
1919
}
2020

2121
fn main() {}

tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,6 @@ LL | fn test(&self) -> [u8; bar::<Self>()];
1717
= help: consider moving `test` to another trait
1818
= help: only type `()` implements `Foo`; consider using it directly instead.
1919

20-
error[E0038]: the trait `Foo` is not dyn compatible
21-
--> $DIR/dyn-compatibility-err-ret.rs:18:5
22-
|
23-
LL | v.test();
24-
| ^^^^^^^^ `Foo` is not dyn compatible
25-
|
26-
note: for a trait to be dyn compatible it needs to allow building a vtable
27-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
28-
--> $DIR/dyn-compatibility-err-ret.rs:8:8
29-
|
30-
LL | trait Foo {
31-
| --- this trait is not dyn compatible...
32-
LL | fn test(&self) -> [u8; bar::<Self>()];
33-
| ^^^^ ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
34-
| |
35-
| ...because method `test` references the `Self` type in its `where` clause
36-
= help: consider moving `test` to another trait
37-
= help: only type `()` implements `Foo`; consider using it directly instead.
38-
39-
error: aborting due to 2 previous errors
20+
error: aborting due to 1 previous error
4021

4122
For more information about this error, try `rustc --explain E0038`.

tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ impl Foo for () {
1515
fn use_dyn(v: &dyn Foo) {
1616
//~^ ERROR the trait `Foo` is not dyn compatible
1717
v.test();
18-
//~^ ERROR the trait `Foo` is not dyn compatible
1918
}
2019

2120
fn main() {}

tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,6 @@ LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
1515
= help: consider moving `test` to another trait
1616
= help: only type `()` implements `Foo`; consider using it directly instead.
1717

18-
error[E0038]: the trait `Foo` is not dyn compatible
19-
--> $DIR/dyn-compatibility-err-where-bounds.rs:17:5
20-
|
21-
LL | v.test();
22-
| ^^^^^^^^ `Foo` is not dyn compatible
23-
|
24-
note: for a trait to be dyn compatible it needs to allow building a vtable
25-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
26-
--> $DIR/dyn-compatibility-err-where-bounds.rs:8:8
27-
|
28-
LL | trait Foo {
29-
| --- this trait is not dyn compatible...
30-
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
31-
| ^^^^ ...because method `test` references the `Self` type in its `where` clause
32-
= help: consider moving `test` to another trait
33-
= help: only type `()` implements `Foo`; consider using it directly instead.
34-
35-
error: aborting due to 2 previous errors
18+
error: aborting due to 1 previous error
3619

3720
For more information about this error, try `rustc --explain E0038`.

tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,4 @@ pub fn foo() {
2525
let fetcher = fetcher();
2626
//~^ ERROR the trait `Fetcher` is not dyn compatible
2727
let _ = fetcher.get();
28-
//~^ ERROR the trait `Fetcher` is not dyn compatible
2928
}

tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,6 @@ LL | pub trait Fetcher: Send + Sync {
3434
LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
3535
| ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
3636

37-
error[E0038]: the trait `Fetcher` is not dyn compatible
38-
--> $DIR/undispatchable-receiver-and-wc-references-Self.rs:27:13
39-
|
40-
LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
41-
| ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self`
42-
...
43-
LL | let _ = fetcher.get();
44-
| ^^^^^^^^^^^^^ `Fetcher` is not dyn compatible
45-
|
46-
note: for a trait to be dyn compatible it needs to allow building a vtable
47-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
48-
--> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22
49-
|
50-
LL | pub trait Fetcher: Send + Sync {
51-
| ------- this trait is not dyn compatible...
52-
LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
53-
| ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
54-
55-
error: aborting due to 3 previous errors
37+
error: aborting due to 2 previous errors
5638

5739
For more information about this error, try `rustc --explain E0038`.

tests/ui/error-codes/E0038.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ trait Trait {
55
fn call_foo(x: Box<dyn Trait>) {
66
//~^ ERROR E0038
77
let y = x.foo();
8-
//~^ ERROR E0038
9-
//~| ERROR E0277
108
}
119

1210
fn main() {

tests/ui/error-codes/E0038.stderr

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,6 @@ LL | fn foo(&self) -> Self;
1414
| ^^^^ ...because method `foo` references the `Self` type in its return type
1515
= help: consider moving `foo` to another trait
1616

17-
error[E0038]: the trait `Trait` is not dyn compatible
18-
--> $DIR/E0038.rs:7:13
19-
|
20-
LL | let y = x.foo();
21-
| ^^^^^^^ `Trait` is not dyn compatible
22-
|
23-
note: for a trait to be dyn compatible it needs to allow building a vtable
24-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
25-
--> $DIR/E0038.rs:2:22
26-
|
27-
LL | trait Trait {
28-
| ----- this trait is not dyn compatible...
29-
LL | fn foo(&self) -> Self;
30-
| ^^^^ ...because method `foo` references the `Self` type in its return type
31-
= help: consider moving `foo` to another trait
32-
33-
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
34-
--> $DIR/E0038.rs:7:9
35-
|
36-
LL | let y = x.foo();
37-
| ^ doesn't have a size known at compile-time
38-
|
39-
= help: the trait `Sized` is not implemented for `dyn Trait`
40-
= note: all local variables must have a statically known size
41-
= help: unsized locals are gated as an unstable feature
42-
43-
error: aborting due to 3 previous errors
17+
error: aborting due to 1 previous error
4418

45-
Some errors have detailed explanations: E0038, E0277.
46-
For more information about an error, try `rustc --explain E0038`.
19+
For more information about this error, try `rustc --explain E0038`.

tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ trait Foo {
77
async fn takes_dyn_trait(x: &dyn Foo) {
88
//~^ ERROR the trait `Foo` is not dyn compatible
99
x.bar().await;
10-
//~^ ERROR the trait `Foo` is not dyn compatible
11-
//~| ERROR the trait `Foo` is not dyn compatible
1210
}
1311

1412
fn main() {}

tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,6 @@ LL | async fn bar(&self);
1414
| ^^^ ...because method `bar` is `async`
1515
= help: consider moving `bar` to another trait
1616

17-
error[E0038]: the trait `Foo` is not dyn compatible
18-
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:7
19-
|
20-
LL | x.bar().await;
21-
| ^^^ `Foo` is not dyn compatible
22-
|
23-
note: for a trait to be dyn compatible it needs to allow building a vtable
24-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
25-
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
26-
|
27-
LL | trait Foo {
28-
| --- this trait is not dyn compatible...
29-
LL | async fn bar(&self);
30-
| ^^^ ...because method `bar` is `async`
31-
= help: consider moving `bar` to another trait
32-
33-
error[E0038]: the trait `Foo` is not dyn compatible
34-
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:5
35-
|
36-
LL | x.bar().await;
37-
| ^^^^^^^ `Foo` is not dyn compatible
38-
|
39-
note: for a trait to be dyn compatible it needs to allow building a vtable
40-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
41-
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
42-
|
43-
LL | trait Foo {
44-
| --- this trait is not dyn compatible...
45-
LL | async fn bar(&self);
46-
| ^^^ ...because method `bar` is `async`
47-
= help: consider moving `bar` to another trait
48-
49-
error: aborting due to 3 previous errors
17+
error: aborting due to 1 previous error
5018

5119
For more information about this error, try `rustc --explain E0038`.

tests/ui/generic-associated-types/trait-objects.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ trait StreamingIterator {
88
fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
99
//~^ ERROR the trait `StreamingIterator` is not dyn compatible
1010
x.size_hint().0
11-
//~^ ERROR the trait `StreamingIterator` is not dyn compatible
12-
//~| ERROR the trait `StreamingIterator` is not dyn compatible
1311
}
1412

1513
fn main() {}

tests/ui/generic-associated-types/trait-objects.stderr

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,6 @@ LL | type Item<'a> where Self: 'a;
1414
| ^^^^ ...because it contains the generic associated type `Item`
1515
= help: consider moving `Item` to another trait
1616

17-
error[E0038]: the trait `StreamingIterator` is not dyn compatible
18-
--> $DIR/trait-objects.rs:10:7
19-
|
20-
LL | x.size_hint().0
21-
| ^^^^^^^^^ `StreamingIterator` is not dyn compatible
22-
|
23-
note: for a trait to be dyn compatible it needs to allow building a vtable
24-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
25-
--> $DIR/trait-objects.rs:2:10
26-
|
27-
LL | trait StreamingIterator {
28-
| ----------------- this trait is not dyn compatible...
29-
LL | type Item<'a> where Self: 'a;
30-
| ^^^^ ...because it contains the generic associated type `Item`
31-
= help: consider moving `Item` to another trait
32-
33-
error[E0038]: the trait `StreamingIterator` is not dyn compatible
34-
--> $DIR/trait-objects.rs:10:5
35-
|
36-
LL | x.size_hint().0
37-
| ^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible
38-
|
39-
note: for a trait to be dyn compatible it needs to allow building a vtable
40-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
41-
--> $DIR/trait-objects.rs:2:10
42-
|
43-
LL | trait StreamingIterator {
44-
| ----------------- this trait is not dyn compatible...
45-
LL | type Item<'a> where Self: 'a;
46-
| ^^^^ ...because it contains the generic associated type `Item`
47-
= help: consider moving `Item` to another trait
48-
49-
error: aborting due to 3 previous errors
17+
error: aborting due to 1 previous error
5018

5119
For more information about this error, try `rustc --explain E0038`.

tests/ui/impl-trait/in-trait/dyn-compatibility.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@ fn main() {
1515
//~^ ERROR the trait `Foo` is not dyn compatible
1616
//~| ERROR the trait `Foo` is not dyn compatible
1717
let s = i.baz();
18-
//~^ ERROR the trait `Foo` is not dyn compatible
19-
//~| ERROR the trait `Foo` is not dyn compatible
2018
}

tests/ui/impl-trait/in-trait/dyn-compatibility.stderr

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,6 @@ LL | fn baz(&self) -> impl Debug;
1515
= help: consider moving `baz` to another trait
1616
= help: only type `u32` implements `Foo`; consider using it directly instead.
1717

18-
error[E0038]: the trait `Foo` is not dyn compatible
19-
--> $DIR/dyn-compatibility.rs:17:15
20-
|
21-
LL | let s = i.baz();
22-
| ^^^ `Foo` is not dyn compatible
23-
|
24-
note: for a trait to be dyn compatible it needs to allow building a vtable
25-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
26-
--> $DIR/dyn-compatibility.rs:4:22
27-
|
28-
LL | trait Foo {
29-
| --- this trait is not dyn compatible...
30-
LL | fn baz(&self) -> impl Debug;
31-
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
32-
= help: consider moving `baz` to another trait
33-
= help: only type `u32` implements `Foo`; consider using it directly instead.
34-
35-
error[E0038]: the trait `Foo` is not dyn compatible
36-
--> $DIR/dyn-compatibility.rs:17:13
37-
|
38-
LL | let s = i.baz();
39-
| ^^^^^^^ `Foo` is not dyn compatible
40-
|
41-
note: for a trait to be dyn compatible it needs to allow building a vtable
42-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
43-
--> $DIR/dyn-compatibility.rs:4:22
44-
|
45-
LL | trait Foo {
46-
| --- this trait is not dyn compatible...
47-
LL | fn baz(&self) -> impl Debug;
48-
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
49-
= help: consider moving `baz` to another trait
50-
= help: only type `u32` implements `Foo`; consider using it directly instead.
51-
5218
error[E0038]: the trait `Foo` is not dyn compatible
5319
--> $DIR/dyn-compatibility.rs:14:13
5420
|
@@ -67,6 +33,6 @@ LL | fn baz(&self) -> impl Debug;
6733
= help: only type `u32` implements `Foo`; consider using it directly instead.
6834
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
6935

70-
error: aborting due to 4 previous errors
36+
error: aborting due to 2 previous errors
7137

7238
For more information about this error, try `rustc --explain E0038`.

tests/ui/issues/issue-18959.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ impl Foo for Thing {
1111
fn foo(b: &dyn Bar) {
1212
//~^ ERROR E0038
1313
b.foo(&0)
14-
//~^ ERROR E0038
1514
}
1615

1716
fn main() {

0 commit comments

Comments
 (0)