You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在rustc_ast中匹配TokenStream识别dead_code属性?

问题描述

我正在使用rustc_ast::tokenstream::TokenStream,控制台打印的TokenStream内容如下:

Contents of value2.tokens: TokenStream(
    [
        Token(
            Token {
                kind: Ident(
                    "dead_code",
                    false,
                ),
                span: src/main.rs:12:9: 12:18 (#0),
            },
            Alone,
        ),
    ],
)

我需要匹配该TokenStream,确保处理的是dead_code属性符号而非其他符号。以下是我处理AST并尝试匹配TokenStream的代码,标注位置匹配失败:

for attr in tcx.get_attrs(item.owner_id.to_def_id(), sym::allow) {
    println!("Print attributes: {:#?}", attr);
    if let AttrKind::Normal(value) = &attr.kind {
        if let AttrArgs::Delimited(value2) = &value.item.args {
            if let value3 = &value2.tokens {
                println!("Contents of value2.tokens: {:#?}", value3);
                match value3 {
                    [a] => { // 此处匹配不正确,该如何正确匹配?
                        println!("hi, {}", a)
                    }
                }
            }
        }
    }
}

我尝试按元组、枚举、列表匹配TokenStream内部结构均失败,始终存在类型不匹配问题。尝试使用指定解析器也因复杂度太高未能成功,请问如何匹配作为抽象令牌序列的TokenStream?

解决方案

rustc_ast::tokenstream::TokenStream是封装令牌序列的结构体,不能直接用数组模式匹配。要正确匹配内部令牌,需借助它提供的迭代器方法,或转换为令牌列表后处理:

方法1:转换为令牌Vec后匹配

先把TokenStream转成Vec<TokenTree>(TokenStream内部元素是TokenTree枚举,打印内容里的Token(...)是其变体之一),再进行精准匹配:

for attr in tcx.get_attrs(item.owner_id.to_def_id(), sym::allow) {
    println!("Print attributes: {:#?}", attr);
    if let AttrKind::Normal(value) = &attr.kind {
        if let AttrArgs::Delimited(value2) = &value.item.args {
            let tokens: Vec<_> = value2.tokens.clone().into_iter().collect();
            match tokens.as_slice() {
                [TokenTree::Token(token, Alone)] => {
                    if let TokenKind::Ident(ident, _) = &token.kind {
                        if ident.name == sym::dead_code {
                            println!("匹配到dead_code属性");
                            // 此处添加你的业务处理逻辑
                        }
                    }
                }
                _ => {}
            }
        }
    }
}

方法2:直接遍历TokenStream迭代器

如果不需要严格匹配单令牌场景,可直接遍历迭代器筛选目标令牌:

for attr in tcx.get_attrs(item.owner_id.to_def_id(), sym::allow) {
    println!("Print attributes: {:#?}", attr);
    if let AttrKind::Normal(value) = &attr.kind {
        if let AttrArgs::Delimited(value2) = &value.item.args {
            for tree in value2.tokens.clone() {
                if let TokenTree::Token(token, Alone) = tree {
                    if let TokenKind::Ident(ident, _) = token.kind {
                        if ident.name == sym::dead_code {
                            println!("匹配到dead_code属性");
                            // 此处添加你的业务处理逻辑
                        }
                    }
                }
            }
        }
    }
}

关键说明

  • TokenStream的into_iter()方法返回TokenTree迭代器,该枚举包含Token和Delimited两个核心变体
  • 匹配Ident类型令牌时,需先解构TokenTree::Token,再进一步解构TokenKind::Ident
  • 使用rustc内部符号常量sym::dead_code比直接字符串匹配更可靠,能避免拼写错误

内容的提问来源于stack exchange,提问作者Natasha Klaus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:45:16