Skip to content

Commit e0f4dc9

Browse files
authored
Rollup merge of #135042 - lukas-code:taint-dyn-incompat, r=compiler-errors
taint fcx on selection errors during unsizing With `feature(dyn_compatible_for_dispatch)` we only check for dyn-compatibility by checking the `T: Unsize<dyn Trait>` predicate during the unsizing coercions checks. If the predicate doesn't hold, we emit an error, but pretend the coercion succeeded to prevent further errors. To prevent const eval from attempting to actually perform this coercion, we need to taint the fcx after reporting the trait errors in the coercion check. fixes #135021 fixes #130521
2 parents e11d5f8 + 93bb639 commit e0f4dc9

File tree

5 files changed

+119
-14
lines changed

5 files changed

+119
-14
lines changed

Diff for: compiler/rustc_hir_typeck/src/coercion.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
666666

667667
// Dyn-compatibility violations or miscellaneous.
668668
Err(err) => {
669-
self.err_ctxt().report_selection_error(obligation.clone(), &obligation, &err);
669+
let guar = self.err_ctxt().report_selection_error(
670+
obligation.clone(),
671+
&obligation,
672+
&err,
673+
);
674+
self.fcx.set_tainted_by_errors(guar);
670675
// Treat this like an obligation and follow through
671676
// with the unsizing - the lack of a coercion should
672677
// be silent, as it causes a type mismatch later.

Diff for: tests/crashes/130521.rs

-13
This file was deleted.
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
error[E0038]: the trait `Qux` cannot be made into an object
2+
--> $DIR/taint-const-eval.rs:11:15
3+
|
4+
LL | static FOO: &(dyn Qux + Sync) = "desc";
5+
| ^^^^^^^^^^^^^^ `Qux` cannot be made into an object
6+
|
7+
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
8+
--> $DIR/taint-const-eval.rs:8:8
9+
|
10+
LL | trait Qux {
11+
| --- this trait cannot be made into an object...
12+
LL | fn bar();
13+
| ^^^ ...because associated function `bar` has no `self` parameter
14+
help: consider turning `bar` into a method by giving it a `&self` argument
15+
|
16+
LL | fn bar(&self);
17+
| +++++
18+
help: alternatively, consider constraining `bar` so it does not apply to trait objects
19+
|
20+
LL | fn bar() where Self: Sized;
21+
| +++++++++++++++++
22+
23+
error[E0038]: the trait `Qux` cannot be made into an object
24+
--> $DIR/taint-const-eval.rs:11:33
25+
|
26+
LL | static FOO: &(dyn Qux + Sync) = "desc";
27+
| ^^^^^^ `Qux` cannot be made into an object
28+
|
29+
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
30+
--> $DIR/taint-const-eval.rs:8:8
31+
|
32+
LL | trait Qux {
33+
| --- this trait cannot be made into an object...
34+
LL | fn bar();
35+
| ^^^ ...because associated function `bar` has no `self` parameter
36+
= note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
37+
help: consider turning `bar` into a method by giving it a `&self` argument
38+
|
39+
LL | fn bar(&self);
40+
| +++++
41+
help: alternatively, consider constraining `bar` so it does not apply to trait objects
42+
|
43+
LL | fn bar() where Self: Sized;
44+
| +++++++++++++++++
45+
46+
error[E0038]: the trait `Qux` cannot be made into an object
47+
--> $DIR/taint-const-eval.rs:11:15
48+
|
49+
LL | static FOO: &(dyn Qux + Sync) = "desc";
50+
| ^^^^^^^^^^^^^^ `Qux` cannot be made into an object
51+
|
52+
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
53+
--> $DIR/taint-const-eval.rs:8:8
54+
|
55+
LL | trait Qux {
56+
| --- this trait cannot be made into an object...
57+
LL | fn bar();
58+
| ^^^ ...because associated function `bar` has no `self` parameter
59+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
60+
help: consider turning `bar` into a method by giving it a `&self` argument
61+
|
62+
LL | fn bar(&self);
63+
| +++++
64+
help: alternatively, consider constraining `bar` so it does not apply to trait objects
65+
|
66+
LL | fn bar() where Self: Sized;
67+
| +++++++++++++++++
68+
69+
error: aborting due to 3 previous errors
70+
71+
For more information about this error, try `rustc --explain E0038`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0038]: the trait `Qux` cannot be made into an object
2+
--> $DIR/taint-const-eval.rs:11:33
3+
|
4+
LL | static FOO: &(dyn Qux + Sync) = "desc";
5+
| ^^^^^^ `Qux` cannot be made into an object
6+
|
7+
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
8+
--> $DIR/taint-const-eval.rs:8:8
9+
|
10+
LL | trait Qux {
11+
| --- this trait cannot be made into an object...
12+
LL | fn bar();
13+
| ^^^ ...because associated function `bar` has no `self` parameter
14+
= note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
15+
help: consider turning `bar` into a method by giving it a `&self` argument
16+
|
17+
LL | fn bar(&self);
18+
| +++++
19+
help: alternatively, consider constraining `bar` so it does not apply to trait objects
20+
|
21+
LL | fn bar() where Self: Sized;
22+
| +++++++++++++++++
23+
24+
error: aborting due to 1 previous error
25+
26+
For more information about this error, try `rustc --explain E0038`.

Diff for: tests/ui/dyn-compatibility/taint-const-eval.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Test that we do not attempt to create dyn-incompatible trait objects in const eval.
2+
3+
//@ revisions: curr dyn_compatible_for_dispatch
4+
5+
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
6+
7+
trait Qux {
8+
fn bar();
9+
}
10+
11+
static FOO: &(dyn Qux + Sync) = "desc";
12+
//~^ the trait `Qux` cannot be made into an object
13+
//[curr]~| the trait `Qux` cannot be made into an object
14+
//[curr]~| the trait `Qux` cannot be made into an object
15+
16+
fn main() {}

0 commit comments

Comments
 (0)