diff options
| author | Michael Goulet <michael@errs.io> | 2024-09-23 23:49:12 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-23 23:49:12 -0400 |
| commit | ec1ccff8ce77d09594019c94788e95bb9487ae54 (patch) | |
| tree | d636a838d2f04d6cdb6e2ce7d4edb2f39d1f8fdf /compiler/rustc_const_eval/src/errors.rs | |
| parent | c0f1a69229a8d139cde0e8a65eb8dfb79dca0ae9 (diff) | |
| parent | 702a644b74872104e23e26a8d9f7a8e99a4a5956 (diff) | |
| download | rust-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.rs | 18 |
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 |
