about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/errors.rs
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-23 23:49:12 -0400
committerGitHub <noreply@github.com>2024-09-23 23:49:12 -0400
commitec1ccff8ce77d09594019c94788e95bb9487ae54 (patch)
treed636a838d2f04d6cdb6e2ce7d4edb2f39d1f8fdf /compiler/rustc_const_eval/src/errors.rs
parentc0f1a69229a8d139cde0e8a65eb8dfb79dca0ae9 (diff)
parent702a644b74872104e23e26a8d9f7a8e99a4a5956 (diff)
downloadrust-ec1ccff8ce77d09594019c94788e95bb9487ae54.tar.gz
rust-ec1ccff8ce77d09594019c94788e95bb9487ae54.zip
Rollup merge of #130727 - compiler-errors:objects, r=RalfJung
Check vtable projections for validity in miri

Currently, miri does not catch when we transmute `dyn Trait<Assoc = A>` to `dyn Trait<Assoc = B>`. This PR implements such a check, and fixes https://github.com/rust-lang/miri/issues/3905.

To do this, we modify `GlobalAlloc::VTable` to contain the *whole* list of `PolyExistentialPredicate`, and then modify `check_vtable_for_type` to validate the `PolyExistentialProjection`s of the vtable, along with the principal trait that was already being validated.

cc ``@RalfJung``
r? ``@lcnr`` or types

I also tweaked the diagnostics a bit.

---

**Open question:** We don't validate the auto traits. You can transmute `dyn Foo` into `dyn Foo + Send`. Should we check that? We currently have a test that *exercises* this as not being UB:

https://github.com/rust-lang/rust/blob/6c6d210089e4589afee37271862b9f88ba1d7755/src/tools/miri/tests/pass/dyn-upcast.rs#L14-L20

I'm not actually sure if we ever decided that's actually UB or not 🤔

We could perhaps still check that the underlying type of the object (i.e. the concrete type that was unsized) implements the auto traits, to catch UB like:

```rust
fn main() {
    let x: &dyn Trait = &std::ptr::null_mut::<()>();
    let _: &(dyn Trait + Send) = std::mem::transmute(x);
    //~^ this vtable is not allocated for a type that is `Send`!
}
```
Diffstat (limited to 'compiler/rustc_const_eval/src/errors.rs')
-rw-r--r--compiler/rustc_const_eval/src/errors.rs18
1 files changed, 6 insertions, 12 deletions
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index c38d7f3d03c..c60bacb8506 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -522,12 +522,9 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
             UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => {
                 diag.arg("pointer", ptr);
             }
-            InvalidVTableTrait { expected_trait, vtable_trait } => {
-                diag.arg("expected_trait", expected_trait.to_string());
-                diag.arg(
-                    "vtable_trait",
-                    vtable_trait.map(|t| t.to_string()).unwrap_or_else(|| format!("<trivial>")),
-                );
+            InvalidVTableTrait { expected_dyn_type, vtable_dyn_type } => {
+                diag.arg("expected_dyn_type", expected_dyn_type.to_string());
+                diag.arg("vtable_dyn_type", vtable_dyn_type.to_string());
             }
             PointerUseAfterFree(alloc_id, msg) => {
                 diag.arg("alloc_id", alloc_id)
@@ -777,12 +774,9 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
             DanglingPtrNoProvenance { pointer, .. } => {
                 err.arg("pointer", pointer);
             }
-            InvalidMetaWrongTrait { expected_trait: ref_trait, vtable_trait } => {
-                err.arg("ref_trait", ref_trait.to_string());
-                err.arg(
-                    "vtable_trait",
-                    vtable_trait.map(|t| t.to_string()).unwrap_or_else(|| format!("<trivial>")),
-                );
+            InvalidMetaWrongTrait { vtable_dyn_type, expected_dyn_type } => {
+                err.arg("vtable_dyn_type", vtable_dyn_type.to_string());
+                err.arg("expected_dyn_type", expected_dyn_type.to_string());
             }
             NullPtr { .. }
             | ConstRefToMutable