Auto merge of #53815 - F001:if-let-guard, r=petrochenkov
refactor match guard This is the first step to implement RFC 2294: if-let-guard. Tracking issue: https://github.com/rust-lang/rust/issues/51114 The second step should be introducing another variant `IfLet` in the Guard enum. I separated them into 2 PRs for the convenience of reviewers. r? @petrochenkov
This commit is contained in:
commit
28bcffead7
@ -488,8 +488,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||||||
// expression to target
|
// expression to target
|
||||||
let guard_start = self.add_dummy_node(&[pat_exit]);
|
let guard_start = self.add_dummy_node(&[pat_exit]);
|
||||||
// Visit the guard expression
|
// Visit the guard expression
|
||||||
let guard_exit = self.expr(&guard, guard_start);
|
let guard_exit = match guard {
|
||||||
|
hir::Guard::If(ref e) => self.expr(e, guard_start),
|
||||||
|
};
|
||||||
// #47295: We used to have very special case code
|
// #47295: We used to have very special case code
|
||||||
// here for when a pair of arms are both formed
|
// here for when a pair of arms are both formed
|
||||||
// solely from constants, and if so, not add these
|
// solely from constants, and if so, not add these
|
||||||
|
@ -1102,7 +1102,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
|||||||
|
|
||||||
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
||||||
walk_list!(visitor, visit_pat, &arm.pats);
|
walk_list!(visitor, visit_pat, &arm.pats);
|
||||||
walk_list!(visitor, visit_expr, &arm.guard);
|
if let Some(ref g) = arm.guard {
|
||||||
|
match g {
|
||||||
|
Guard::If(ref e) => visitor.visit_expr(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
visitor.visit_expr(&arm.body);
|
visitor.visit_expr(&arm.body);
|
||||||
walk_list!(visitor, visit_attribute, &arm.attrs);
|
walk_list!(visitor, visit_attribute, &arm.attrs);
|
||||||
}
|
}
|
||||||
|
@ -1054,7 +1054,10 @@ impl<'a> LoweringContext<'a> {
|
|||||||
hir::Arm {
|
hir::Arm {
|
||||||
attrs: self.lower_attrs(&arm.attrs),
|
attrs: self.lower_attrs(&arm.attrs),
|
||||||
pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
|
pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
|
||||||
guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))),
|
guard: match arm.guard {
|
||||||
|
Some(Guard::If(ref x)) => Some(hir::Guard::If(P(self.lower_expr(x)))),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
body: P(self.lower_expr(&arm.body)),
|
body: P(self.lower_expr(&arm.body)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1204,10 +1204,15 @@ impl DeclKind {
|
|||||||
pub struct Arm {
|
pub struct Arm {
|
||||||
pub attrs: HirVec<Attribute>,
|
pub attrs: HirVec<Attribute>,
|
||||||
pub pats: HirVec<P<Pat>>,
|
pub pats: HirVec<P<Pat>>,
|
||||||
pub guard: Option<P<Expr>>,
|
pub guard: Option<Guard>,
|
||||||
pub body: P<Expr>,
|
pub body: P<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
|
pub enum Guard {
|
||||||
|
If(P<Expr>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
|
@ -1949,11 +1949,15 @@ impl<'a> State<'a> {
|
|||||||
self.print_pat(&p)?;
|
self.print_pat(&p)?;
|
||||||
}
|
}
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
if let Some(ref e) = arm.guard {
|
if let Some(ref g) = arm.guard {
|
||||||
|
match g {
|
||||||
|
hir::Guard::If(e) => {
|
||||||
self.word_space("if")?;
|
self.word_space("if")?;
|
||||||
self.print_expr(&e)?;
|
self.print_expr(&e)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.word_space("=>")?;
|
self.word_space("=>")?;
|
||||||
|
|
||||||
match arm.body.node {
|
match arm.body.node {
|
||||||
|
@ -493,6 +493,10 @@ impl_stable_hash_for!(struct hir::Arm {
|
|||||||
body
|
body
|
||||||
});
|
});
|
||||||
|
|
||||||
|
impl_stable_hash_for!(enum hir::Guard {
|
||||||
|
If(expr),
|
||||||
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct hir::Field {
|
impl_stable_hash_for!(struct hir::Field {
|
||||||
id -> _,
|
id -> _,
|
||||||
ident,
|
ident,
|
||||||
|
@ -792,7 +792,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref guard) = arm.guard {
|
if let Some(ref guard) = arm.guard {
|
||||||
self.consume_expr(&guard);
|
match guard {
|
||||||
|
hir::Guard::If(ref e) => self.consume_expr(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.consume_expr(&arm.body);
|
self.consume_expr(&arm.body);
|
||||||
|
@ -1030,7 +1030,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
let body_succ =
|
let body_succ =
|
||||||
self.propagate_through_expr(&arm.body, succ);
|
self.propagate_through_expr(&arm.body, succ);
|
||||||
let guard_succ =
|
let guard_succ =
|
||||||
self.propagate_through_opt_expr(arm.guard.as_ref().map(|e| &**e), body_succ);
|
self.propagate_through_opt_expr(
|
||||||
|
arm.guard.as_ref().map(|g|
|
||||||
|
match g {
|
||||||
|
hir::Guard::If(e) => &**e,
|
||||||
|
}),
|
||||||
|
body_succ);
|
||||||
// only consider the first pattern; any later patterns must have
|
// only consider the first pattern; any later patterns must have
|
||||||
// the same bindings, and we also consider the first pattern to be
|
// the same bindings, and we also consider the first pattern to be
|
||||||
// the "authoritative" set of ids
|
// the "authoritative" set of ids
|
||||||
|
@ -885,8 +885,10 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
|
|||||||
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) {
|
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) {
|
||||||
visitor.terminating_scopes.insert(arm.body.hir_id.local_id);
|
visitor.terminating_scopes.insert(arm.body.hir_id.local_id);
|
||||||
|
|
||||||
if let Some(ref expr) = arm.guard {
|
if let Some(ref g) = arm.guard {
|
||||||
visitor.terminating_scopes.insert(expr.hir_id.local_id);
|
match g {
|
||||||
|
hir::Guard::If(ref expr) => visitor.terminating_scopes.insert(expr.hir_id.local_id),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
intravisit::walk_arm(visitor, arm);
|
intravisit::walk_arm(visitor, arm);
|
||||||
|
@ -453,7 +453,7 @@ pub struct Candidate<'pat, 'tcx:'pat> {
|
|||||||
bindings: Vec<Binding<'tcx>>,
|
bindings: Vec<Binding<'tcx>>,
|
||||||
|
|
||||||
// ...and the guard must be evaluated...
|
// ...and the guard must be evaluated...
|
||||||
guard: Option<ExprRef<'tcx>>,
|
guard: Option<Guard<'tcx>>,
|
||||||
|
|
||||||
// ...and then we branch to arm with this index.
|
// ...and then we branch to arm with this index.
|
||||||
arm_index: usize,
|
arm_index: usize,
|
||||||
@ -998,7 +998,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// the block to branch to if the guard fails; if there is no
|
// the block to branch to if the guard fails; if there is no
|
||||||
// guard, this block is simply unreachable
|
// guard, this block is simply unreachable
|
||||||
let guard = self.hir.mirror(guard);
|
let guard = match guard {
|
||||||
|
Guard::If(e) => self.hir.mirror(e),
|
||||||
|
};
|
||||||
let source_info = self.source_info(guard.span);
|
let source_info = self.source_info(guard.span);
|
||||||
let cond = unpack!(block = self.as_local_operand(block, guard));
|
let cond = unpack!(block = self.as_local_operand(block, guard));
|
||||||
if autoref {
|
if autoref {
|
||||||
|
@ -837,7 +837,10 @@ impl ToBorrowKind for hir::Mutability {
|
|||||||
fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
|
fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
|
||||||
Arm {
|
Arm {
|
||||||
patterns: arm.pats.iter().map(|p| cx.pattern_from_hir(p)).collect(),
|
patterns: arm.pats.iter().map(|p| cx.pattern_from_hir(p)).collect(),
|
||||||
guard: arm.guard.to_ref(),
|
guard: match arm.guard {
|
||||||
|
Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
body: arm.body.to_ref(),
|
body: arm.body.to_ref(),
|
||||||
// BUG: fix this
|
// BUG: fix this
|
||||||
lint_level: LintLevel::Inherited,
|
lint_level: LintLevel::Inherited,
|
||||||
|
@ -316,11 +316,16 @@ pub struct FruInfo<'tcx> {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Arm<'tcx> {
|
pub struct Arm<'tcx> {
|
||||||
pub patterns: Vec<Pattern<'tcx>>,
|
pub patterns: Vec<Pattern<'tcx>>,
|
||||||
pub guard: Option<ExprRef<'tcx>>,
|
pub guard: Option<Guard<'tcx>>,
|
||||||
pub body: ExprRef<'tcx>,
|
pub body: ExprRef<'tcx>,
|
||||||
pub lint_level: LintLevel,
|
pub lint_level: LintLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum Guard<'tcx> {
|
||||||
|
If(ExprRef<'tcx>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum LogicalOp {
|
pub enum LogicalOp {
|
||||||
And,
|
And,
|
||||||
|
@ -208,7 +208,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
(pattern, &**pat)
|
(pattern, &**pat)
|
||||||
}).collect(),
|
}).collect(),
|
||||||
arm.guard.as_ref().map(|e| &**e)
|
arm.guard.as_ref().map(|g| match g {
|
||||||
|
hir::Guard::If(ref e) => &**e,
|
||||||
|
})
|
||||||
)).collect();
|
)).collect();
|
||||||
|
|
||||||
// Bail out early if inlining failed.
|
// Bail out early if inlining failed.
|
||||||
@ -575,12 +577,19 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
|
|||||||
/// assign.
|
/// assign.
|
||||||
///
|
///
|
||||||
/// FIXME: this should be done by borrowck.
|
/// FIXME: this should be done by borrowck.
|
||||||
fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
|
fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Guard) {
|
||||||
let mut checker = MutationChecker {
|
let mut checker = MutationChecker {
|
||||||
cx,
|
cx,
|
||||||
};
|
};
|
||||||
ExprUseVisitor::new(&mut checker, cx.tcx, cx.param_env, cx.region_scope_tree, cx.tables, None)
|
match guard {
|
||||||
.walk_expr(guard);
|
hir::Guard::If(expr) =>
|
||||||
|
ExprUseVisitor::new(&mut checker,
|
||||||
|
cx.tcx,
|
||||||
|
cx.param_env,
|
||||||
|
cx.region_scope_tree,
|
||||||
|
cx.tables,
|
||||||
|
None).walk_expr(expr),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MutationChecker<'a, 'tcx: 'a> {
|
struct MutationChecker<'a, 'tcx: 'a> {
|
||||||
|
@ -577,7 +577,7 @@ fn check_expr_kind<'a, 'tcx>(
|
|||||||
for index in hirvec_arm.iter() {
|
for index in hirvec_arm.iter() {
|
||||||
let _ = v.check_expr(&*index.body);
|
let _ = v.check_expr(&*index.body);
|
||||||
match index.guard {
|
match index.guard {
|
||||||
Some(ref expr) => {
|
Some(hir::Guard::If(ref expr)) => {
|
||||||
let _ = v.check_expr(&expr);
|
let _ = v.check_expr(&expr);
|
||||||
},
|
},
|
||||||
None => {},
|
None => {},
|
||||||
|
@ -2701,7 +2701,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||||||
// This has to happen *after* we determine which pat_idents are variants
|
// This has to happen *after* we determine which pat_idents are variants
|
||||||
self.check_consistent_bindings(&arm.pats);
|
self.check_consistent_bindings(&arm.pats);
|
||||||
|
|
||||||
walk_list!(self, visit_expr, &arm.guard);
|
match arm.guard {
|
||||||
|
Some(ast::Guard::If(ref expr)) => self.visit_expr(expr),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
self.visit_expr(&arm.body);
|
self.visit_expr(&arm.body);
|
||||||
|
|
||||||
self.ribs[ValueNS].pop();
|
self.ribs[ValueNS].pop();
|
||||||
|
@ -1663,7 +1663,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
|||||||
|
|
||||||
fn visit_arm(&mut self, arm: &'l ast::Arm) {
|
fn visit_arm(&mut self, arm: &'l ast::Arm) {
|
||||||
self.process_var_decl_multi(&arm.pats);
|
self.process_var_decl_multi(&arm.pats);
|
||||||
walk_list!(self, visit_expr, &arm.guard);
|
match arm.guard {
|
||||||
|
Some(ast::Guard::If(ref expr)) => self.visit_expr(expr),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
self.visit_expr(&arm.body);
|
self.visit_expr(&arm.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,9 +663,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
|
for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
|
||||||
if let Some(ref e) = arm.guard {
|
if let Some(ref g) = arm.guard {
|
||||||
self.diverges.set(pats_diverge);
|
self.diverges.set(pats_diverge);
|
||||||
self.check_expr_has_type_or_error(e, tcx.types.bool);
|
match g {
|
||||||
|
hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
self.diverges.set(pats_diverge);
|
self.diverges.set(pats_diverge);
|
||||||
|
@ -857,10 +857,15 @@ pub struct Local {
|
|||||||
pub struct Arm {
|
pub struct Arm {
|
||||||
pub attrs: Vec<Attribute>,
|
pub attrs: Vec<Attribute>,
|
||||||
pub pats: Vec<P<Pat>>,
|
pub pats: Vec<P<Pat>>,
|
||||||
pub guard: Option<P<Expr>>,
|
pub guard: Option<Guard>,
|
||||||
pub body: P<Expr>,
|
pub body: P<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
|
pub enum Guard {
|
||||||
|
If(P<Expr>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
pub ident: Ident,
|
pub ident: Ident,
|
||||||
|
@ -118,6 +118,10 @@ pub trait Folder : Sized {
|
|||||||
noop_fold_arm(a, self)
|
noop_fold_arm(a, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_guard(&mut self, g: Guard) -> Guard {
|
||||||
|
noop_fold_guard(g, self)
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_pat(&mut self, p: P<Pat>) -> P<Pat> {
|
fn fold_pat(&mut self, p: P<Pat>) -> P<Pat> {
|
||||||
noop_fold_pat(p, self)
|
noop_fold_pat(p, self)
|
||||||
}
|
}
|
||||||
@ -354,11 +358,17 @@ pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm,
|
|||||||
Arm {
|
Arm {
|
||||||
attrs: fold_attrs(attrs, fld),
|
attrs: fold_attrs(attrs, fld),
|
||||||
pats: pats.move_map(|x| fld.fold_pat(x)),
|
pats: pats.move_map(|x| fld.fold_pat(x)),
|
||||||
guard: guard.map(|x| fld.fold_expr(x)),
|
guard: guard.map(|x| fld.fold_guard(x)),
|
||||||
body: fld.fold_expr(body),
|
body: fld.fold_expr(body),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn noop_fold_guard<T: Folder>(g: Guard, fld: &mut T) -> Guard {
|
||||||
|
match g {
|
||||||
|
Guard::If(e) => Guard::If(fld.fold_expr(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding {
|
pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding {
|
||||||
TypeBinding {
|
TypeBinding {
|
||||||
id: fld.new_id(b.id),
|
id: fld.new_id(b.id),
|
||||||
|
@ -12,7 +12,7 @@ use rustc_target::spec::abi::{self, Abi};
|
|||||||
use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy};
|
use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy};
|
||||||
use ast::{GenericBound, TraitBoundModifier};
|
use ast::{GenericBound, TraitBoundModifier};
|
||||||
use ast::Unsafety;
|
use ast::Unsafety;
|
||||||
use ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind};
|
use ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind};
|
||||||
use ast::Block;
|
use ast::Block;
|
||||||
use ast::{BlockCheckMode, CaptureBy, Movability};
|
use ast::{BlockCheckMode, CaptureBy, Movability};
|
||||||
use ast::{Constness, Crate};
|
use ast::{Constness, Crate};
|
||||||
@ -3533,7 +3533,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.eat(&token::BinOp(token::Or));
|
self.eat(&token::BinOp(token::Or));
|
||||||
let pats = self.parse_pats()?;
|
let pats = self.parse_pats()?;
|
||||||
let guard = if self.eat_keyword(keywords::If) {
|
let guard = if self.eat_keyword(keywords::If) {
|
||||||
Some(self.parse_expr()?)
|
Some(Guard::If(self.parse_expr()?))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -2702,11 +2702,15 @@ impl<'a> State<'a> {
|
|||||||
self.print_outer_attributes(&arm.attrs)?;
|
self.print_outer_attributes(&arm.attrs)?;
|
||||||
self.print_pats(&arm.pats)?;
|
self.print_pats(&arm.pats)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
if let Some(ref e) = arm.guard {
|
if let Some(ref g) = arm.guard {
|
||||||
|
match g {
|
||||||
|
ast::Guard::If(ref e) => {
|
||||||
self.word_space("if")?;
|
self.word_space("if")?;
|
||||||
self.print_expr(e)?;
|
self.print_expr(e)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.word_space("=>")?;
|
self.word_space("=>")?;
|
||||||
|
|
||||||
match arm.body.node {
|
match arm.body.node {
|
||||||
|
@ -819,7 +819,11 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
|||||||
|
|
||||||
pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
|
pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
|
||||||
walk_list!(visitor, visit_pat, &arm.pats);
|
walk_list!(visitor, visit_pat, &arm.pats);
|
||||||
walk_list!(visitor, visit_expr, &arm.guard);
|
if let Some(ref g) = &arm.guard {
|
||||||
|
match g {
|
||||||
|
Guard::If(ref e) => visitor.visit_expr(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
visitor.visit_expr(&arm.body);
|
visitor.visit_expr(&arm.body);
|
||||||
walk_list!(visitor, visit_attribute, &arm.attrs);
|
walk_list!(visitor, visit_attribute, &arm.attrs);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user