为什么编译器不自动在声明性宏中添加双括号?

Why does the compiler not adds double brackets in a declarative macro automatically?

在声明性宏中创建标识符时,必须在宏中放置额外的括号(双括号)。我想知道为什么编译器不只是(总是)添加额外的括号。

示例 1:此代码将无法编译,因为在强制使用双括号的地方只使用了单括号:

macro_rules! some_macro {
    () => {
        let mut x = 1;

        x += 1;

        x
    };
}

fn main() {
    let y = some_macro!();
}

添加双括号解决了编译错误。

示例 2:无论使用单括号还是双括号,这段代码都能编译通过:

macro_rules! some_macro {
    () => {{
        1
    }};
}

fn main() {
    let y = some_macro!();
}

是否存在双括号宏会破坏单括号宏的情况?如果不是,为什么编译器不总是添加双括号?

有时双括号会失败。由于内部大括号创建了一个范围,如果你想声明任何标识符,它们将不会被“导出”:

// compiles with single braces but not double braces
macro_rules! set_ident_to_1 {
    ($var: ident) => {
        let $var = 1;
    }
}

fn main() {
    set_ident_to_1!(foo);
    println!("{}", foo);
}

也可能存在不允许直接使用大括号的情况,例如顶级定义。以这个创建重复 Deref 实现的宏为例:

struct Foo {
    x: i32
}

struct Bar {
    y: u32
}

// compiles with single braces but not double braces
macro_rules! create_repetitive_impl {
    ($prop: ident, $typ: ty, $target: ty) => {
        impl std::ops::Deref for $typ {
            type Target = $target;
            
            fn deref(&self) -> &Self::Target {
                &self.$prop
            }
        }
    }
}

create_repetitive_impl!(x, Foo, i32);
create_repetitive_impl!(y, Bar, u32);

fn main() {
    println!("{:?}", Foo {x: 5}.checked_mul(6))
}