首页 文章

尝试在宏扩展中实现特征时出现宏错误

提问于
浏览
0

fn a() {} 似乎满足了预期 fn 的解析规则,然后是其他一些东西 . item 应该可以是函数定义,对吗?所以他们应该工作,对吗?

macro_rules! multi_impl {
    (for $base:ty :
        $($t:ty {
            $($i:item);*
        }),+) =>
    {
        $(
            impl $t for $base
            {
                $( $i )*
            }
        )+
    }
}

trait A {
    fn a();
}

trait B {
    fn b();
}

struct S;

multi_impl! {
    for S:
    A {
        fn a() {}
    }, B {
        fn b() {}
    }
}

fn main() {
    S::a();
    S::b();
}

playground

有问题的错误:

error: expected one of `const`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `fn a() { }`
  --> <anon>:11:20
   |
11 |                 $( $i )*
   |                    ^^

使它 $( fn $i)* 只改变错误以抱怨在 fn 之后期望一个标识符,这是有道理的,但是初始错误没有(至少对我来说) .

解析器中有关源代码中的代码与宏放入源代码的代码是否存在差异?

1 回答

  • 3

    问题不在于 impl 的主体不包含项目 . 它包含"impl items" . 它抱怨的是你试图将一个方形块放入一个圆孔中,而不是该块是错误的颜色 .

    是的,这是两件不同的事情 . 不,你无法在宏中捕获"impl items" . 不,您无法将项目转换为impl项目 . 因为宏捕获AST节点,而不是令牌 . 好吧,方法可以有一个 self 参数和常规函数's don't . 我不知道,大概当时这似乎是一个好主意 .

    把假设来回放在一边,在这种情况下的解决方案是不打扰尝试匹配任何特定的东西,只是匹配任何东西 .

    macro_rules! multi_impl
    {
        (for $base:ty :
            $($t:ty {
                $($body:tt)*
            }),+) =>
        {
            $(
                impl $t for $base
                {
                    $($body)*
                }
            )+
        }
    }
    

相关问题