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:
Manish Goregaokar 2020-07-05 16:07:23 -07:00 committed by GitHub
commit fed20132a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 306 additions and 192 deletions

View file

@ -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
}

View file

@ -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

View file

@ -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
};

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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));

View file

@ -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