Rollup merge of #73834 - oli-obk:safe_intrinsics, r=ecstatic-morse
Some refactoring around intrinsic type checking So... This PR went a bit overboard. I wanted to make the `rustc_peek` intrinsic safe (cc @ecstatic-morse ), and remembered a long-standing itch of mine. So I made that huge `&str` match for the intrinsic name a match on `Symbol`s (so basically `u32`s). This is unlikely to have a positive perf effect, even if it likely has better codegen (intrinsics are used rarely, mostly once in their wrapper), so it's mostly a consistency thing since other places actually match on the symbol name of the intrinsics.
This commit is contained in:
commit
fed20132a6
15 changed files with 306 additions and 192 deletions
|
|
@ -11,13 +11,13 @@ struct S(i32);
|
|||
fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
||||
let ret;
|
||||
// `ret` starts off uninitialized
|
||||
unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&ret); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// All function formal parameters start off initialized.
|
||||
|
||||
unsafe { rustc_peek(&x) };
|
||||
unsafe { rustc_peek(&y) };
|
||||
unsafe { rustc_peek(&z) };
|
||||
rustc_peek(&x);
|
||||
rustc_peek(&y);
|
||||
rustc_peek(&z);
|
||||
|
||||
ret = if test {
|
||||
::std::mem::replace(x, y)
|
||||
|
|
@ -27,21 +27,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
|||
};
|
||||
|
||||
// `z` may be uninitialized here.
|
||||
unsafe { rustc_peek(&z); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&z); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// `y` is definitely uninitialized here.
|
||||
unsafe { rustc_peek(&y); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&y); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// `x` is still (definitely) initialized (replace above is a reborrow).
|
||||
unsafe { rustc_peek(&x); }
|
||||
rustc_peek(&x);
|
||||
|
||||
::std::mem::drop(x);
|
||||
|
||||
// `x` is *definitely* uninitialized here
|
||||
unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&x); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// `ret` is now definitely initialized (via `if` above).
|
||||
unsafe { rustc_peek(&ret); }
|
||||
rustc_peek(&ret);
|
||||
|
||||
ret
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
error: rustc_peek: bit not set
|
||||
--> $DIR/def-inits-1.rs:14:14
|
||||
--> $DIR/def-inits-1.rs:14:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&ret); }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&ret);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/def-inits-1.rs:30:14
|
||||
--> $DIR/def-inits-1.rs:30:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&z); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&z);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/def-inits-1.rs:33:14
|
||||
--> $DIR/def-inits-1.rs:33:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&y); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&y);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/def-inits-1.rs:41:14
|
||||
--> $DIR/def-inits-1.rs:41:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&x); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&x);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: stop_after_dataflow ended compilation
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const BOO: i32 = {
|
|||
|
||||
*rmut_cell = 42; // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!!
|
||||
let val = *rmut_cell;
|
||||
unsafe { rustc_peek(x) }; //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(x); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
val
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: rustc_peek: bit not set
|
||||
--> $DIR/indirect-mutation-offset.rs:41:14
|
||||
--> $DIR/indirect-mutation-offset.rs:41:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(x) };
|
||||
| ^^^^^^^^^^^^^
|
||||
LL | rustc_peek(x);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: stop_after_dataflow ended compilation
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ struct S(i32);
|
|||
fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
||||
let ret;
|
||||
// `ret` starts off uninitialized, so we get an error report here.
|
||||
unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&ret); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// All function formal parameters start off initialized.
|
||||
|
||||
unsafe { rustc_peek(&x) };
|
||||
unsafe { rustc_peek(&y) };
|
||||
unsafe { rustc_peek(&z) };
|
||||
rustc_peek(&x);
|
||||
rustc_peek(&y);
|
||||
rustc_peek(&z);
|
||||
|
||||
ret = if test {
|
||||
::std::mem::replace(x, y)
|
||||
|
|
@ -28,21 +28,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
|||
|
||||
|
||||
// `z` may be initialized here.
|
||||
unsafe { rustc_peek(&z); }
|
||||
rustc_peek(&z);
|
||||
|
||||
// `y` is definitely uninitialized here.
|
||||
unsafe { rustc_peek(&y); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&y); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// `x` is still (definitely) initialized (replace above is a reborrow).
|
||||
unsafe { rustc_peek(&x); }
|
||||
rustc_peek(&x);
|
||||
|
||||
::std::mem::drop(x);
|
||||
|
||||
// `x` is *definitely* uninitialized here
|
||||
unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&x); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
// `ret` is now definitely initialized (via `if` above).
|
||||
unsafe { rustc_peek(&ret); }
|
||||
rustc_peek(&ret);
|
||||
|
||||
ret
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
error: rustc_peek: bit not set
|
||||
--> $DIR/inits-1.rs:14:14
|
||||
--> $DIR/inits-1.rs:14:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&ret); }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&ret);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/inits-1.rs:34:14
|
||||
--> $DIR/inits-1.rs:34:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&y); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&y);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/inits-1.rs:42:14
|
||||
--> $DIR/inits-1.rs:42:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&x); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&x);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: stop_after_dataflow ended compilation
|
||||
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ fn foo() -> i32 {
|
|||
x = 0;
|
||||
|
||||
// `x` is live here since it is used in the next statement...
|
||||
unsafe { rustc_peek(x); }
|
||||
rustc_peek(x);
|
||||
|
||||
p = &x;
|
||||
|
||||
// ... but not here, even while it can be accessed through `p`.
|
||||
unsafe { rustc_peek(x); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(x); //~ ERROR rustc_peek: bit not set
|
||||
let tmp = unsafe { *p };
|
||||
|
||||
x = tmp + 1;
|
||||
|
||||
unsafe { rustc_peek(x); }
|
||||
rustc_peek(x);
|
||||
|
||||
x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: rustc_peek: bit not set
|
||||
--> $DIR/liveness-ptr.rs:18:14
|
||||
--> $DIR/liveness-ptr.rs:18:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(x); }
|
||||
| ^^^^^^^^^^^^^
|
||||
LL | rustc_peek(x);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: stop_after_dataflow ended compilation
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ struct S(i32);
|
|||
fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
||||
let ret;
|
||||
// `ret` starts off uninitialized
|
||||
unsafe { rustc_peek(&ret); }
|
||||
rustc_peek(&ret);
|
||||
|
||||
// All function formal parameters start off initialized.
|
||||
|
||||
unsafe { rustc_peek(&x) }; //~ ERROR rustc_peek: bit not set
|
||||
unsafe { rustc_peek(&y) }; //~ ERROR rustc_peek: bit not set
|
||||
unsafe { rustc_peek(&z) }; //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&x); //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&y); //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&z); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
ret = if test {
|
||||
::std::mem::replace(x, y)
|
||||
|
|
@ -27,21 +27,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
|||
};
|
||||
|
||||
// `z` may be uninitialized here.
|
||||
unsafe { rustc_peek(&z); }
|
||||
rustc_peek(&z);
|
||||
|
||||
// `y` is definitely uninitialized here.
|
||||
unsafe { rustc_peek(&y); }
|
||||
rustc_peek(&y);
|
||||
|
||||
// `x` is still (definitely) initialized (replace above is a reborrow).
|
||||
unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&x); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
::std::mem::drop(x);
|
||||
|
||||
// `x` is *definitely* uninitialized here
|
||||
unsafe { rustc_peek(&x); }
|
||||
rustc_peek(&x);
|
||||
|
||||
// `ret` is now definitely initialized (via `if` above).
|
||||
unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&ret); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
ret
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,32 @@
|
|||
error: rustc_peek: bit not set
|
||||
--> $DIR/uninits-1.rs:18:14
|
||||
--> $DIR/uninits-1.rs:18:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&x) };
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&x);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/uninits-1.rs:19:14
|
||||
--> $DIR/uninits-1.rs:19:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&y) };
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&y);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/uninits-1.rs:20:14
|
||||
--> $DIR/uninits-1.rs:20:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&z) };
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&z);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/uninits-1.rs:36:14
|
||||
--> $DIR/uninits-1.rs:36:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&x); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&x);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: rustc_peek: bit not set
|
||||
--> $DIR/uninits-1.rs:44:14
|
||||
--> $DIR/uninits-1.rs:44:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&ret); }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&ret);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: stop_after_dataflow ended compilation
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ struct S(i32);
|
|||
fn foo(x: &mut S) {
|
||||
// `x` is initialized here, so maybe-uninit bit is 0.
|
||||
|
||||
unsafe { rustc_peek(&x) }; //~ ERROR rustc_peek: bit not set
|
||||
rustc_peek(&x); //~ ERROR rustc_peek: bit not set
|
||||
|
||||
::std::mem::drop(x);
|
||||
|
||||
// `x` definitely uninitialized here, so maybe-uninit bit is 1.
|
||||
unsafe { rustc_peek(&x) };
|
||||
rustc_peek(&x);
|
||||
}
|
||||
fn main() {
|
||||
foo(&mut S(13));
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: rustc_peek: bit not set
|
||||
--> $DIR/uninits-2.rs:14:14
|
||||
--> $DIR/uninits-2.rs:14:5
|
||||
|
|
||||
LL | unsafe { rustc_peek(&x) };
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | rustc_peek(&x);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: stop_after_dataflow ended compilation
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue