Skip to content

Commit 3e29c99

Browse files
authored
Rollup merge of #127856 - RalfJung:interpret-cast-sanity, r=oli-obk
interpret: add sanity check in dyn upcast to double-check what codegen does For dyn receiver calls, we already have two codepaths: look up the function to call by indexing into the vtable, or alternatively resolve the DefId given the dynamic type of the receiver. With debug assertions enabled, the interpreter does both and compares the results. (Without debug assertions we always use the vtable as it is simpler.) This PR does the same for dyn trait upcasts. However, for casts *not* using the vtable is the easier thing to do, so now the vtable path is the debug-assertion-only path. In particular, there are cases where the vtable does not contain a pointer for upcasts but instead reuses the old pointer: when the supertrait vtable is a prefix of the larger vtable. We don't want to expose this optimization and detect UB if people do a transmute assuming this optimization, so we cannot in general use the vtable indexing path. r? ``@oli-obk``
2 parents 1225de6 + 417eb05 commit 3e29c99

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

tests/fail/dyn-upcast-trait-mismatch.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ impl Baz for i32 {
5959
}
6060

6161
fn main() {
62-
let baz: &dyn Baz = &1;
63-
let baz_fake: *const dyn Bar = unsafe { std::mem::transmute(baz) };
64-
let _err = baz_fake as *const dyn Foo;
65-
//~^ERROR: using vtable for trait `Baz` but trait `Bar` was expected
62+
unsafe {
63+
let baz: &dyn Baz = &1;
64+
let baz_fake: *const dyn Bar = std::mem::transmute(baz);
65+
let _err = baz_fake as *const dyn Foo;
66+
//~^ERROR: using vtable for trait `Baz` but trait `Bar` was expected
67+
}
6668
}

tests/fail/dyn-upcast-trait-mismatch.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: Undefined Behavior: using vtable for trait `Baz` but trait `Bar` was expected
22
--> $DIR/dyn-upcast-trait-mismatch.rs:LL:CC
33
|
4-
LL | let _err = baz_fake as *const dyn Foo;
5-
| ^^^^^^^^ using vtable for trait `Baz` but trait `Bar` was expected
4+
LL | let _err = baz_fake as *const dyn Foo;
5+
| ^^^^^^^^ using vtable for trait `Baz` but trait `Bar` was expected
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

0 commit comments

Comments
 (0)