Skip to content

Commit b217e97

Browse files
committed
Auto merge of #124277 - matthiaskrgr:rollup-zdb93i4, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #123680 (Deny gen keyword in `edition_2024_compat` lints) - #124057 (Fix ICE when ADT tail has type error) - #124168 (Use `DefiningOpaqueTypes::Yes` in rustdoc, where the `InferCtxt` is guaranteed to have no opaque types it can define) - #124197 (Move duplicated code in functions in `tests/rustdoc-gui/notable-trait.goml`) - #124200 (Improve handling of expr->field errors) - #124220 (Miri: detect wrong vtables in wide pointers) - #124266 (remove an unused type from the reentrant lock tests) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 29381b6 + edc13b7 commit b217e97

12 files changed

+116
-30
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Validation stops this too early.
2+
//@compile-flags: -Zmiri-disable-validation
3+
14
trait T1 {
25
#[allow(dead_code)]
36
fn method1(self: Box<Self>);
@@ -13,5 +16,5 @@ impl T1 for i32 {
1316
fn main() {
1417
let r = Box::new(0) as Box<dyn T1>;
1518
let r2: Box<dyn T2> = unsafe { std::mem::transmute(r) };
16-
r2.method2(); //~ERROR: call on a pointer whose vtable does not match its type
19+
r2.method2(); //~ERROR: using vtable for trait `T1` but trait `T2` was expected
1720
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: Undefined Behavior: `dyn` call on a pointer whose vtable does not match its type
1+
error: Undefined Behavior: using vtable for trait `T1` but trait `T2` was expected
22
--> $DIR/dyn-call-trait-mismatch.rs:LL:CC
33
|
44
LL | r2.method2();
5-
| ^^^^^^^^^^^^ `dyn` call on a pointer whose vtable does not match its type
5+
| ^^^^^^^^^^^^ using vtable for trait `T1` but trait `T2` 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
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// This upcast is currently forbidden because it involves an invalid value.
2+
// However, if in the future we relax the validity requirements for raw pointer vtables,
3+
// we could consider allowing this again -- the cast itself isn't doing anything wrong,
4+
// only the transmutes needed to set up the testcase are wrong.
5+
6+
use std::fmt;
7+
8+
fn main() {
9+
// vtable_mismatch_nop_cast
10+
let ptr: &dyn fmt::Display = &0;
11+
let ptr: *const (dyn fmt::Debug + Send + Sync) = unsafe { std::mem::transmute(ptr) }; //~ERROR: wrong trait
12+
// Even though the vtable is for the wrong trait, this cast doesn't actually change the needed
13+
// vtable so it should still be allowed -- if we ever allow the line above.
14+
let _ptr2 = ptr as *const dyn fmt::Debug;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `std::fmt::Debug + std::marker::Send + std::marker::Sync`, but encountered `std::fmt::Display`
2+
--> $DIR/dyn-upcast-nop-wrong-trait.rs:LL:CC
3+
|
4+
LL | let ptr: *const (dyn fmt::Debug + Send + Sync) = unsafe { std::mem::transmute(ptr) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `std::fmt::Debug + std::marker::Send + std::marker::Sync`, but encountered `std::fmt::Display`
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/dyn-upcast-nop-wrong-trait.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Validation stops this too early.
2+
//@compile-flags: -Zmiri-disable-validation
3+
14
#![feature(trait_upcasting)]
25
#![allow(incomplete_features)]
36

@@ -57,7 +60,7 @@ impl Baz for i32 {
5760

5861
fn main() {
5962
let baz: &dyn Baz = &1;
60-
let baz_fake: &dyn Bar = unsafe { std::mem::transmute(baz) };
61-
let _err = baz_fake as &dyn Foo;
62-
//~^ERROR: upcast on a pointer whose vtable does not match its type
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
6366
}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: Undefined Behavior: upcast on a pointer whose vtable does not match its type
1+
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 &dyn Foo;
5-
| ^^^^^^^^ upcast on a pointer whose vtable does not match its type
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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::mem;
2+
3+
// Make sure we notice the mismatch also if the difference is "only" in the generic
4+
// parameters of the trait.
5+
6+
trait Trait<T> {}
7+
impl<T> Trait<T> for T {}
8+
9+
fn main() {
10+
let x: &dyn Trait<i32> = &0;
11+
let _y: *const dyn Trait<u32> = unsafe { mem::transmute(x) }; //~ERROR: wrong trait
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<u32>`, but encountered `Trait<i32>`
2+
--> $DIR/wrong-dyn-trait-generic.rs:LL:CC
3+
|
4+
LL | let _y: *const dyn Trait<u32> = unsafe { mem::transmute(x) };
5+
| ^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<u32>`, but encountered `Trait<i32>`
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/wrong-dyn-trait-generic.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use std::{fmt, mem};
2+
3+
fn main() {
4+
let x: &dyn Send = &0;
5+
let _y: *const dyn fmt::Debug = unsafe { mem::transmute(x) }; //~ERROR: wrong trait
6+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `std::fmt::Debug`, but encountered `<trivial>`
2+
--> $DIR/wrong-dyn-trait.rs:LL:CC
3+
|
4+
LL | let _y: *const dyn fmt::Debug = unsafe { mem::transmute(x) };
5+
| ^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `std::fmt::Debug`, but encountered `<trivial>`
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/wrong-dyn-trait.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+

tests/pass/cast-rfc0401-vtable-kinds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ impl Foo<u32> for u32 {
2525
impl Bar for () {}
2626

2727
unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32> + 'a)) -> u32 {
28-
let foo_e: *const dyn Foo<u16> = t as *const _;
28+
let foo_e: *const dyn Foo<u32> = t as *const _;
2929
let r_1 = foo_e as *mut dyn Foo<u32>;
3030

3131
(&*r_1).foo(0)

tests/pass/dyn-upcast.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
#![feature(trait_upcasting)]
22
#![allow(incomplete_features)]
33

4+
use std::fmt;
5+
46
fn main() {
57
basic();
68
diamond();
79
struct_();
810
replace_vptr();
9-
vtable_mismatch_nop_cast();
11+
vtable_nop_cast();
1012
}
1113

12-
fn vtable_mismatch_nop_cast() {
13-
let ptr: &dyn std::fmt::Display = &0;
14-
// Even though the vtable is for the wrong trait, this cast doesn't actually change the needed
15-
// vtable so it should still be allowed.
16-
let ptr: *const (dyn std::fmt::Debug + Send + Sync) = unsafe { std::mem::transmute(ptr) };
17-
let _ptr2 = ptr as *const dyn std::fmt::Debug;
14+
fn vtable_nop_cast() {
15+
let ptr: &dyn fmt::Debug = &0;
16+
// We transmute things around, but the principal trait does not change, so this is allowed.
17+
let ptr: *const (dyn fmt::Debug + Send + Sync) = unsafe { std::mem::transmute(ptr) };
18+
// This cast is a NOP and should be allowed.
19+
let _ptr2 = ptr as *const dyn fmt::Debug;
1820
}
1921

2022
fn basic() {
21-
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
23+
trait Foo: PartialEq<i32> + fmt::Debug + Send + Sync {
2224
fn a(&self) -> i32 {
2325
10
2426
}
@@ -67,7 +69,7 @@ fn basic() {
6769
}
6870

6971
let baz: &dyn Baz = &1;
70-
let _: &dyn std::fmt::Debug = baz;
72+
let _: &dyn fmt::Debug = baz;
7173
assert_eq!(*baz, 1);
7274
assert_eq!(baz.a(), 100);
7375
assert_eq!(baz.b(), 200);
@@ -77,7 +79,7 @@ fn basic() {
7779
assert_eq!(baz.w(), 21);
7880

7981
let bar: &dyn Bar = baz;
80-
let _: &dyn std::fmt::Debug = bar;
82+
let _: &dyn fmt::Debug = bar;
8183
assert_eq!(*bar, 1);
8284
assert_eq!(bar.a(), 100);
8385
assert_eq!(bar.b(), 200);
@@ -86,22 +88,22 @@ fn basic() {
8688
assert_eq!(bar.w(), 21);
8789

8890
let foo: &dyn Foo = baz;
89-
let _: &dyn std::fmt::Debug = foo;
91+
let _: &dyn fmt::Debug = foo;
9092
assert_eq!(*foo, 1);
9193
assert_eq!(foo.a(), 100);
9294
assert_eq!(foo.z(), 11);
9395
assert_eq!(foo.y(), 12);
9496

9597
let foo: &dyn Foo = bar;
96-
let _: &dyn std::fmt::Debug = foo;
98+
let _: &dyn fmt::Debug = foo;
9799
assert_eq!(*foo, 1);
98100
assert_eq!(foo.a(), 100);
99101
assert_eq!(foo.z(), 11);
100102
assert_eq!(foo.y(), 12);
101103
}
102104

103105
fn diamond() {
104-
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
106+
trait Foo: PartialEq<i32> + fmt::Debug + Send + Sync {
105107
fn a(&self) -> i32 {
106108
10
107109
}
@@ -166,7 +168,7 @@ fn diamond() {
166168
}
167169

168170
let baz: &dyn Baz = &1;
169-
let _: &dyn std::fmt::Debug = baz;
171+
let _: &dyn fmt::Debug = baz;
170172
assert_eq!(*baz, 1);
171173
assert_eq!(baz.a(), 100);
172174
assert_eq!(baz.b(), 200);
@@ -178,7 +180,7 @@ fn diamond() {
178180
assert_eq!(baz.v(), 31);
179181

180182
let bar1: &dyn Bar1 = baz;
181-
let _: &dyn std::fmt::Debug = bar1;
183+
let _: &dyn fmt::Debug = bar1;
182184
assert_eq!(*bar1, 1);
183185
assert_eq!(bar1.a(), 100);
184186
assert_eq!(bar1.b(), 200);
@@ -187,7 +189,7 @@ fn diamond() {
187189
assert_eq!(bar1.w(), 21);
188190

189191
let bar2: &dyn Bar2 = baz;
190-
let _: &dyn std::fmt::Debug = bar2;
192+
let _: &dyn fmt::Debug = bar2;
191193
assert_eq!(*bar2, 1);
192194
assert_eq!(bar2.a(), 100);
193195
assert_eq!(bar2.c(), 300);
@@ -196,17 +198,17 @@ fn diamond() {
196198
assert_eq!(bar2.v(), 31);
197199

198200
let foo: &dyn Foo = baz;
199-
let _: &dyn std::fmt::Debug = foo;
201+
let _: &dyn fmt::Debug = foo;
200202
assert_eq!(*foo, 1);
201203
assert_eq!(foo.a(), 100);
202204

203205
let foo: &dyn Foo = bar1;
204-
let _: &dyn std::fmt::Debug = foo;
206+
let _: &dyn fmt::Debug = foo;
205207
assert_eq!(*foo, 1);
206208
assert_eq!(foo.a(), 100);
207209

208210
let foo: &dyn Foo = bar2;
209-
let _: &dyn std::fmt::Debug = foo;
211+
let _: &dyn fmt::Debug = foo;
210212
assert_eq!(*foo, 1);
211213
assert_eq!(foo.a(), 100);
212214
}
@@ -215,7 +217,7 @@ fn struct_() {
215217
use std::rc::Rc;
216218
use std::sync::Arc;
217219

218-
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
220+
trait Foo: PartialEq<i32> + fmt::Debug + Send + Sync {
219221
fn a(&self) -> i32 {
220222
10
221223
}

0 commit comments

Comments
 (0)