261 lines
5.9 KiB
Rust
261 lines
5.9 KiB
Rust
//! Tests macro_metavars_in_unsafe with default configuration
|
|
#![feature(decl_macro)]
|
|
#![warn(clippy::macro_metavars_in_unsafe)]
|
|
#![allow(clippy::no_effect)]
|
|
|
|
#[macro_export]
|
|
macro_rules! allow_works {
|
|
($v:expr) => {
|
|
#[expect(clippy::macro_metavars_in_unsafe)]
|
|
unsafe {
|
|
$v;
|
|
};
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! simple {
|
|
($v:expr) => {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
dbg!($v);
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
#[rustfmt::skip] // for some reason rustfmt rewrites $r#unsafe to r#u$nsafe, bug?
|
|
macro_rules! raw_symbol {
|
|
($r#mod:expr, $r#unsafe:expr) => {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$r#mod;
|
|
}
|
|
$r#unsafe;
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! multilevel_unsafe {
|
|
($v:expr) => {
|
|
unsafe {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$v;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! in_function {
|
|
($v:expr) => {
|
|
unsafe {
|
|
fn f() {
|
|
// function introduces a new body, so don't lint.
|
|
$v;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! in_function_with_unsafe {
|
|
($v:expr) => {
|
|
unsafe {
|
|
fn f() {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$v;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! const_static {
|
|
($c:expr, $s:expr) => {
|
|
unsafe {
|
|
// const and static introduces new body, don't lint
|
|
const _X: i32 = $c;
|
|
static _Y: i32 = $s;
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! const_generic_in_struct {
|
|
($inside_unsafe:expr, $outside_unsafe:expr) => {
|
|
unsafe {
|
|
struct Ty<
|
|
const L: i32 = 1,
|
|
const M: i32 = {
|
|
1;
|
|
unsafe { $inside_unsafe }
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
},
|
|
const N: i32 = { $outside_unsafe },
|
|
>;
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! fn_with_const_generic {
|
|
($inside_unsafe:expr, $outside_unsafe:expr) => {
|
|
unsafe {
|
|
fn f<const N: usize>() {
|
|
$outside_unsafe;
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$inside_unsafe;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! variables {
|
|
($inside_unsafe:expr, $outside_unsafe:expr) => {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$inside_unsafe;
|
|
let inside_unsafe = 1;
|
|
inside_unsafe;
|
|
}
|
|
$outside_unsafe;
|
|
let outside_unsafe = 1;
|
|
outside_unsafe;
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! multiple_matchers {
|
|
($inside_unsafe:expr, $outside_unsafe:expr) => {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$inside_unsafe;
|
|
}
|
|
$outside_unsafe;
|
|
};
|
|
($($v:expr, $x:expr),+) => {
|
|
$(
|
|
$v;
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$x;
|
|
}
|
|
);+
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! multiple_unsafe_blocks {
|
|
($w:expr, $x:expr, $y:expr) => {
|
|
$w;
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$x;
|
|
}
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$x;
|
|
$y;
|
|
}
|
|
};
|
|
}
|
|
|
|
pub macro macro2_0($v:expr) {
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$v;
|
|
}
|
|
}
|
|
|
|
// don't lint private macros with the default configuration
|
|
macro_rules! private_mac {
|
|
($v:expr) => {
|
|
unsafe {
|
|
$v;
|
|
}
|
|
};
|
|
}
|
|
|
|
// don't lint exported macros that are doc(hidden) because they also aren't part of the public API
|
|
#[macro_export]
|
|
#[doc(hidden)]
|
|
macro_rules! exported_but_hidden {
|
|
($v:expr) => {
|
|
unsafe {
|
|
$v;
|
|
}
|
|
};
|
|
}
|
|
|
|
// don't lint if the same metavariable is expanded in an unsafe block and then outside of one:
|
|
// unsafe {} is still needed at callsite so not problematic
|
|
#[macro_export]
|
|
macro_rules! does_require_unsafe {
|
|
($v:expr) => {
|
|
unsafe {
|
|
$v;
|
|
}
|
|
$v;
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! unsafe_from_root_ctxt {
|
|
($v:expr) => {
|
|
// Expands to unsafe { 1 }, but the unsafe block is from the root ctxt and not this macro,
|
|
// so no warning.
|
|
$v;
|
|
};
|
|
}
|
|
|
|
// invoked from another macro, should still generate a warning
|
|
#[macro_export]
|
|
macro_rules! nested_macro_helper {
|
|
($v:expr) => {{
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
$v;
|
|
}
|
|
}};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! nested_macros {
|
|
($v:expr, $v2:expr) => {{
|
|
unsafe {
|
|
//~^ ERROR: this macro expands metavariables in an unsafe block
|
|
nested_macro_helper!($v);
|
|
$v;
|
|
}
|
|
}};
|
|
}
|
|
|
|
fn main() {
|
|
allow_works!(1);
|
|
simple!(1);
|
|
raw_symbol!(1, 1);
|
|
multilevel_unsafe!(1);
|
|
in_function!(1);
|
|
in_function_with_unsafe!(1);
|
|
const_static!(1, 1);
|
|
const_generic_in_struct!(1, 1);
|
|
fn_with_const_generic!(1, 1);
|
|
variables!(1, 1);
|
|
multiple_matchers!(1, 1);
|
|
multiple_matchers!(1, 1, 1, 1);
|
|
macro2_0!(1);
|
|
private_mac!(1);
|
|
exported_but_hidden!(1);
|
|
does_require_unsafe!(1);
|
|
multiple_unsafe_blocks!(1, 1, 1);
|
|
unsafe_from_root_ctxt!(unsafe { 1 });
|
|
nested_macros!(1, 1);
|
|
}
|