diff options
Diffstat (limited to 'src/test/ui/unsafe')
97 files changed, 2132 insertions, 0 deletions
diff --git a/src/test/ui/unsafe/access_union_field.mir.stderr b/src/test/ui/unsafe/access_union_field.mir.stderr new file mode 100644 index 000000000..98bc40777 --- /dev/null +++ b/src/test/ui/unsafe/access_union_field.mir.stderr @@ -0,0 +1,19 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/access_union_field.rs:13:13 + | +LL | let a = foo.bar; + | ^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/access_union_field.rs:14:13 + | +LL | let b = foo.baz; + | ^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/access_union_field.rs b/src/test/ui/unsafe/access_union_field.rs new file mode 100644 index 000000000..5c4e695df --- /dev/null +++ b/src/test/ui/unsafe/access_union_field.rs @@ -0,0 +1,15 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![allow(unused_variables)] + +union Foo { + bar: i8, + baz: u8, +} + +fn main() { + let foo = Foo { bar: 5 }; + let a = foo.bar; //~ ERROR access to union field is unsafe and requires unsafe function or block + let b = foo.baz; //~ ERROR access to union field is unsafe and requires unsafe function or block +} diff --git a/src/test/ui/unsafe/access_union_field.thir.stderr b/src/test/ui/unsafe/access_union_field.thir.stderr new file mode 100644 index 000000000..98bc40777 --- /dev/null +++ b/src/test/ui/unsafe/access_union_field.thir.stderr @@ -0,0 +1,19 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/access_union_field.rs:13:13 + | +LL | let a = foo.bar; + | ^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/access_union_field.rs:14:13 + | +LL | let b = foo.baz; + | ^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/inline_asm.mir.stderr b/src/test/ui/unsafe/inline_asm.mir.stderr new file mode 100644 index 000000000..633f1edb2 --- /dev/null +++ b/src/test/ui/unsafe/inline_asm.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: use of inline assembly is unsafe and requires unsafe function or block + --> $DIR/inline_asm.rs:8:5 + | +LL | asm!("nop"); + | ^^^^^^^^^^^ use of inline assembly + | + = note: inline assembly is entirely unchecked and can cause undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/inline_asm.rs b/src/test/ui/unsafe/inline_asm.rs new file mode 100644 index 000000000..12c7efe4f --- /dev/null +++ b/src/test/ui/unsafe/inline_asm.rs @@ -0,0 +1,9 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck +// needs-asm-support + +use std::arch::asm; + +fn main() { + asm!("nop"); //~ ERROR use of inline assembly is unsafe and requires unsafe function or block +} diff --git a/src/test/ui/unsafe/inline_asm.thir.stderr b/src/test/ui/unsafe/inline_asm.thir.stderr new file mode 100644 index 000000000..633f1edb2 --- /dev/null +++ b/src/test/ui/unsafe/inline_asm.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: use of inline assembly is unsafe and requires unsafe function or block + --> $DIR/inline_asm.rs:8:5 + | +LL | asm!("nop"); + | ^^^^^^^^^^^ use of inline assembly + | + = note: inline assembly is entirely unchecked and can cause undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-3080.mir.stderr b/src/test/ui/unsafe/issue-3080.mir.stderr new file mode 100644 index 000000000..f395c30b8 --- /dev/null +++ b/src/test/ui/unsafe/issue-3080.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/issue-3080.rs:10:5 + | +LL | X(()).with(); + | ^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-3080.rs b/src/test/ui/unsafe/issue-3080.rs new file mode 100644 index 000000000..2b5269dda --- /dev/null +++ b/src/test/ui/unsafe/issue-3080.rs @@ -0,0 +1,11 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +struct X(()); +impl X { + pub unsafe fn with(&self) { } +} + +fn main() { + X(()).with(); //~ ERROR requires unsafe function or block +} diff --git a/src/test/ui/unsafe/issue-3080.thir.stderr b/src/test/ui/unsafe/issue-3080.thir.stderr new file mode 100644 index 000000000..4d8acac61 --- /dev/null +++ b/src/test/ui/unsafe/issue-3080.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `X::with` is unsafe and requires unsafe function or block + --> $DIR/issue-3080.rs:10:5 + | +LL | X(()).with(); + | ^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr new file mode 100644 index 000000000..e79609607 --- /dev/null +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr @@ -0,0 +1,27 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:7:5 + | +LL | *(1 as *mut u32) = 42; + | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:17:5 + | +LL | *a = 1; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:29:5 + | +LL | *b = 1; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs new file mode 100644 index 000000000..3e3da667c --- /dev/null +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs @@ -0,0 +1,31 @@ +// Verify that unreachable code undergoes unsafety checks. +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +fn main() { + return; + *(1 as *mut u32) = 42; + //~^ ERROR dereference of raw pointer is unsafe +} + +fn panic() -> ! { + panic!(); +} + +fn f(a: *mut u32) { + panic(); + *a = 1; + //~^ ERROR dereference of raw pointer is unsafe +} + +enum Void {} + +fn uninhabited() -> Void { + panic!(); +} + +fn g(b: *mut u32) { + uninhabited(); + *b = 1; + //~^ ERROR dereference of raw pointer is unsafe +} diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr new file mode 100644 index 000000000..e81adad45 --- /dev/null +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr @@ -0,0 +1,27 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:7:5 + | +LL | *(1 as *mut u32) = 42; + | ^^^^^^^^^^^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:17:5 + | +LL | *a = 1; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:29:5 + | +LL | *b = 1; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr new file mode 100644 index 000000000..9e9cbcf33 --- /dev/null +++ b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr @@ -0,0 +1,35 @@ +error: unnecessary `unsafe` block + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:10:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +LL | let f = |v: &mut Vec<_>| { +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:4:8 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | |w: &mut Vec<u32>| { unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:16:34 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | |x: &mut Vec<u32>| { unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs new file mode 100644 index 000000000..ac1cfd62a --- /dev/null +++ b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs @@ -0,0 +1,28 @@ +// revisions: mir thir +// [thir]compile-flags: -Zthir-unsafeck + +#[deny(unused_unsafe)] +fn main() { + let mut v = Vec::<i32>::with_capacity(24); + + unsafe { + let f = |v: &mut Vec<_>| { + unsafe { //~ ERROR unnecessary `unsafe` + v.set_len(24); + |w: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` + w.set_len(32); + } }; + } + |x: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` + x.set_len(40); + } }; + }; + + v.set_len(0); + f(&mut v); + } + + |y: &mut Vec<u32>| { unsafe { + y.set_len(48); + } }; +} diff --git a/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr new file mode 100644 index 000000000..9e9cbcf33 --- /dev/null +++ b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr @@ -0,0 +1,35 @@ +error: unnecessary `unsafe` block + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:10:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +LL | let f = |v: &mut Vec<_>| { +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:4:8 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | |w: &mut Vec<u32>| { unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:16:34 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | |x: &mut Vec<u32>| { unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/unsafe/issue-47412.mir.stderr b/src/test/ui/unsafe/issue-47412.mir.stderr new file mode 100644 index 000000000..305f482e8 --- /dev/null +++ b/src/test/ui/unsafe/issue-47412.mir.stderr @@ -0,0 +1,19 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-47412.rs:14:11 + | +LL | match u.void {} + | ^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-47412.rs:20:11 + | +LL | match *ptr {} + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-47412.rs b/src/test/ui/unsafe/issue-47412.rs new file mode 100644 index 000000000..df6d6e422 --- /dev/null +++ b/src/test/ui/unsafe/issue-47412.rs @@ -0,0 +1,24 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#[derive(Copy, Clone)] +enum Void {} + +// Tests that we detect unsafe places (specifically, union fields and +// raw pointer dereferences), even when they're matched on while having +// an uninhabited type (equivalent to `std::intrinsics::unreachable()`). + +fn union_field() { + union Union { unit: (), void: Void } + let u = Union { unit: () }; + match u.void {} + //~^ ERROR access to union field is unsafe +} + +fn raw_ptr_deref() { + let ptr = std::ptr::null::<Void>(); + match *ptr {} + //~^ ERROR dereference of raw pointer is unsafe +} + +fn main() {} diff --git a/src/test/ui/unsafe/issue-47412.thir.stderr b/src/test/ui/unsafe/issue-47412.thir.stderr new file mode 100644 index 000000000..305f482e8 --- /dev/null +++ b/src/test/ui/unsafe/issue-47412.thir.stderr @@ -0,0 +1,19 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-47412.rs:14:11 + | +LL | match u.void {} + | ^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-47412.rs:20:11 + | +LL | match *ptr {} + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs new file mode 100644 index 000000000..72f7b6747 --- /dev/null +++ b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs @@ -0,0 +1,27 @@ +// check-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +// This is issue #85435. But the real story is reflected in issue #85561, where +// a bug in the implementation of feature(capture_disjoint_fields) () was +// exposed to non-feature-gated code by a diagnostic changing PR that removed +// the gating in one case. + +// This test is double-checking that the case of interest continues to work as +// expected in the *absence* of that feature gate. At the time of this writing, +// enabling the feature gate will cause this test to fail. We obviously cannot +// stabilize that feature until it can correctly handle this test. + +fn main() { + let val: u8 = 5; + let u8_ptr: *const u8 = &val; + let _closure = || { + unsafe { + let tmp = *u8_ptr; + tmp + + // Just dereferencing and returning directly compiles fine: + // *u8_ptr + } + }; +} diff --git a/src/test/ui/unsafe/issue-87414-query-cycle.rs b/src/test/ui/unsafe/issue-87414-query-cycle.rs new file mode 100644 index 000000000..99e40ba4b --- /dev/null +++ b/src/test/ui/unsafe/issue-87414-query-cycle.rs @@ -0,0 +1,15 @@ +// Regression test for #87414. + +// check-pass +// compile-flags: -Zthir-unsafeck + +fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() } + +fn foo() -> [(); { |x: u32| { x }; 4 }] { todo!() } +fn bar() { let _: [(); { |x: u32| { x }; 4 }]; } + +// This one should not cause any errors either: +unsafe fn unsf() {} +fn bad2<T>() -> Box<dyn Iterator<Item = [(); { unsafe { || { unsf() } }; 4 }]>> { todo!() } + +fn main() {} diff --git a/src/test/ui/unsafe/ranged_ints.mir.stderr b/src/test/ui/unsafe/ranged_ints.mir.stderr new file mode 100644 index 000000000..f9ef7834e --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block + --> $DIR/ranged_ints.rs:10:14 + | +LL | let _x = NonZero(0); + | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr + | + = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints.rs b/src/test/ui/unsafe/ranged_ints.rs new file mode 100644 index 000000000..05efe87ba --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints.rs @@ -0,0 +1,11 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() { + let _x = NonZero(0); //~ ERROR initializing type with `rustc_layout_scalar_valid_range` attr +} diff --git a/src/test/ui/unsafe/ranged_ints.thir.stderr b/src/test/ui/unsafe/ranged_ints.thir.stderr new file mode 100644 index 000000000..f9ef7834e --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block + --> $DIR/ranged_ints.rs:10:14 + | +LL | let _x = NonZero(0); + | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr + | + = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr new file mode 100644 index 000000000..427843f8d --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints2.rs:11:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2.rs b/src/test/ui/unsafe/ranged_ints2.rs new file mode 100644 index 000000000..9a6bb18f9 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2.rs @@ -0,0 +1,12 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(1) }; + let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe +} diff --git a/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr new file mode 100644 index 000000000..427843f8d --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints2.rs:11:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr new file mode 100644 index 000000000..c16550a58 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr @@ -0,0 +1,39 @@ +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:14:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:21:22 + | +LL | let y = unsafe { &mut x.0 }; + | ^^^^^^^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:27:22 + | +LL | unsafe { let y = &mut x.0; } + | ^^^^^^^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints2_const.rs:14:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0133, E0658. +For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.rs b/src/test/ui/unsafe/ranged_ints2_const.rs new file mode 100644 index 000000000..56f5407bb --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2_const.rs @@ -0,0 +1,29 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() { +} + +const fn foo() -> NonZero<u32> { + let mut x = unsafe { NonZero(1) }; + let y = &mut x.0; //~ ERROR mutable references + //~^ ERROR mutation of layout constrained field is unsafe + unsafe { NonZero(1) } +} + +const fn bar() -> NonZero<u32> { + let mut x = unsafe { NonZero(1) }; + let y = unsafe { &mut x.0 }; //~ ERROR mutable references + unsafe { NonZero(1) } +} + +const fn boo() -> NonZero<u32> { + let mut x = unsafe { NonZero(1) }; + unsafe { let y = &mut x.0; } //~ ERROR mutable references + unsafe { NonZero(1) } +} diff --git a/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr new file mode 100644 index 000000000..b3f139f72 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr @@ -0,0 +1,39 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints2_const.rs:14:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:14:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:21:22 + | +LL | let y = unsafe { &mut x.0 }; + | ^^^^^^^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:27:22 + | +LL | unsafe { let y = &mut x.0; } + | ^^^^^^^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0133, E0658. +For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr new file mode 100644 index 000000000..9eec0b09e --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3.rs:13:13 + | +LL | let y = &x.0; + | ^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3.rs b/src/test/ui/unsafe/ranged_ints3.rs new file mode 100644 index 000000000..76d4bfe95 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3.rs @@ -0,0 +1,14 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(Cell::new(1)) }; + let y = &x.0; //~ ERROR borrow of layout constrained field with interior mutability +} diff --git a/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr new file mode 100644 index 000000000..9eec0b09e --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3.rs:13:13 + | +LL | let y = &x.0; + | ^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr new file mode 100644 index 000000000..62df93330 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr @@ -0,0 +1,30 @@ +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/ranged_ints3_const.rs:15:13 + | +LL | let y = &x.0; + | ^^^^ + | + = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information + = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable + +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/ranged_ints3_const.rs:22:22 + | +LL | let y = unsafe { &x.0 }; + | ^^^^ + | + = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information + = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable + +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_const.rs:15:13 + | +LL | let y = &x.0; + | ^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0133, E0658. +For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_const.rs b/src/test/ui/unsafe/ranged_ints3_const.rs new file mode 100644 index 000000000..637198d36 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3_const.rs @@ -0,0 +1,24 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() {} + +const fn foo() -> NonZero<Cell<u32>> { + let mut x = unsafe { NonZero(Cell::new(1)) }; + let y = &x.0; //~ ERROR the borrowed element may contain interior mutability + //~^ ERROR borrow of layout constrained field with interior mutability + unsafe { NonZero(Cell::new(1)) } +} + +const fn bar() -> NonZero<Cell<u32>> { + let mut x = unsafe { NonZero(Cell::new(1)) }; + let y = unsafe { &x.0 }; //~ ERROR the borrowed element may contain interior mutability + unsafe { NonZero(Cell::new(1)) } +} diff --git a/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr new file mode 100644 index 000000000..5dbc563aa --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr @@ -0,0 +1,30 @@ +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_const.rs:15:13 + | +LL | let y = &x.0; + | ^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/ranged_ints3_const.rs:15:13 + | +LL | let y = &x.0; + | ^^^^ + | + = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information + = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable + +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/ranged_ints3_const.rs:22:22 + | +LL | let y = unsafe { &x.0 }; + | ^^^^ + | + = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information + = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0133, E0658. +For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr new file mode 100644 index 000000000..27c066409 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr @@ -0,0 +1,19 @@ +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_match.rs:14:17 + | +LL | NonZero(ref x) => { x } + | ^^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_match.rs:20:23 + | +LL | match y { NonZero(ref mut y) => { y } }; + | ^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_match.rs b/src/test/ui/unsafe/ranged_ints3_match.rs new file mode 100644 index 000000000..d9fcf0bd6 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3_match.rs @@ -0,0 +1,22 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(Cell::new(1)) }; + match x { + NonZero(ref x) => { x } + //~^ ERROR borrow of layout constrained field with interior mutability + }; + + let mut y = unsafe { NonZero(42) }; + match y { NonZero(ref y) => { y } }; // OK, type of `y` is freeze + match y { NonZero(ref mut y) => { y } }; + //~^ ERROR mutation of layout constrained field +} diff --git a/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr new file mode 100644 index 000000000..27c066409 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr @@ -0,0 +1,19 @@ +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_match.rs:14:17 + | +LL | NonZero(ref x) => { x } + | ^^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_match.rs:20:23 + | +LL | match y { NonZero(ref mut y) => { y } }; + | ^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr new file mode 100644 index 000000000..493483d2c --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints4.rs:11:5 + | +LL | x.0 = 0; + | ^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4.rs b/src/test/ui/unsafe/ranged_ints4.rs new file mode 100644 index 000000000..fe80af454 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints4.rs @@ -0,0 +1,12 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(1) }; + x.0 = 0; //~ ERROR mutation of layout constrained field is unsafe +} diff --git a/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr new file mode 100644 index 000000000..493483d2c --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints4.rs:11:5 + | +LL | x.0 = 0; + | ^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr new file mode 100644 index 000000000..a06c6f479 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints4_const.rs:13:5 + | +LL | x.0 = 0; + | ^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4_const.rs b/src/test/ui/unsafe/ranged_ints4_const.rs new file mode 100644 index 000000000..a43c8be71 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints4_const.rs @@ -0,0 +1,22 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() {} + +const fn foo() -> NonZero<u32> { + let mut x = unsafe { NonZero(1) }; + x.0 = 0; + //~^ ERROR mutation of layout constrained field is unsafe + x +} + +const fn bar() -> NonZero<u32> { + let mut x = unsafe { NonZero(1) }; + unsafe { x.0 = 0 }; // this is UB + x +} diff --git a/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr new file mode 100644 index 000000000..a06c6f479 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints4_const.rs:13:5 + | +LL | x.0 = 0; + | ^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints_const.mir.stderr b/src/test/ui/unsafe/ranged_ints_const.mir.stderr new file mode 100644 index 000000000..33d134c7c --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints_const.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block + --> $DIR/ranged_ints_const.rs:11:34 + | +LL | const fn foo() -> NonZero<u32> { NonZero(0) } + | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr + | + = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints_const.rs b/src/test/ui/unsafe/ranged_ints_const.rs new file mode 100644 index 000000000..472b09681 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints_const.rs @@ -0,0 +1,14 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero<T>(pub(crate) T); +fn main() {} + +const fn foo() -> NonZero<u32> { NonZero(0) } +//~^ ERROR initializing type with `rustc_layout_scalar_valid_range` attr is unsafe + +const fn bar() -> NonZero<u32> { unsafe { NonZero(0) } } diff --git a/src/test/ui/unsafe/ranged_ints_const.thir.stderr b/src/test/ui/unsafe/ranged_ints_const.thir.stderr new file mode 100644 index 000000000..33d134c7c --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints_const.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block + --> $DIR/ranged_ints_const.rs:11:34 + | +LL | const fn foo() -> NonZero<u32> { NonZero(0) } + | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr + | + = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints_macro.rs b/src/test/ui/unsafe/ranged_ints_macro.rs new file mode 100644 index 000000000..8293d0299 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints_macro.rs @@ -0,0 +1,19 @@ +// build-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] + +macro_rules! apply { + ($val:expr) => { + #[rustc_layout_scalar_valid_range_start($val)] + #[repr(transparent)] + pub(crate) struct NonZero<T>(pub(crate) T); + } +} + +apply!(1); + +fn main() { + let _x = unsafe { NonZero(1) }; +} diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr new file mode 100644 index 000000000..fd58e1b1e --- /dev/null +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr @@ -0,0 +1,134 @@ +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 + | +LL | #![deny(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 + | +LL | VOID = (); + | ^^^^^^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9 + | +LL | #![deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 + | +LL | #[deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + | +LL | VOID = (); + | ^^^^^^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:35:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:5 + | +LL | unsafe { unsafe { unsf() } } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5 + | +LL | unsafe fn allow_level() { + | ----------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:53:9 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9 + | +LL | unsafe fn nested_allow_level() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:65:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0133]: call to unsafe function is unsafe and requires unsafe block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs new file mode 100644 index 000000000..30b072340 --- /dev/null +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -0,0 +1,87 @@ +// revisions: mir thir +// [thir]compile-flags: -Zthir-unsafeck + +#![deny(unsafe_op_in_unsafe_fn)] +#![deny(unused_unsafe)] + +unsafe fn unsf() {} +const PTR: *const () = std::ptr::null(); +static mut VOID: () = (); + +unsafe fn deny_level() { + unsf(); + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block + *PTR; + //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block + VOID = (); + //~^ ERROR use of mutable static is unsafe and requires unsafe block + + unsafe {} + //~^ ERROR unnecessary `unsafe` block +} + +// Check that `unsafe_op_in_unsafe_fn` works starting from the `warn` level. +#[warn(unsafe_op_in_unsafe_fn)] +#[deny(warnings)] +unsafe fn warning_level() { + unsf(); + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block + *PTR; + //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block + VOID = (); + //~^ ERROR use of mutable static is unsafe and requires unsafe block + unsafe {} + //~^ ERROR unnecessary `unsafe` block +} + +unsafe fn explicit_block() { + // no error + unsafe { + unsf(); + *PTR; + VOID = (); + } +} + +unsafe fn two_explicit_blocks() { + unsafe { unsafe { unsf() } } + //~^ ERROR unnecessary `unsafe` block +} + +#[allow(unsafe_op_in_unsafe_fn)] +unsafe fn allow_level() { + // lint allowed -> no error + unsf(); + *PTR; + VOID = (); + + unsafe { unsf() } + //~^ ERROR unnecessary `unsafe` block +} + +unsafe fn nested_allow_level() { + #[allow(unsafe_op_in_unsafe_fn)] + { + // lint allowed -> no error + unsf(); + *PTR; + VOID = (); + + unsafe { unsf() } + //~^ ERROR unnecessary `unsafe` block + } +} + +fn main() { + unsf(); + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block + #[allow(unsafe_op_in_unsafe_fn)] + { + unsf(); + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe function or block + } +} diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr new file mode 100644 index 000000000..2ba6a7293 --- /dev/null +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr @@ -0,0 +1,122 @@ +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 + | +LL | #![deny(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 + | +LL | VOID = (); + | ^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9 + | +LL | #![deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 + | +LL | #[deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + | +LL | VOID = (); + | ^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:35:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:14 + | +LL | unsafe { unsafe { unsf() } } + | ------ ^^^^^^ unnecessary `unsafe` block + | | + | because it's nested under this `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5 + | +LL | unsafe fn allow_level() { + | ----------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9 + | +LL | unsafe fn nested_allow_level() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr b/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr new file mode 100644 index 000000000..0ecd5203d --- /dev/null +++ b/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr @@ -0,0 +1,51 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:19:5 + | +LL | foo.a += 5; + | ^^^^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:20:6 + | +LL | *foo.b += NonCopy; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:21:6 + | +LL | *foo.b = NonCopy; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:23:5 + | +LL | foo.a; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:25:5 + | +LL | foo.b; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:27:13 + | +LL | foo.b = foo.b; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/union-assignop.rs b/src/test/ui/unsafe/union-assignop.rs new file mode 100644 index 000000000..5e667cd10 --- /dev/null +++ b/src/test/ui/unsafe/union-assignop.rs @@ -0,0 +1,29 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +use std::ops::AddAssign; +use std::mem::ManuallyDrop; + +struct NonCopy; +impl AddAssign for NonCopy { + fn add_assign(&mut self, _: Self) {} +} + +union Foo { + a: u8, // non-dropping + b: ManuallyDrop<NonCopy>, +} + +fn main() { + let mut foo = Foo { a: 42 }; + foo.a += 5; //~ ERROR access to union field is unsafe + *foo.b += NonCopy; //~ ERROR access to union field is unsafe + *foo.b = NonCopy; //~ ERROR access to union field is unsafe + foo.b = ManuallyDrop::new(NonCopy); + foo.a; //~ ERROR access to union field is unsafe + let foo = Foo { a: 42 }; + foo.b; //~ ERROR access to union field is unsafe + let mut foo = Foo { a: 42 }; + foo.b = foo.b; + //~^ ERROR access to union field is unsafe +} diff --git a/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr b/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr new file mode 100644 index 000000000..24b357e76 --- /dev/null +++ b/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr @@ -0,0 +1,51 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:19:5 + | +LL | foo.a += 5; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:20:6 + | +LL | *foo.b += NonCopy; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:21:6 + | +LL | *foo.b = NonCopy; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:23:5 + | +LL | foo.a; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:25:5 + | +LL | foo.b; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-assignop.rs:27:13 + | +LL | foo.b = foo.b; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/union-modification.rs b/src/test/ui/unsafe/union-modification.rs new file mode 100644 index 000000000..9a53ef908 --- /dev/null +++ b/src/test/ui/unsafe/union-modification.rs @@ -0,0 +1,37 @@ +// run-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +union Foo { + bar: i8, + _blah: isize, + _zst: (), +} + +struct FooHolder { + inner_foo: Foo +} + +fn do_nothing(_x: &mut Foo) {} + +pub fn main() { + let mut foo = Foo { bar: 5 }; + do_nothing(&mut foo); + foo.bar = 6; + unsafe { foo.bar += 1; } + assert_eq!(unsafe { foo.bar }, 7); + unsafe { + let Foo { bar: inner } = foo; + assert_eq!(inner, 7); + } + + let foo = Foo { bar: 5 }; + let foo = if let 3 = if let true = true { 3 } else { 4 } { foo } else { foo }; + + let (_foo2, _random) = (foo, 42); + + let mut foo_holder = FooHolder { inner_foo: Foo { bar: 5 } }; + foo_holder.inner_foo.bar = 4; + assert_eq!(unsafe { foo_holder.inner_foo.bar }, 4); + drop(foo_holder); +} diff --git a/src/test/ui/unsafe/union.mir.stderr b/src/test/ui/unsafe/union.mir.stderr new file mode 100644 index 000000000..787714cdd --- /dev/null +++ b/src/test/ui/unsafe/union.mir.stderr @@ -0,0 +1,19 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:30:20 + | +LL | Foo { bar: _a } => {}, + | ^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:32:11 + | +LL | match foo { + | ^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/union.rs b/src/test/ui/unsafe/union.rs new file mode 100644 index 000000000..4338d78ea --- /dev/null +++ b/src/test/ui/unsafe/union.rs @@ -0,0 +1,53 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +union Foo { + bar: i8, + zst: (), + pizza: Pizza, +} + +#[derive(Clone, Copy)] +struct Pizza { + topping: Option<PizzaTopping> +} + +#[allow(dead_code)] +#[derive(Clone, Copy)] +enum PizzaTopping { + Cheese, + Pineapple, +} + +fn do_nothing(_x: &mut Foo) {} + +pub fn main() { + let mut foo = Foo { bar: 5 }; + do_nothing(&mut foo); + + // This is UB, so this test isn't run + match foo { + Foo { bar: _a } => {}, //~ ERROR access to union field is unsafe + } + match foo { //[mir]~ ERROR access to union field is unsafe + Foo { + pizza: Pizza { //[thir]~ ERROR access to union field is unsafe + topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None + } + } => {}, + } + + // MIR unsafeck incorrectly thinks that no unsafe block is needed to do these + match foo { + Foo { zst: () } => {}, //[thir]~ ERROR access to union field is unsafe + } + match foo { + Foo { pizza: Pizza { .. } } => {}, //[thir]~ ERROR access to union field is unsafe + } + + // binding to wildcard is okay + match foo { + Foo { bar: _ } => {}, + } + let Foo { bar: _ } = foo; +} diff --git a/src/test/ui/unsafe/union.thir.stderr b/src/test/ui/unsafe/union.thir.stderr new file mode 100644 index 000000000..e1a1bd634 --- /dev/null +++ b/src/test/ui/unsafe/union.thir.stderr @@ -0,0 +1,38 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:30:20 + | +LL | Foo { bar: _a } => {}, + | ^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:34:20 + | +LL | pizza: Pizza { + | ____________________^ +LL | | topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None +LL | | } + | |_____________^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:42:20 + | +LL | Foo { zst: () } => {}, + | ^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:45:22 + | +LL | Foo { pizza: Pizza { .. } } => {}, + | ^^^^^^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/union_access_through_block.rs b/src/test/ui/unsafe/union_access_through_block.rs new file mode 100644 index 000000000..e4c0976b8 --- /dev/null +++ b/src/test/ui/unsafe/union_access_through_block.rs @@ -0,0 +1,18 @@ +// check-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#[derive(Copy, Clone)] +pub struct Foo { a: bool } + +pub union Bar { + a: Foo, + b: u32, +} +pub fn baz(mut bar: Bar) { + unsafe { + { bar.a }.a = true; + } +} + +fn main() {} diff --git a/src/test/ui/unsafe/union_destructure.mir.stderr b/src/test/ui/unsafe/union_destructure.mir.stderr new file mode 100644 index 000000000..818f5ce03 --- /dev/null +++ b/src/test/ui/unsafe/union_destructure.mir.stderr @@ -0,0 +1,16 @@ +warning: unnecessary `unsafe` block + --> $DIR/union_destructure.rs:35:5 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: `#[warn(unused_unsafe)]` on by default + +warning: unnecessary `unsafe` block + --> $DIR/union_destructure.rs:41:5 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +warning: 2 warnings emitted + diff --git a/src/test/ui/unsafe/union_destructure.rs b/src/test/ui/unsafe/union_destructure.rs new file mode 100644 index 000000000..6c88344b5 --- /dev/null +++ b/src/test/ui/unsafe/union_destructure.rs @@ -0,0 +1,51 @@ +// run-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#[derive(Copy, Clone)] +#[allow(dead_code)] +struct Pie { + slices: u8, + size: u8, +} + +union Foo { + #[allow(dead_code)] + bar: i8, + baz: Pie +} + +fn main() { + let u = Foo { bar: 5 }; + let (Some(Foo { bar: _ }) | None) = Some(u); + let u = Foo { bar: 6 }; + let (Some(Foo { bar: _ }) | Some(Foo { bar: _ }) | None) = Some(u); + unsafe { + let u = Foo { bar: 7 }; + let (Foo { bar } | Foo { bar }) = u; + assert_eq!(bar, 7) + } + let u = Foo { bar: 8 }; + match Some(u) { + Some(Foo { bar: _ }) => 3, + None => 4, + }; + + let u = Foo { bar: 9 }; + unsafe { //[mir]~ WARNING unnecessary `unsafe` block + match u { + Foo { baz: Pie { .. } } => {}, + }; + } + let u = Foo { bar: 10 }; + unsafe { //[mir]~ WARNING unnecessary `unsafe` block + match u { + Foo { baz: Pie { slices: _, size: _ } } => {}, + }; + } + + let u = Foo { bar: 11 }; + match u { + Foo { baz: _ } => {}, + }; +} diff --git a/src/test/ui/unsafe/union_wild_or_wild.rs b/src/test/ui/unsafe/union_wild_or_wild.rs new file mode 100644 index 000000000..52a0a7abf --- /dev/null +++ b/src/test/ui/unsafe/union_wild_or_wild.rs @@ -0,0 +1,12 @@ +// check-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +union X { a: i8 } + +fn main() { + let x = X { a: 5 }; + match x { + X { a: _ | _ } => {}, + } +} diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr new file mode 100644 index 000000000..62199e5a2 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr @@ -0,0 +1,20 @@ +error: unnecessary `unsafe` block + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:9 + | +LL | unsafe { async {}.await; } + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:5:9 + | +LL | #![deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:13:5 + | +LL | unsafe { println!("foo"); } + | ^^^^^^ unnecessary `unsafe` block + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs new file mode 100644 index 000000000..c1a327640 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs @@ -0,0 +1,14 @@ +// edition:2018 +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![deny(unused_unsafe)] + +fn main() { + let _ = async { + unsafe { async {}.await; } //~ ERROR unnecessary `unsafe` + }; + + // `format_args!` expands with a compiler-generated unsafe block + unsafe { println!("foo"); } //~ ERROR unnecessary `unsafe` +} diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr new file mode 100644 index 000000000..62199e5a2 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr @@ -0,0 +1,20 @@ +error: unnecessary `unsafe` block + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:9 + | +LL | unsafe { async {}.await; } + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:5:9 + | +LL | #![deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:13:5 + | +LL | unsafe { println!("foo"); } + | ^^^^^^ unnecessary `unsafe` block + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr b/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr new file mode 100644 index 000000000..9abc51424 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-assign.rs:12:5 + | +LL | foo.0.0 = 0; + | ^^^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-assign.rs b/src/test/ui/unsafe/unsafe-assign.rs new file mode 100644 index 000000000..15273165b --- /dev/null +++ b/src/test/ui/unsafe/unsafe-assign.rs @@ -0,0 +1,25 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] +#![allow(unused,dead_code)] + +fn nested_field() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<T>(T); + + let mut foo = unsafe { NonZero((1,)) }; + foo.0.0 = 0; + //~^ ERROR: mutation of layout constrained field is unsafe +} + +fn block() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<T>(T); + + let mut foo = unsafe { NonZero((1,)) }; + { foo.0 }.0 = 0; + // ^ not unsafe because the result of the block expression is a new place +} + +fn main() {} diff --git a/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr b/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr new file mode 100644 index 000000000..9abc51424 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-assign.rs:12:5 + | +LL | foo.0.0 = 0; + | ^^^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-block-without-braces.rs b/src/test/ui/unsafe/unsafe-block-without-braces.rs new file mode 100644 index 000000000..4e4611618 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-block-without-braces.rs @@ -0,0 +1,6 @@ +fn main() { + unsafe //{ + std::mem::transmute::<f32, u32>(1.0); + //} +} +//~^^^ ERROR expected `{`, found `std` diff --git a/src/test/ui/unsafe/unsafe-block-without-braces.stderr b/src/test/ui/unsafe/unsafe-block-without-braces.stderr new file mode 100644 index 000000000..44f77b99c --- /dev/null +++ b/src/test/ui/unsafe/unsafe-block-without-braces.stderr @@ -0,0 +1,15 @@ +error: expected `{`, found `std` + --> $DIR/unsafe-block-without-braces.rs:3:9 + | +LL | unsafe //{ + | ------ while parsing this `unsafe` expression +LL | std::mem::transmute::<f32, u32>(1.0); + | ^^^ expected `{` + | +help: try placing this code inside a block + | +LL | { std::mem::transmute::<f32, u32>(1.0); } + | + + + +error: aborting due to previous error + diff --git a/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr b/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr new file mode 100644 index 000000000..a20672249 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr @@ -0,0 +1,27 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-borrow.rs:12:13 + | +LL | let a = &mut foo.0.0; + | ^^^^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-borrow.rs:32:13 + | +LL | let a = &mut foo.0[2]; + | ^^^^^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-borrow.rs:51:18 + | +LL | NonZero((a,)) => *a = 0, + | ^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-borrow.rs b/src/test/ui/unsafe/unsafe-borrow.rs new file mode 100644 index 000000000..8dddc70be --- /dev/null +++ b/src/test/ui/unsafe/unsafe-borrow.rs @@ -0,0 +1,56 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck + +#![feature(rustc_attrs)] +#![allow(unused,dead_code)] + +fn tuple_struct() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<T>(T); + + let mut foo = unsafe { NonZero((1,)) }; + let a = &mut foo.0.0; + //~^ ERROR: mutation of layout constrained field is unsafe +} + +fn slice() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<'a, T>(&'a mut [T]); + + let mut nums = [1, 2, 3, 4]; + let mut foo = unsafe { NonZero(&mut nums[..]) }; + let a = &mut foo.0[2]; + // ^ not unsafe because there is an implicit dereference here +} + +fn array() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<T>([T; 4]); + + let nums = [1, 2, 3, 4]; + let mut foo = unsafe { NonZero(nums) }; + let a = &mut foo.0[2]; + //~^ ERROR: mutation of layout constrained field is unsafe +} + +fn block() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<T>(T); + + let foo = unsafe { NonZero((1,)) }; + &mut { foo.0 }.0; + // ^ not unsafe because the result of the block expression is a new place +} + +fn mtch() { + #[rustc_layout_scalar_valid_range_start(1)] + struct NonZero<T>(T); + + let mut foo = unsafe { NonZero((1,)) }; + match &mut foo { + NonZero((a,)) => *a = 0, + //~^ ERROR: mutation of layout constrained field is unsafe + } +} + +fn main() {} diff --git a/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr b/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr new file mode 100644 index 000000000..a20672249 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr @@ -0,0 +1,27 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-borrow.rs:12:13 + | +LL | let a = &mut foo.0.0; + | ^^^^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-borrow.rs:32:13 + | +LL | let a = &mut foo.0[2]; + | ^^^^^^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/unsafe-borrow.rs:51:18 + | +LL | NonZero((a,)) => *a = 0, + | ^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-const-fn.mir.stderr b/src/test/ui/unsafe/unsafe-const-fn.mir.stderr new file mode 100644 index 000000000..3031be720 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-const-fn.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unsafe-const-fn.rs:10:18 + | +LL | const VAL: u32 = dummy(0xFFFF); + | ^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-const-fn.rs b/src/test/ui/unsafe/unsafe-const-fn.rs new file mode 100644 index 000000000..65e3acf30 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-const-fn.rs @@ -0,0 +1,15 @@ +// A quick test of 'unsafe const fn' functionality + +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +const unsafe fn dummy(v: u32) -> u32 { + !v +} + +const VAL: u32 = dummy(0xFFFF); +//~^ ERROR E0133 + +fn main() { + assert_eq!(VAL, 0xFFFF0000); +} diff --git a/src/test/ui/unsafe/unsafe-const-fn.thir.stderr b/src/test/ui/unsafe/unsafe-const-fn.thir.stderr new file mode 100644 index 000000000..1a77adf44 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-const-fn.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `dummy` is unsafe and requires unsafe function or block + --> $DIR/unsafe-const-fn.rs:10:18 + | +LL | const VAL: u32 = dummy(0xFFFF); + | ^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.mir.stderr b/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.mir.stderr new file mode 100644 index 000000000..fee645e41 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-assign-deref-ptr.rs:5:5 + | +LL | *p = 0; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.rs b/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.rs new file mode 100644 index 000000000..a94e94375 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.rs @@ -0,0 +1,10 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +fn f(p: *mut u8) { + *p = 0; //~ ERROR dereference of raw pointer is unsafe + return; +} + +fn main() { +} diff --git a/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.thir.stderr b/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.thir.stderr new file mode 100644 index 000000000..bbe4a415b --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-assign-deref-ptr.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-assign-deref-ptr.rs:5:5 + | +LL | *p = 0; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-autoderef.rs b/src/test/ui/unsafe/unsafe-fn-autoderef.rs new file mode 100644 index 000000000..60460fc6e --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-autoderef.rs @@ -0,0 +1,23 @@ +struct Rec { + f: isize +} + +fn f(p: *const Rec) -> isize { + + // Test that * ptrs do not autoderef. There is a deeper reason for + // prohibiting this, beyond making unsafe things annoying (which doesn't + // actually seem desirable to me). The deeper reason is that if you + // have a type like: + // + // enum foo = *foo; + // + // you end up with an infinite auto-deref chain, which is + // currently impossible (in all other cases, infinite auto-derefs + // are prohibited by various checks, such as that the enum is + // instantiable and so forth). + + return p.f; //~ ERROR no field `f` on type `*const Rec` +} + +fn main() { +} diff --git a/src/test/ui/unsafe/unsafe-fn-autoderef.stderr b/src/test/ui/unsafe/unsafe-fn-autoderef.stderr new file mode 100644 index 000000000..20a88c356 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-autoderef.stderr @@ -0,0 +1,11 @@ +error[E0609]: no field `f` on type `*const Rec` + --> $DIR/unsafe-fn-autoderef.rs:19:14 + | +LL | return p.f; + | --^ + | | + | help: `p` is a raw pointer; try dereferencing it: `(*p).f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/unsafe/unsafe-fn-called-from-safe.mir.stderr b/src/test/ui/unsafe/unsafe-fn-called-from-safe.mir.stderr new file mode 100644 index 000000000..1d6fa4cbf --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-called-from-safe.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-called-from-safe.rs:7:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs b/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs new file mode 100644 index 000000000..55072dcc6 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs @@ -0,0 +1,10 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +unsafe fn f() { return; } + +fn main() { + f(); + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `f` is unsafe +} diff --git a/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr b/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr new file mode 100644 index 000000000..206dbd90a --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-called-from-safe.rs:7:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr b/src/test/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr new file mode 100644 index 000000000..a26149924 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:5:12 + | +LL | return *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-deref-ptr.rs b/src/test/ui/unsafe/unsafe-fn-deref-ptr.rs new file mode 100644 index 000000000..dc989535b --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-deref-ptr.rs @@ -0,0 +1,9 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +fn f(p: *const u8) -> u8 { + return *p; //~ ERROR dereference of raw pointer is unsafe +} + +fn main() { +} diff --git a/src/test/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr b/src/test/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr new file mode 100644 index 000000000..a26149924 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:5:12 + | +LL | return *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-used-as-value.mir.stderr b/src/test/ui/unsafe/unsafe-fn-used-as-value.mir.stderr new file mode 100644 index 000000000..b08a7109d --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-used-as-value.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-used-as-value.rs:8:5 + | +LL | x(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-fn-used-as-value.rs b/src/test/ui/unsafe/unsafe-fn-used-as-value.rs new file mode 100644 index 000000000..9517598c7 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-used-as-value.rs @@ -0,0 +1,11 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +unsafe fn f() { return; } + +fn main() { + let x = f; + x(); + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `f` is unsafe +} diff --git a/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr b/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr new file mode 100644 index 000000000..e81dd3b2b --- /dev/null +++ b/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-used-as-value.rs:8:5 + | +LL | x(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-subtyping.rs b/src/test/ui/unsafe/unsafe-subtyping.rs new file mode 100644 index 000000000..a4b748a50 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-subtyping.rs @@ -0,0 +1,11 @@ +// Check that safe fns are not a subtype of unsafe fns. + +fn foo(x: Option<fn(i32)>) -> Option<unsafe fn(i32)> { + x //~ ERROR mismatched types +} + +fn bar(x: fn(i32)) -> unsafe fn(i32) { + x // OK, coercion! +} + +fn main() { } diff --git a/src/test/ui/unsafe/unsafe-subtyping.stderr b/src/test/ui/unsafe/unsafe-subtyping.stderr new file mode 100644 index 000000000..2db7cc312 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-subtyping.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/unsafe-subtyping.rs:4:5 + | +LL | fn foo(x: Option<fn(i32)>) -> Option<unsafe fn(i32)> { + | ---------------------- expected `Option<unsafe fn(i32)>` because of return type +LL | x + | ^ expected unsafe fn, found normal fn + | + = note: expected enum `Option<unsafe fn(_)>` + found enum `Option<fn(_)>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/unsafe/unsafe-trait-impl.rs b/src/test/ui/unsafe/unsafe-trait-impl.rs new file mode 100644 index 000000000..03a251be1 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-trait-impl.rs @@ -0,0 +1,14 @@ +// Check that safe fns are not a subtype of unsafe fns. + +trait Foo { + unsafe fn len(&self) -> u32; +} + +impl Foo for u32 { + fn len(&self) -> u32 { *self } + //~^ ERROR method `len` has an incompatible type for trait + //~| expected fn pointer `unsafe fn(&u32) -> _` + //~| found fn pointer `fn(&u32) -> _` +} + +fn main() { } diff --git a/src/test/ui/unsafe/unsafe-trait-impl.stderr b/src/test/ui/unsafe/unsafe-trait-impl.stderr new file mode 100644 index 000000000..8a0cba1fa --- /dev/null +++ b/src/test/ui/unsafe/unsafe-trait-impl.stderr @@ -0,0 +1,17 @@ +error[E0053]: method `len` has an incompatible type for trait + --> $DIR/unsafe-trait-impl.rs:8:5 + | +LL | fn len(&self) -> u32 { *self } + | ^^^^^^^^^^^^^^^^^^^^ expected unsafe fn, found normal fn + | +note: type in trait + --> $DIR/unsafe-trait-impl.rs:4:5 + | +LL | unsafe fn len(&self) -> u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected fn pointer `unsafe fn(&u32) -> _` + found fn pointer `fn(&u32) -> _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.mir.stderr b/src/test/ui/unsafe/unsafe-unstable-const-fn.mir.stderr new file mode 100644 index 000000000..dcb84a80c --- /dev/null +++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-unstable-const-fn.rs:10:5 + | +LL | *a == b + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.rs b/src/test/ui/unsafe/unsafe-unstable-const-fn.rs new file mode 100644 index 000000000..581b15cdf --- /dev/null +++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.rs @@ -0,0 +1,14 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![stable(feature = "foo", since = "1.33.0")] +#![feature(staged_api)] + +#[stable(feature = "foo", since = "1.33.0")] +#[rustc_const_unstable(feature = "const_foo", issue = "none")] +const fn unstable(a: *const i32, b: i32) -> bool { + *a == b + //~^ dereference of raw pointer is unsafe +} + +fn main() {} diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.thir.stderr b/src/test/ui/unsafe/unsafe-unstable-const-fn.thir.stderr new file mode 100644 index 000000000..dcb84a80c --- /dev/null +++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-unstable-const-fn.rs:10:5 + | +LL | *a == b + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. |