mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Remove thir::Guard
Use Expr instead. Use `ExprKind::Let` to represent if let guards.
This commit is contained in:
parent
407cb24142
commit
a549711f6e
@ -519,20 +519,13 @@ pub struct FruInfo<'tcx> {
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct Arm<'tcx> {
|
||||
pub pattern: Box<Pat<'tcx>>,
|
||||
pub guard: Option<Guard<'tcx>>,
|
||||
pub guard: Option<ExprId>,
|
||||
pub body: ExprId,
|
||||
pub lint_level: LintLevel,
|
||||
pub scope: region::Scope,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// A `match` guard.
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub enum Guard<'tcx> {
|
||||
If(ExprId),
|
||||
IfLet(Box<Pat<'tcx>>, ExprId),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub enum LogicalOp {
|
||||
/// The `&&` operator.
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, Guard, InlineAsmExpr, InlineAsmOperand, Pat,
|
||||
AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, InlineAsmExpr, InlineAsmOperand, Pat,
|
||||
PatKind, Stmt, StmtKind, Thir,
|
||||
};
|
||||
|
||||
@ -213,13 +213,8 @@ pub fn walk_arm<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
|
||||
visitor: &mut V,
|
||||
arm: &'thir Arm<'tcx>,
|
||||
) {
|
||||
match arm.guard {
|
||||
Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]),
|
||||
Some(Guard::IfLet(ref pat, expr)) => {
|
||||
visitor.visit_pat(pat);
|
||||
visitor.visit_expr(&visitor.thir()[expr]);
|
||||
}
|
||||
None => {}
|
||||
if let Some(expr) = arm.guard {
|
||||
visitor.visit_expr(&visitor.thir()[expr])
|
||||
}
|
||||
visitor.visit_pat(&arm.pattern);
|
||||
visitor.visit_expr(&visitor.thir()[arm.body]);
|
||||
|
@ -425,7 +425,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
None,
|
||||
arm.span,
|
||||
&arm.pattern,
|
||||
arm.guard.as_ref(),
|
||||
arm.guard,
|
||||
opt_scrutinee_place,
|
||||
);
|
||||
|
||||
@ -717,7 +717,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
mut visibility_scope: Option<SourceScope>,
|
||||
scope_span: Span,
|
||||
pattern: &Pat<'tcx>,
|
||||
guard: Option<&Guard<'tcx>>,
|
||||
guard: Option<ExprId>,
|
||||
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
|
||||
) -> Option<SourceScope> {
|
||||
self.visit_primary_bindings(
|
||||
@ -745,7 +745,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
);
|
||||
},
|
||||
);
|
||||
if let Some(&Guard::If(guard_expr)) = guard {
|
||||
if let Some(guard_expr) = guard {
|
||||
self.declare_guard_bindings(guard_expr, scope_span, visibility_scope);
|
||||
}
|
||||
visibility_scope
|
||||
@ -2044,7 +2044,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// * So we eagerly create the reference for the arm and then take a
|
||||
// reference to that.
|
||||
if let Some((arm, match_scope)) = arm_match_scope
|
||||
&& let Some(guard) = &arm.guard
|
||||
&& let Some(guard) = arm.guard
|
||||
{
|
||||
let tcx = self.tcx;
|
||||
let bindings = parent_bindings
|
||||
@ -2069,22 +2069,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let mut guard_span = rustc_span::DUMMY_SP;
|
||||
|
||||
let (post_guard_block, otherwise_post_guard_block) =
|
||||
self.in_if_then_scope(match_scope, guard_span, |this| match *guard {
|
||||
Guard::If(e) => {
|
||||
guard_span = this.thir[e].span;
|
||||
this.then_else_break(
|
||||
block,
|
||||
e,
|
||||
None,
|
||||
match_scope,
|
||||
this.source_info(arm.span),
|
||||
false,
|
||||
)
|
||||
}
|
||||
Guard::IfLet(ref pat, s) => {
|
||||
guard_span = this.thir[s].span;
|
||||
this.lower_let_expr(block, s, pat, match_scope, None, arm.span, false)
|
||||
}
|
||||
self.in_if_then_scope(match_scope, guard_span, |this| {
|
||||
guard_span = this.thir[guard].span;
|
||||
this.then_else_break(
|
||||
block,
|
||||
guard,
|
||||
None,
|
||||
match_scope,
|
||||
this.source_info(arm.span),
|
||||
false,
|
||||
)
|
||||
});
|
||||
|
||||
let source_info = self.source_info(guard_span);
|
||||
|
@ -856,7 +856,7 @@ impl<'tcx> Cx<'tcx> {
|
||||
fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
|
||||
let arm = Arm {
|
||||
pattern: self.pattern_from_hir(&arm.pat),
|
||||
guard: arm.guard.as_ref().map(|g| Guard::If(self.mirror_expr(g))),
|
||||
guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)),
|
||||
body: self.mirror_expr(arm.body),
|
||||
lint_level: LintLevel::Explicit(arm.hir_id),
|
||||
scope: region::Scope { id: arm.hir_id.local_id, data: region::ScopeData::Node },
|
||||
|
@ -100,20 +100,10 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn visit_arm(&mut self, arm: &'p Arm<'tcx>) {
|
||||
self.with_lint_level(arm.lint_level, |this| {
|
||||
match arm.guard {
|
||||
Some(Guard::If(expr)) => {
|
||||
this.with_let_source(LetSource::IfLetGuard, |this| {
|
||||
this.visit_expr(&this.thir[expr])
|
||||
});
|
||||
}
|
||||
Some(Guard::IfLet(ref pat, expr)) => {
|
||||
this.with_let_source(LetSource::IfLetGuard, |this| {
|
||||
this.check_let(pat, Some(expr), pat.span);
|
||||
this.visit_pat(pat);
|
||||
this.visit_expr(&this.thir[expr]);
|
||||
});
|
||||
}
|
||||
None => {}
|
||||
if let Some(expr) = arm.guard {
|
||||
this.with_let_source(LetSource::IfLetGuard, |this| {
|
||||
this.visit_expr(&this.thir[expr])
|
||||
});
|
||||
}
|
||||
this.visit_pat(&arm.pattern);
|
||||
this.visit_expr(&self.thir[arm.body]);
|
||||
|
@ -593,9 +593,9 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
||||
print_indented!(self, "pattern: ", depth_lvl + 1);
|
||||
self.print_pat(pattern, depth_lvl + 2);
|
||||
|
||||
if let Some(guard) = guard {
|
||||
if let Some(guard) = *guard {
|
||||
print_indented!(self, "guard: ", depth_lvl + 1);
|
||||
self.print_guard(guard, depth_lvl + 2);
|
||||
self.print_expr(guard, depth_lvl + 2);
|
||||
} else {
|
||||
print_indented!(self, "guard: None", depth_lvl + 1);
|
||||
}
|
||||
@ -764,27 +764,6 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
|
||||
fn print_guard(&mut self, guard: &Guard<'tcx>, depth_lvl: usize) {
|
||||
print_indented!(self, "Guard {", depth_lvl);
|
||||
|
||||
match guard {
|
||||
Guard::If(expr_id) => {
|
||||
print_indented!(self, "If (", depth_lvl + 1);
|
||||
self.print_expr(*expr_id, depth_lvl + 2);
|
||||
print_indented!(self, ")", depth_lvl + 1);
|
||||
}
|
||||
Guard::IfLet(pat, expr_id) => {
|
||||
print_indented!(self, "IfLet (", depth_lvl + 1);
|
||||
self.print_pat(pat, depth_lvl + 2);
|
||||
print_indented!(self, ",", depth_lvl + 1);
|
||||
self.print_expr(*expr_id, depth_lvl + 2);
|
||||
print_indented!(self, ")", depth_lvl + 1);
|
||||
}
|
||||
}
|
||||
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
|
||||
fn print_closure_expr(&mut self, expr: &ClosureExpr<'tcx>, depth_lvl: usize) {
|
||||
let ClosureExpr { closure_id, args, upvars, movability, fake_reads } = expr;
|
||||
|
||||
|
30
tests/ui/rfcs/rfc-2294-if-let-guard/scope.rs
Normal file
30
tests/ui/rfcs/rfc-2294-if-let-guard/scope.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Tests for #88015 when using if let chains in match guards
|
||||
|
||||
//run-pass
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
fn lhs_let(opt: Option<bool>) {
|
||||
match opt {
|
||||
None | Some(false) | Some(true) if let x = 42 && true => assert_eq!(x, 42),
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn rhs_let(opt: Option<bool>) {
|
||||
match opt {
|
||||
None | Some(false) | Some(true) if true && let x = 41 => assert_eq!(x, 41),
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
lhs_let(None);
|
||||
lhs_let(Some(false));
|
||||
lhs_let(Some(true));
|
||||
rhs_let(None);
|
||||
rhs_let(Some(false));
|
||||
rhs_let(Some(true));
|
||||
}
|
Loading…
Reference in New Issue
Block a user