mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
181 lines
4.4 KiB
Rust
181 lines
4.4 KiB
Rust
//@aux-build:proc_macros.rs
|
|
//@aux-build:proc_macro_derive.rs
|
|
//@aux-build:macro_rules.rs
|
|
#![warn(clippy::double_parens)]
|
|
#![expect(clippy::eq_op, clippy::no_effect)]
|
|
#![feature(custom_inner_attributes)]
|
|
#![rustfmt::skip]
|
|
|
|
use proc_macros::{external, with_span};
|
|
|
|
fn dummy_fn<T>(_: T) {}
|
|
|
|
struct DummyStruct;
|
|
|
|
impl DummyStruct {
|
|
fn dummy_method<T>(&self, _: T) {}
|
|
}
|
|
|
|
fn simple_double_parens() -> i32 {
|
|
(0)
|
|
//~^ double_parens
|
|
}
|
|
|
|
fn fn_double_parens() {
|
|
dummy_fn(0);
|
|
//~^ double_parens
|
|
}
|
|
|
|
fn method_double_parens(x: DummyStruct) {
|
|
x.dummy_method(0);
|
|
//~^ double_parens
|
|
}
|
|
|
|
fn tuple_double_parens() -> (i32, i32) {
|
|
(1, 2)
|
|
//~^ double_parens
|
|
}
|
|
|
|
#[allow(clippy::unused_unit)]
|
|
fn unit_double_parens() {
|
|
()
|
|
//~^ double_parens
|
|
}
|
|
|
|
fn fn_tuple_ok() {
|
|
dummy_fn((1, 2));
|
|
}
|
|
|
|
fn method_tuple_ok(x: DummyStruct) {
|
|
x.dummy_method((1, 2));
|
|
}
|
|
|
|
fn fn_unit_ok() {
|
|
dummy_fn(());
|
|
}
|
|
|
|
fn method_unit_ok(x: DummyStruct) {
|
|
x.dummy_method(());
|
|
}
|
|
|
|
// Issue #3206
|
|
fn inside_macro() {
|
|
assert_eq!((1, 2), (1, 2), "Error");
|
|
assert_eq!((1, 2), (1, 2), "Error");
|
|
//~^ double_parens
|
|
}
|
|
|
|
fn issue9000(x: DummyStruct) {
|
|
macro_rules! foo {
|
|
() => {(100)}
|
|
}
|
|
// don't lint: the inner paren comes from the macro expansion
|
|
(foo!());
|
|
dummy_fn(foo!());
|
|
x.dummy_method(foo!());
|
|
|
|
macro_rules! baz {
|
|
($n:literal) => {($n)}
|
|
}
|
|
// don't lint: don't get confused by the expression inside the inner paren
|
|
// having the same `ctxt` as the overall expression
|
|
// (this is a bug that happened during the development of the fix)
|
|
(baz!(100));
|
|
dummy_fn(baz!(100));
|
|
x.dummy_method(baz!(100));
|
|
|
|
// should lint: both parens are from inside the macro
|
|
macro_rules! bar {
|
|
() => {(100)}
|
|
//~^ double_parens
|
|
}
|
|
bar!();
|
|
|
|
// should lint: both parens are from outside the macro;
|
|
// make sure to suggest the macro unexpanded
|
|
(vec![1, 2]);
|
|
//~^ double_parens
|
|
dummy_fn(vec![1, 2]);
|
|
//~^ double_parens
|
|
x.dummy_method(vec![1, 2]);
|
|
//~^ double_parens
|
|
}
|
|
|
|
fn issue15892() {
|
|
use macro_rules::double_parens as double_parens_external;
|
|
|
|
macro_rules! double_parens{
|
|
($a:expr, $b:expr, $c:expr, $d:expr) => {{
|
|
let a = ($a);
|
|
let a = ();
|
|
//~^ double_parens
|
|
let b = (5);
|
|
//~^ double_parens
|
|
let c = std::convert::identity(5);
|
|
//~^ double_parens
|
|
InterruptMask((($a.union($b).union($c).union($d)).into_bits()) as u32)
|
|
}};
|
|
}
|
|
|
|
// Don't lint: external macro
|
|
(external!((5)));
|
|
external!(((5)));
|
|
|
|
#[repr(transparent)]
|
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
|
pub struct InterruptMask(u32);
|
|
|
|
impl InterruptMask {
|
|
pub const OE: InterruptMask = InterruptMask(1 << 10);
|
|
pub const BE: InterruptMask = InterruptMask(1 << 9);
|
|
pub const PE: InterruptMask = InterruptMask(1 << 8);
|
|
pub const FE: InterruptMask = InterruptMask(1 << 7);
|
|
// Lint: internal macro
|
|
pub const E: InterruptMask = double_parens!((Self::OE), Self::BE, Self::PE, Self::FE);
|
|
// Don't lint: external macro
|
|
pub const F: InterruptMask = double_parens_external!((Self::OE), Self::BE, Self::PE, Self::FE);
|
|
#[allow(clippy::unnecessary_cast)]
|
|
pub const G: InterruptMask = external!(
|
|
InterruptMask((((Self::OE.union(Self::BE).union(Self::PE).union(Self::FE))).into_bits()) as u32)
|
|
);
|
|
#[allow(clippy::unnecessary_cast)]
|
|
// Don't lint: external proc-macro
|
|
pub const H: InterruptMask = with_span!(span
|
|
InterruptMask((((Self::OE.union(Self::BE).union(Self::PE).union(Self::FE))).into_bits()) as u32)
|
|
);
|
|
pub const fn into_bits(self) -> u32 {
|
|
self.0
|
|
}
|
|
#[must_use]
|
|
pub const fn union(self, rhs: Self) -> Self {
|
|
InterruptMask(self.0 | rhs.0)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn issue15940() {
|
|
use proc_macro_derive::DoubleParens;
|
|
|
|
#[derive(DoubleParens)]
|
|
// Don't lint: external derive macro
|
|
pub struct Person;
|
|
}
|
|
|
|
fn issue16224() {
|
|
fn test() -> i32 { 42 }
|
|
|
|
macro_rules! call {
|
|
($matcher:pat $(=> $result:expr)?) => {
|
|
match test() {
|
|
$matcher => Result::Ok(($($result),*)),
|
|
_ => Result::Err("No match".to_string()),
|
|
}
|
|
};
|
|
}
|
|
|
|
let _: Result<(), String> = call!(_);
|
|
let _: Result<i32, String> = call!(_ => 42);
|
|
}
|
|
|
|
fn main() {}
|