Skip to content

Commit c375f69

Browse files
Do not try to confirm non-dyn compatible method
1 parent 52bf0cf commit c375f69

25 files changed

+100
-313
lines changed

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
288288
self.fresh_args_for_item(self.span, impl_def_id)
289289
}
290290

291-
probe::ObjectPick => {
291+
probe::ObjectPick(principal_def_id) => {
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(principal_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

compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8080
return;
8181
}
8282

83-
if matches!(pick.kind, probe::PickKind::InherentImplPick | probe::PickKind::ObjectPick) {
83+
if matches!(pick.kind, probe::PickKind::InherentImplPick | probe::PickKind::ObjectPick(_)) {
8484
// avoid repeatedly adding unneeded `&*`s
8585
if pick.autoderefs == 1
8686
&& matches!(

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub(crate) struct Candidate<'tcx> {
106106
#[derive(Debug, Clone)]
107107
pub(crate) enum CandidateKind<'tcx> {
108108
InherentImplCandidate { impl_def_id: DefId, receiver_steps: usize },
109-
ObjectCandidate(ty::PolyTraitRef<'tcx>),
109+
ObjectCandidate(ty::PolyTraitRef<'tcx>, DefId),
110110
TraitCandidate(ty::PolyTraitRef<'tcx>),
111111
WhereClauseCandidate(ty::PolyTraitRef<'tcx>),
112112
}
@@ -236,7 +236,7 @@ pub(crate) struct Pick<'tcx> {
236236
#[derive(Clone, Debug, PartialEq, Eq)]
237237
pub(crate) enum PickKind<'tcx> {
238238
InherentImplPick,
239-
ObjectPick,
239+
ObjectPick(DefId),
240240
TraitPick,
241241
WhereClausePick(
242242
// Trait
@@ -900,7 +900,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
900900
this.push_candidate(
901901
Candidate {
902902
item,
903-
kind: ObjectCandidate(new_trait_ref),
903+
kind: ObjectCandidate(new_trait_ref, principal.def_id()),
904904
import_ids: smallvec![],
905905
},
906906
true,
@@ -1753,7 +1753,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17531753
InherentImplCandidate { .. } => {
17541754
CandidateSource::Impl(candidate.item.container_id(self.tcx))
17551755
}
1756-
ObjectCandidate(_) | WhereClauseCandidate(_) => {
1756+
ObjectCandidate(_, _) | WhereClauseCandidate(_) => {
17571757
CandidateSource::Trait(candidate.item.container_id(self.tcx))
17581758
}
17591759
TraitCandidate(trait_ref) => self.probe(|_| {
@@ -1783,7 +1783,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17831783
fn candidate_source_from_pick(&self, pick: &Pick<'tcx>) -> CandidateSource {
17841784
match pick.kind {
17851785
InherentImplPick => CandidateSource::Impl(pick.item.container_id(self.tcx)),
1786-
ObjectPick | WhereClausePick(_) | TraitPick => {
1786+
ObjectPick(_) | WhereClausePick(_) | TraitPick => {
17871787
CandidateSource::Trait(pick.item.container_id(self.tcx))
17881788
}
17891789
}
@@ -1935,7 +1935,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
19351935

19361936
trait_predicate = Some(trait_ref.upcast(self.tcx));
19371937
}
1938-
ObjectCandidate(poly_trait_ref) | WhereClauseCandidate(poly_trait_ref) => {
1938+
ObjectCandidate(poly_trait_ref, _) | WhereClauseCandidate(poly_trait_ref) => {
19391939
let trait_ref = self.instantiate_binder_with_fresh_vars(
19401940
self.span,
19411941
infer::FnCall,
@@ -2412,7 +2412,7 @@ impl<'tcx> Candidate<'tcx> {
24122412
item: self.item,
24132413
kind: match self.kind {
24142414
InherentImplCandidate { .. } => InherentImplPick,
2415-
ObjectCandidate(_) => ObjectPick,
2415+
ObjectCandidate(_, principal_def_id) => ObjectPick(principal_def_id),
24162416
TraitCandidate(_) => TraitPick,
24172417
WhereClauseCandidate(trait_ref) => {
24182418
// Only trait derived from where-clauses should

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
}

0 commit comments

Comments
 (0)