如何在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
相关产品推荐
相关产品推荐

