rust/tests/ui/span/lint-unused-unsafe.rs
Matthew Jasper dc3d428a8a Make THIR unused_unsafe lint consistent with MIR
Updates THIR behavior to match the changes from #93678
2023-10-25 10:10:13 +00:00

1097 lines
34 KiB
Rust

// Exercise the unused_unsafe attribute in some positive and negative cases
// edition:2018
// revisions: mir thir
// [thir]compile-flags: -Zthir-unsafeck
#![allow(dead_code)]
#![deny(unused_unsafe)]
mod foo {
extern "C" {
pub fn bar();
}
}
fn callback<T, F>(_f: F) -> T where F: FnOnce() -> T { panic!() }
unsafe fn unsf() {}
fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block
unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block
unsafe fn bad5() { unsafe { unsf() } }
fn bad6() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe { // don't put the warning here
unsf()
}
}
}
unsafe fn bad7() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe {
unsf()
}
}
}
unsafe fn good0() { unsf() }
fn good1() { unsafe { unsf() } }
fn good2() {
/* bug uncovered when implementing warning about unused unsafe blocks. Be
sure that when purity is inherited that the source of the unsafe-ness
is tracked correctly */
unsafe {
unsafe fn what() -> Vec<String> { panic!() }
callback(|| {
what();
});
}
}
unsafe fn good3() { foo::bar() }
fn good4() { unsafe { foo::bar() } }
#[allow(unused_unsafe)] fn allowed() { unsafe {} }
fn main() {}
mod additional_tests {
unsafe fn unsf() {}
// some tests
fn inner_ignored() {
unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
unsafe {
unsf()
}
}
}
fn multi_level_unused() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe {} //~ ERROR: unnecessary `unsafe` block
unsafe {} //~ ERROR: unnecessary `unsafe` block
}
}
fn granularity() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() }
unsafe { unsf() }
unsafe { unsf() }
}
}
fn top_level_used() {
unsafe {
unsf();
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
}
}
fn top_level_ignored() {
#[allow(unused_unsafe)]
unsafe {
#[deny(unused_unsafe)]
{
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
}
}
}
// same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_1() {
unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
unsafe {
unsf()
}
}
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_1() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe {} //~ ERROR: unnecessary `unsafe` block
unsafe {} //~ ERROR: unnecessary `unsafe` block
}
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_1() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() }
unsafe { unsf() }
unsafe { unsf() }
}
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_1() {
unsafe {
unsf();
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
}
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_1() {
#[allow(unused_unsafe)]
unsafe {
#[deny(unused_unsafe)]
{
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
}
}
}
// same tests, but unsafe_op_in_unsafe_fn allowed,
// so that *all* unsafe blocks are unused
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_2() {
unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
unsafe {
unsf()
}
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_2() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe {} //~ ERROR: unnecessary `unsafe` block
unsafe {} //~ ERROR: unnecessary `unsafe` block
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() }
unsafe { unsf() }
unsafe { unsf() }
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
unsafe {
unsf();
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_2() {
#[allow(unused_unsafe)]
unsafe {
#[deny(unused_unsafe)]
{
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
}
}
}
// additional tests when using unsafe_op_in_unsafe_fn
// in more complex ways
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn() {
unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_2() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
}
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
unsafe {
unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
}
unsf();
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_4() {
unsafe {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsf();
}
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
}
}
}
// the same set of tests, with closures everywhere
mod additional_tests_closures {
unsafe fn unsf() {}
// some tests
fn inner_ignored() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
fn multi_level_unused() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
fn granularity() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
fn top_level_used() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
fn top_level_ignored() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_1() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_1() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// same tests, but unsafe_op_in_unsafe_fn allowed,
// so that *all* unsafe blocks are unused
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_2() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// additional tests when using unsafe_op_in_unsafe_fn
// in more complex ways
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn() {
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
unsf();
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_4() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
unsf();
};
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
}
}
// the same set of tests, with closures everywhere
// and closures on the unsafe fn calls
mod additional_tests_even_more_closures {
unsafe fn unsf() {}
// some tests
fn inner_ignored() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
let _ = || unsf();
};
};
}
fn multi_level_unused() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
fn granularity() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); };
let _ = || unsafe { let _ = || unsf(); };
let _ = || unsafe { let _ = || unsf(); };
};
}
fn top_level_used() {
let _ = || unsafe {
let _ = || unsf();
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
};
}
fn top_level_ignored() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
let _ = || unsf();
};
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); };
let _ = || unsafe { let _ = || unsf(); };
let _ = || unsafe { let _ = || unsf(); };
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_1() {
let _ = || unsafe {
let _ = || unsf();
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_1() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// same tests, but unsafe_op_in_unsafe_fn allowed,
// so that *all* unsafe blocks are unused
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
let _ = || unsf();
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); };
let _ = || unsafe { let _ = || unsf(); };
let _ = || unsafe { let _ = || unsf(); };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
let _ = || unsafe {
let _ = || unsf();
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_2() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// additional tests when using unsafe_op_in_unsafe_fn
// in more complex ways
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn() {
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
let _ = || unsf();
}
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
let _ = || unsf();
}
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
let _ = || unsf();
}
};
let _ = || unsf();
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_4() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsf();
};
#[deny(unsafe_op_in_unsafe_fn)]
{
let _ = || unsf();
}
};
}
}
mod item_likes {
unsafe fn unsf() {}
struct S;
impl S {
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_1() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_1() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// same tests, but unsafe_op_in_unsafe_fn allowed,
// so that *all* unsafe blocks are unused
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_2() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// additional tests when using unsafe_op_in_unsafe_fn
// in more complex ways
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn() {
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
unsf();
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_4() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
unsf();
};
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
}
}
trait T {
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_1() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_1() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_1() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// same tests, but unsafe_op_in_unsafe_fn allowed,
// so that *all* unsafe blocks are unused
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn inner_ignored_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[allow(unused_unsafe)]
let _ = || unsafe {
unsf()
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn multi_level_unused_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
let _ = || unsafe { unsf() };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_ignored_2() {
#[allow(unused_unsafe)]
let _ = || unsafe {
#[deny(unused_unsafe)]
{
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
}
};
}
// additional tests when using unsafe_op_in_unsafe_fn
// in more complex ways
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn() {
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe {
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
unsf();
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_4() {
let _ = || unsafe {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
unsf();
};
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
}
}
}
mod additional_tests_extra {
unsafe fn unsf() {}
// multiple uses with different `unsafe_op_in_unsafe_fn` in the same closure
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn() {
let _ = || unsafe {
let _ = || {
unsf();
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
}
};
};
}
#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
unsafe {
#[allow(unsafe_op_in_unsafe_fn)]
{
unsf();
}
#[allow(unsafe_op_in_unsafe_fn)]
{
unsf();
}
}
}
async unsafe fn async_blocks() {
#[deny(unsafe_op_in_unsafe_fn)]
{
let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }};
let _ = async { unsafe { let _ = async { unsf() }; }};
let _ = async { unsafe { let _ = async { unsf() }; }};
}};
let _ = async { unsafe {
let _ = async { unsf() };
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
}};
}
#[allow(unsafe_op_in_unsafe_fn)]
{
let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }};
let _ = async { unsafe { let _ = async { unsf() }; }};
let _ = async { unsafe { let _ = async { unsf() }; }};
}};
let _ = async { unsafe {
let _ = async { unsf() };
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
}};
}
}
fn used_unsafe_in_const() {
let _x: [(); unsafe { size() }] = [];
}
fn unused_unsafe_in_const_1() {
let _x: [(); unsafe { 0 }] = []; //~ ERROR: unnecessary `unsafe` block
}
fn unused_unsafe_in_const_2() {
let _x: [(); unsafe { unsafe { size() } }] = []; //~ ERROR: unnecessary `unsafe` block
}
const unsafe fn size() -> usize { 0 }
}