//@aux-build:proc_macro_unsafe.rs:proc-macro #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] #![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)] #![feature(lint_reasons)] extern crate proc_macro_unsafe; // Valid comments fn nested_local() { let _ = { let _ = { // SAFETY: let _ = unsafe {}; }; }; } fn deep_nest() { let _ = { let _ = { // SAFETY: let _ = unsafe {}; // Safety: unsafe {}; let _ = { let _ = { let _ = { let _ = { let _ = { // Safety: let _ = unsafe {}; // SAFETY: unsafe {}; }; }; }; // Safety: unsafe {}; }; }; }; // Safety: unsafe {}; }; // SAFETY: unsafe {}; } fn local_tuple_expression() { // Safety: let _ = (42, unsafe {}); } fn line_comment() { // Safety: unsafe {} } fn line_comment_newlines() { // SAFETY: unsafe {} } fn line_comment_empty() { // Safety: // // // unsafe {} } fn line_comment_with_extras() { // This is a description // Safety: unsafe {} } fn block_comment() { /* Safety: */ unsafe {} } fn block_comment_newlines() { /* SAFETY: */ unsafe {} } fn block_comment_with_extras() { /* This is a description * SAFETY: */ unsafe {} } fn block_comment_terminator_same_line() { /* This is a description * Safety: */ unsafe {} } fn buried_safety() { // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est // laborum. Safety: // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. unsafe {} } fn safety_with_prepended_text() { // This is a test. safety: unsafe {} } fn local_line_comment() { // Safety: let _ = unsafe {}; } fn local_block_comment() { /* SAFETY: */ let _ = unsafe {}; } fn comment_array() { // Safety: let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; } fn comment_tuple() { // sAFETY: let _ = (42, unsafe {}, "test", unsafe {}); } fn comment_unary() { // SAFETY: let _ = *unsafe { &42 }; } #[allow(clippy::match_single_binding)] fn comment_match() { // SAFETY: let _ = match unsafe {} { _ => {}, }; } fn comment_addr_of() { // Safety: let _ = &unsafe {}; } fn comment_repeat() { // Safety: let _ = [unsafe {}; 5]; } fn comment_macro_call() { macro_rules! t { ($b:expr) => { $b }; } t!( // SAFETY: unsafe {} ); } fn comment_macro_def() { macro_rules! t { () => { // Safety: unsafe {} }; } t!(); } fn non_ascii_comment() { // ॐ᧻໒ SaFeTy: ௵∰ unsafe {}; } fn local_commented_block() { let _ = // safety: unsafe {}; } fn local_nest() { // safety: let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})]; } fn in_fn_call(x: *const u32) { fn f(x: u32) {} // Safety: reason f(unsafe { *x }); } fn multi_in_fn_call(x: *const u32) { fn f(x: u32, y: u32) {} // Safety: reason f(unsafe { *x }, unsafe { *x }); } fn in_multiline_fn_call(x: *const u32) { fn f(x: u32, y: u32) {} f( // Safety: reason unsafe { *x }, 0, ); } fn in_macro_call(x: *const u32) { // Safety: reason println!("{}", unsafe { *x }); } fn in_multiline_macro_call(x: *const u32) { println!( "{}", // Safety: reason unsafe { *x }, ); } fn from_proc_macro() { proc_macro_unsafe::unsafe_block!(token); } fn in_closure(x: *const u32) { // Safety: reason let _ = || unsafe { *x }; } // Invalid comments #[rustfmt::skip] fn inline_block_comment() { /* Safety: */ unsafe {} } fn no_comment() { unsafe {} } fn no_comment_array() { let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; } fn no_comment_tuple() { let _ = (42, unsafe {}, "test", unsafe {}); } fn no_comment_unary() { let _ = *unsafe { &42 }; } #[allow(clippy::match_single_binding)] fn no_comment_match() { let _ = match unsafe {} { _ => {}, }; } fn no_comment_addr_of() { let _ = &unsafe {}; } fn no_comment_repeat() { let _ = [unsafe {}; 5]; } fn local_no_comment() { let _ = unsafe {}; } fn no_comment_macro_call() { macro_rules! t { ($b:expr) => { $b }; } t!(unsafe {}); } fn no_comment_macro_def() { macro_rules! t { () => { unsafe {} }; } t!(); } fn trailing_comment() { unsafe {} // SAFETY: } fn internal_comment() { unsafe { // SAFETY: } } fn interference() { // SAFETY let _ = 42; unsafe {}; } pub fn print_binary_tree() { println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); } mod unsafe_impl_smoke_test { unsafe trait A {} // error: no safety comment unsafe impl A for () {} // Safety: ok unsafe impl A for (i32) {} mod sub_mod { // error: unsafe impl B for (u32) {} unsafe trait B {} } #[rustfmt::skip] mod sub_mod2 { // // SAFETY: ok // unsafe impl B for (u32) {} unsafe trait B {} } } mod unsafe_impl_from_macro { unsafe trait T {} // error macro_rules! no_safety_comment { ($t:ty) => { unsafe impl T for $t {} }; } // ok no_safety_comment!(()); // ok macro_rules! with_safety_comment { ($t:ty) => { // SAFETY: unsafe impl T for $t {} }; } // ok with_safety_comment!((i32)); } mod unsafe_impl_macro_and_not_macro { unsafe trait T {} // error macro_rules! no_safety_comment { ($t:ty) => { unsafe impl T for $t {} }; } // ok no_safety_comment!(()); // error unsafe impl T for (i32) {} // ok no_safety_comment!(u32); // error unsafe impl T for (bool) {} } #[rustfmt::skip] mod unsafe_impl_valid_comment { unsafe trait SaFety {} // SaFety: unsafe impl SaFety for () {} unsafe trait MultiLineComment {} // The following impl is safe // ... // Safety: reason unsafe impl MultiLineComment for () {} unsafe trait NoAscii {} // 安全 SAFETY: 以下のコードは安全です unsafe impl NoAscii for () {} unsafe trait InlineAndPrecedingComment {} // SAFETY: /* comment */ unsafe impl InlineAndPrecedingComment for () {} unsafe trait BuriedSafety {} // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est // laborum. Safety: // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. unsafe impl BuriedSafety for () {} unsafe trait MultiLineBlockComment {} /* This is a description * Safety: */ unsafe impl MultiLineBlockComment for () {} } #[rustfmt::skip] mod unsafe_impl_invalid_comment { unsafe trait NoComment {} unsafe impl NoComment for () {} unsafe trait InlineComment {} /* SAFETY: */ unsafe impl InlineComment for () {} unsafe trait TrailingComment {} unsafe impl TrailingComment for () {} // SAFETY: unsafe trait Interference {} // SAFETY: const BIG_NUMBER: i32 = 1000000; unsafe impl Interference for () {} } unsafe trait ImplInFn {} fn impl_in_fn() { // error unsafe impl ImplInFn for () {} // SAFETY: ok unsafe impl ImplInFn for (i32) {} } unsafe trait CrateRoot {} // error unsafe impl CrateRoot for () {} // SAFETY: ok unsafe impl CrateRoot for (i32) {} fn issue_9142() { // SAFETY: ok let _ = // we need this comment to avoid rustfmt putting // it all on one line unsafe {}; // SAFETY: this is more than one level away, so it should warn let _ = { if unsafe { true } { todo!(); } else { let bar = unsafe {}; todo!(); bar } }; } pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 { 1 } pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 { 2 } fn issue_10832() { // Safety: A safety comment let _some_variable_with_a_very_long_name_to_break_the_line = unsafe { a_function_with_a_very_long_name_to_break_the_line() }; // Safety: Another safety comment const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; // Safety: Yet another safety comment static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; } fn issue_8679() { // SAFETY: #[allow(unsafe_code)] unsafe {} // SAFETY: #[expect(unsafe_code, reason = "totally safe")] unsafe { *std::ptr::null::() }; // Safety: A safety comment #[allow(unsafe_code)] let _some_variable_with_a_very_long_name_to_break_the_line = unsafe { a_function_with_a_very_long_name_to_break_the_line() }; // Safety: Another safety comment #[allow(unsafe_code)] const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; // Safety: Yet another safety comment #[allow(unsafe_code)] static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; // SAFETY: #[allow(unsafe_code)] // This also works I guess unsafe {} } fn main() {}