如何从ConstVal中获取元组?

时间:2015-11-27 15:06:55

标签: plugins rust internals

使用当前的夜魇,可以使用rustc::middle::const_eval_partial(..)获得Result<ConstVal, _>。但是,ConstVal对于元组值是Tuple { node: NodeId }。我怎样才能获得这个元组的内容?

示例代码(这里是用作编译器插件的最小lint):

use rustc::lint::*;
use syntax::ptr::P;
use rustc_front::hir::*;
use rustc::middle::const_eval::ConstVal::Tuple;
use rustc::middle::const_eval::eval_const_expr_partial;
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;

declare_lint! { pub TEST_LINT, Warn, "Just a test, ignore this" }

#[derive(Copy,Clone)]
pub struct TestLint;

impl LintPass for TestLint {
    fn get_lints(&self) -> LintArray {
        lint_array!TEST_LINT)
    }
}

impl LateLintPass for BitMask {
    fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
        let res = eval_const_expr_partial(cx.tcx, expr, ExprTypeChecked, None);
        if let Ok(Tuple(node_id))) = res {
            // ... how to get the parts of the tuple?
        }
    }
}

1 个答案:

答案 0 :(得分:2)

如果你看一下ExprTupField表达式的常量评估代码(索引到元组),你可以看到如何提取特定的字段:

if let hir::ExprTup(ref fields) = tcx.map.expect_expr(tup_id).node {
    if index.node < fields.len() {
        return eval_const_expr_partial(tcx, &fields[index.node], base_hint, fn_args)
    } else {
        signal!(e, TupleIndexOutOfBounds);
    }
} else {
    unreachable!()
}

fieldsVec<P<Expr>>。因此,您可以迭代Vec并在其上调用eval_const_expr_partial以获取元组字段的ConstVal

请注意,如果在const fn中创建了元组,则会遇到麻烦:https://github.com/rust-lang/rust/issues/29928