mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
[WIP] Create a Visitor
for the THIR
This commit is contained in:
parent
506e75cbf8
commit
d956122f7e
@ -29,6 +29,7 @@ mod arena;
|
|||||||
pub use arena::Arena;
|
pub use arena::Arena;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
|
pub mod visit;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum LintLevel {
|
pub enum LintLevel {
|
||||||
|
178
compiler/rustc_mir_build/src/thir/visit.rs
Normal file
178
compiler/rustc_mir_build/src/thir/visit.rs
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
use crate::thir::*;
|
||||||
|
|
||||||
|
pub trait Visitor<'thir, 'tcx>: Sized {
|
||||||
|
fn visit_expr(&mut self, expr: &'thir Expr<'thir, 'tcx>) {
|
||||||
|
walk_expr(self, expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_stmt(&mut self, stmt: &'thir Stmt<'thir, 'tcx>) {
|
||||||
|
walk_stmt(self, stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_block(&mut self, block: &Block<'thir, 'tcx>) {
|
||||||
|
walk_block(self, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_arm(&mut self, arm: &'thir Arm<'thir, 'tcx>) {
|
||||||
|
walk_arm(self, arm);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_expr<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||||
|
visitor: &mut V,
|
||||||
|
expr: &'thir Expr<'thir, 'tcx>,
|
||||||
|
) {
|
||||||
|
use ExprKind::*;
|
||||||
|
match expr.kind {
|
||||||
|
Scope { value, .. } => visitor.visit_expr(value),
|
||||||
|
Box { value } => visitor.visit_expr(value),
|
||||||
|
If { cond, then, else_opt } => {
|
||||||
|
visitor.visit_expr(cond);
|
||||||
|
visitor.visit_expr(then);
|
||||||
|
if let Some(else_expr) = else_opt {
|
||||||
|
visitor.visit_expr(else_expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Call { fun, args, .. } => {
|
||||||
|
visitor.visit_expr(fun);
|
||||||
|
for arg in args {
|
||||||
|
visitor.visit_expr(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Deref { arg } => visitor.visit_expr(arg),
|
||||||
|
Binary { lhs, rhs, .. } | LogicalOp { lhs, rhs, .. } => {
|
||||||
|
visitor.visit_expr(lhs);
|
||||||
|
visitor.visit_expr(rhs);
|
||||||
|
}
|
||||||
|
Unary { arg, .. } => visitor.visit_expr(arg),
|
||||||
|
Cast { source } => visitor.visit_expr(source),
|
||||||
|
Use { source } => visitor.visit_expr(source),
|
||||||
|
NeverToAny { source } => visitor.visit_expr(source),
|
||||||
|
Pointer { source, .. } => visitor.visit_expr(source),
|
||||||
|
Loop { body } => visitor.visit_expr(body),
|
||||||
|
Match { scrutinee, arms } => {
|
||||||
|
visitor.visit_expr(scrutinee);
|
||||||
|
for arm in arms {
|
||||||
|
visitor.visit_arm(arm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Block { ref body } => visitor.visit_block(body),
|
||||||
|
Assign { lhs, rhs } | AssignOp { lhs, rhs, .. } => {
|
||||||
|
visitor.visit_expr(lhs);
|
||||||
|
visitor.visit_expr(rhs);
|
||||||
|
}
|
||||||
|
Field { lhs, .. } => visitor.visit_expr(lhs),
|
||||||
|
Index { lhs, index } => {
|
||||||
|
visitor.visit_expr(lhs);
|
||||||
|
visitor.visit_expr(index);
|
||||||
|
}
|
||||||
|
VarRef { .. } | UpvarRef { .. } => {}
|
||||||
|
Borrow { arg, .. } => visitor.visit_expr(arg),
|
||||||
|
AddressOf { arg, .. } => visitor.visit_expr(arg),
|
||||||
|
Break { value, .. } => {
|
||||||
|
if let Some(value) = value {
|
||||||
|
visitor.visit_expr(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Continue { .. } => {}
|
||||||
|
Return { value } => {
|
||||||
|
if let Some(value) = value {
|
||||||
|
visitor.visit_expr(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ConstBlock { value } => visitor.visit_const(value),
|
||||||
|
Repeat { value, count } => {
|
||||||
|
visitor.visit_expr(value);
|
||||||
|
visitor.visit_const(count);
|
||||||
|
}
|
||||||
|
Array { fields } | Tuple { fields } => {
|
||||||
|
for field in fields {
|
||||||
|
visitor.visit_expr(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Adt { fields, ref base, .. } => {
|
||||||
|
for field in fields {
|
||||||
|
visitor.visit_expr(field.expr);
|
||||||
|
}
|
||||||
|
if let Some(base) = base {
|
||||||
|
visitor.visit_expr(base.base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlaceTypeAscription { source, .. } | ValueTypeAscription { source, .. } => {
|
||||||
|
visitor.visit_expr(source)
|
||||||
|
}
|
||||||
|
Closure { .. } => {}
|
||||||
|
Literal { literal, .. } => visitor.visit_const(literal),
|
||||||
|
StaticRef { literal, .. } => visitor.visit_const(literal),
|
||||||
|
InlineAsm { operands, .. } => {
|
||||||
|
for op in operands {
|
||||||
|
use InlineAsmOperand::*;
|
||||||
|
match op {
|
||||||
|
In { expr, .. }
|
||||||
|
| Out { expr: Some(expr), .. }
|
||||||
|
| InOut { expr, .. }
|
||||||
|
| SymFn { expr } => visitor.visit_expr(expr),
|
||||||
|
SplitInOut { in_expr, out_expr, .. } => {
|
||||||
|
visitor.visit_expr(in_expr);
|
||||||
|
if let Some(out_expr) = out_expr {
|
||||||
|
visitor.visit_expr(out_expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Out { .. } | Const { .. } | SymStatic { .. } => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadLocalRef(_) => {}
|
||||||
|
LlvmInlineAsm { outputs, inputs, .. } => {
|
||||||
|
for out_expr in outputs {
|
||||||
|
visitor.visit_expr(out_expr);
|
||||||
|
}
|
||||||
|
for in_expr in inputs {
|
||||||
|
visitor.visit_expr(in_expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Yield { value } => visitor.visit_expr(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_stmt<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||||
|
visitor: &mut V,
|
||||||
|
stmt: &'thir Stmt<'thir, 'tcx>,
|
||||||
|
) {
|
||||||
|
match stmt.kind {
|
||||||
|
StmtKind::Expr { expr, .. } => visitor.visit_expr(expr),
|
||||||
|
StmtKind::Let { pattern: _, initializer, .. } => {
|
||||||
|
if let Some(init) = initializer {
|
||||||
|
visitor.visit_expr(init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_block<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||||
|
visitor: &mut V,
|
||||||
|
block: &Block<'thir, 'tcx>,
|
||||||
|
) {
|
||||||
|
for stmt in block.stmts {
|
||||||
|
visitor.visit_stmt(stmt);
|
||||||
|
}
|
||||||
|
if let Some(expr) = block.expr {
|
||||||
|
visitor.visit_expr(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_arm<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||||
|
visitor: &mut V,
|
||||||
|
arm: &'thir Arm<'thir, 'tcx>,
|
||||||
|
) {
|
||||||
|
match arm.guard {
|
||||||
|
Some(Guard::If(expr)) => visitor.visit_expr(expr),
|
||||||
|
Some(Guard::IfLet(ref _pat, expr)) => {
|
||||||
|
visitor.visit_expr(expr);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
visitor.visit_expr(arm.body);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user