about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2025-01-02 18:31:40 +0100
committerLukas Markeffsky <@>2025-01-02 19:16:00 +0100
commit93bb639ad6b02a68e1681b96351badf8b6a33fa3 (patch)
treea67fcd78691918f643ff1f237b309a9675cad96d
parentbf6f8a4d328f7f3b0f6ea8205ad28591cc11aafd (diff)
downloadrust-93bb639ad6b02a68e1681b96351badf8b6a33fa3.tar.gz
rust-93bb639ad6b02a68e1681b96351badf8b6a33fa3.zip
taint fcx on selection errors during unsizing
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs7
-rw-r--r--tests/crashes/130521.rs13
-rw-r--r--tests/ui/dyn-compatibility/taint-const-eval.curr.stderr71
-rw-r--r--tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr26
-rw-r--r--tests/ui/dyn-compatibility/taint-const-eval.rs16
5 files changed, 119 insertions, 14 deletions
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 60e3c0166b9..bd26be11279 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -666,7 +666,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
                 // Dyn-compatibility violations or miscellaneous.
                 Err(err) => {
-                    self.err_ctxt().report_selection_error(obligation.clone(), &obligation, &err);
+                    let guar = self.err_ctxt().report_selection_error(
+                        obligation.clone(),
+                        &obligation,
+                        &err,
+                    );
+                    self.fcx.set_tainted_by_errors(guar);
                     // Treat this like an obligation and follow through
                     // with the unsizing - the lack of a coercion should
                     // be silent, as it causes a type mismatch later.
diff --git a/tests/crashes/130521.rs b/tests/crashes/130521.rs
deleted file mode 100644
index ebcfacf9623..00000000000
--- a/tests/crashes/130521.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #130521
-
-#![feature(dyn_compatible_for_dispatch)]
-struct Vtable(dyn Cap<'static>);
-
-trait Cap<'a> {}
-
-union Transmute {
-    t: u128,
-    u: &'static Vtable,
-}
-
-const G: &Copy = unsafe { Transmute { t: 1 }.u };
diff --git a/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr b/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr
new file mode 100644
index 00000000000..ef0abc16342
--- /dev/null
+++ b/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr
@@ -0,0 +1,71 @@
+error[E0038]: the trait `Qux` cannot be made into an object
+  --> $DIR/taint-const-eval.rs:11:15
+   |
+LL | static FOO: &(dyn Qux + Sync) = "desc";
+   |               ^^^^^^^^^^^^^^ `Qux` cannot be made into an object
+   |
+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>
+  --> $DIR/taint-const-eval.rs:8:8
+   |
+LL | trait Qux {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar();
+   |        ^^^ ...because associated function `bar` has no `self` parameter
+help: consider turning `bar` into a method by giving it a `&self` argument
+   |
+LL |     fn bar(&self);
+   |            +++++
+help: alternatively, consider constraining `bar` so it does not apply to trait objects
+   |
+LL |     fn bar() where Self: Sized;
+   |              +++++++++++++++++
+
+error[E0038]: the trait `Qux` cannot be made into an object
+  --> $DIR/taint-const-eval.rs:11:33
+   |
+LL | static FOO: &(dyn Qux + Sync) = "desc";
+   |                                 ^^^^^^ `Qux` cannot be made into an object
+   |
+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>
+  --> $DIR/taint-const-eval.rs:8:8
+   |
+LL | trait Qux {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar();
+   |        ^^^ ...because associated function `bar` has no `self` parameter
+   = note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
+help: consider turning `bar` into a method by giving it a `&self` argument
+   |
+LL |     fn bar(&self);
+   |            +++++
+help: alternatively, consider constraining `bar` so it does not apply to trait objects
+   |
+LL |     fn bar() where Self: Sized;
+   |              +++++++++++++++++
+
+error[E0038]: the trait `Qux` cannot be made into an object
+  --> $DIR/taint-const-eval.rs:11:15
+   |
+LL | static FOO: &(dyn Qux + Sync) = "desc";
+   |               ^^^^^^^^^^^^^^ `Qux` cannot be made into an object
+   |
+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>
+  --> $DIR/taint-const-eval.rs:8:8
+   |
+LL | trait Qux {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar();
+   |        ^^^ ...because associated function `bar` has no `self` parameter
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider turning `bar` into a method by giving it a `&self` argument
+   |
+LL |     fn bar(&self);
+   |            +++++
+help: alternatively, consider constraining `bar` so it does not apply to trait objects
+   |
+LL |     fn bar() where Self: Sized;
+   |              +++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr
new file mode 100644
index 00000000000..14940365d23
--- /dev/null
+++ b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr
@@ -0,0 +1,26 @@
+error[E0038]: the trait `Qux` cannot be made into an object
+  --> $DIR/taint-const-eval.rs:11:33
+   |
+LL | static FOO: &(dyn Qux + Sync) = "desc";
+   |                                 ^^^^^^ `Qux` cannot be made into an object
+   |
+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>
+  --> $DIR/taint-const-eval.rs:8:8
+   |
+LL | trait Qux {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar();
+   |        ^^^ ...because associated function `bar` has no `self` parameter
+   = note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
+help: consider turning `bar` into a method by giving it a `&self` argument
+   |
+LL |     fn bar(&self);
+   |            +++++
+help: alternatively, consider constraining `bar` so it does not apply to trait objects
+   |
+LL |     fn bar() where Self: Sized;
+   |              +++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/dyn-compatibility/taint-const-eval.rs b/tests/ui/dyn-compatibility/taint-const-eval.rs
new file mode 100644
index 00000000000..9825ec0ca1c
--- /dev/null
+++ b/tests/ui/dyn-compatibility/taint-const-eval.rs
@@ -0,0 +1,16 @@
+// Test that we do not attempt to create dyn-incompatible trait objects in const eval.
+
+//@ revisions: curr dyn_compatible_for_dispatch
+
+#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
+
+trait Qux {
+    fn bar();
+}
+
+static FOO: &(dyn Qux + Sync) = "desc";
+//~^ the trait `Qux` cannot be made into an object
+//[curr]~| the trait `Qux` cannot be made into an object
+//[curr]~| the trait `Qux` cannot be made into an object
+
+fn main() {}