Skip to content

Commit 07ae142

Browse files
committed
Auto merge of rust-lang#96863 - SparrowLii:let, r=michaelwoerister
use `hir::Let` in `hir::Guard::IfLet` This PR fixes the FIXME about using `hir::Let` in `hir::Guard::IfLet`
2 parents 10d9ecd + 303dcfb commit 07ae142

File tree

18 files changed

+55
-57
lines changed

18 files changed

+55
-57
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
505505
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
506506
let pat = self.lower_pat(&arm.pat);
507507
let guard = arm.guard.as_ref().map(|cond| {
508-
if let ExprKind::Let(ref pat, ref scrutinee, _) = cond.kind {
509-
hir::Guard::IfLet(self.lower_pat(pat), self.lower_expr(scrutinee))
508+
if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind {
509+
hir::Guard::IfLet(self.arena.alloc(hir::Let {
510+
hir_id: self.next_id(),
511+
span: self.lower_span(span),
512+
pat: self.lower_pat(pat),
513+
ty: None,
514+
init: self.lower_expr(scrutinee),
515+
}))
510516
} else {
511517
hir::Guard::If(self.lower_expr(cond))
512518
}

compiler/rustc_hir/src/hir.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1320,8 +1320,7 @@ pub struct Let<'hir> {
13201320
#[derive(Debug, HashStable_Generic)]
13211321
pub enum Guard<'hir> {
13221322
If(&'hir Expr<'hir>),
1323-
// FIXME use hir::Let for this.
1324-
IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>),
1323+
IfLet(&'hir Let<'hir>),
13251324
}
13261325

13271326
#[derive(Debug, HashStable_Generic)]

compiler/rustc_hir/src/intravisit.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1225,9 +1225,8 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
12251225
if let Some(ref g) = arm.guard {
12261226
match g {
12271227
Guard::If(ref e) => visitor.visit_expr(e),
1228-
Guard::IfLet(ref pat, ref e) => {
1229-
visitor.visit_pat(pat);
1230-
visitor.visit_expr(e);
1228+
Guard::IfLet(ref l) => {
1229+
visitor.visit_let_expr(l);
12311230
}
12321231
}
12331232
}

compiler/rustc_hir_pretty/src/lib.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1915,14 +1915,9 @@ impl<'a> State<'a> {
19151915
self.print_expr(&e);
19161916
self.space();
19171917
}
1918-
hir::Guard::IfLet(pat, e) => {
1918+
hir::Guard::IfLet(hir::Let { pat, ty, init, .. }) => {
19191919
self.word_nbsp("if");
1920-
self.word_nbsp("let");
1921-
self.print_pat(&pat);
1922-
self.space();
1923-
self.word_space("=");
1924-
self.print_expr(&e);
1925-
self.space();
1920+
self.print_let(pat, *ty, init);
19261921
}
19271922
}
19281923
}

compiler/rustc_mir_build/src/thir/cx/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,8 @@ impl<'tcx> Cx<'tcx> {
798798
pattern: self.pattern_from_hir(&arm.pat),
799799
guard: arm.guard.as_ref().map(|g| match g {
800800
hir::Guard::If(ref e) => Guard::If(self.mirror_expr(e)),
801-
hir::Guard::IfLet(ref pat, ref e) => {
802-
Guard::IfLet(self.pattern_from_hir(pat), self.mirror_expr(e))
801+
hir::Guard::IfLet(ref l) => {
802+
Guard::IfLet(self.pattern_from_hir(l.pat), self.mirror_expr(l.init))
803803
}
804804
}),
805805
body: self.mirror_expr(arm.body),

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
173173
for arm in hir_arms {
174174
// Check the arm for some things unrelated to exhaustiveness.
175175
self.check_patterns(&arm.pat, Refutable);
176-
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
177-
self.check_patterns(pat, Refutable);
178-
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
179-
self.check_let_reachability(&mut cx, pat.hir_id, tpat, tpat.span());
176+
if let Some(hir::Guard::IfLet(ref let_expr)) = arm.guard {
177+
self.check_patterns(let_expr.pat, Refutable);
178+
let tpat = self.lower_pattern(&mut cx, let_expr.pat, &mut false);
179+
self.check_let_reachability(&mut cx, let_expr.pat.hir_id, tpat, tpat.span());
180180
}
181181
}
182182

@@ -1108,9 +1108,9 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
11081108

11091109
match parent_node {
11101110
hir::Node::Arm(hir::Arm {
1111-
guard: Some(hir::Guard::IfLet(&hir::Pat { hir_id, .. }, _)),
1111+
guard: Some(hir::Guard::IfLet(&hir::Let { pat: hir::Pat { hir_id, .. }, .. })),
11121112
..
1113-
}) if Some(hir_id) == pat_id => {
1113+
}) if Some(*hir_id) == pat_id => {
11141114
return LetSource::IfLetGuard;
11151115
}
11161116
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Let(..), span, .. }) => {

compiler/rustc_passes/src/liveness.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
373373

374374
fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
375375
self.add_from_pat(&arm.pat);
376-
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
377-
self.add_from_pat(pat);
376+
if let Some(hir::Guard::IfLet(ref let_expr)) = arm.guard {
377+
self.add_from_pat(let_expr.pat);
378378
}
379379
intravisit::walk_arm(self, arm);
380380
}
@@ -914,9 +914,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
914914

915915
let guard_succ = arm.guard.as_ref().map_or(body_succ, |g| match g {
916916
hir::Guard::If(e) => self.propagate_through_expr(e, body_succ),
917-
hir::Guard::IfLet(pat, e) => {
918-
let let_bind = self.define_bindings_in_pat(pat, body_succ);
919-
self.propagate_through_expr(e, let_bind)
917+
hir::Guard::IfLet(let_expr) => {
918+
let let_bind = self.define_bindings_in_pat(let_expr.pat, body_succ);
919+
self.propagate_through_expr(let_expr.init, let_bind)
920920
}
921921
});
922922
let arm_succ = self.define_bindings_in_pat(&arm.pat, guard_succ);

compiler/rustc_typeck/src/check/_match.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8282
hir::Guard::If(e) => {
8383
self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {});
8484
}
85-
hir::Guard::IfLet(pat, e) => {
86-
let scrutinee_ty = self.demand_scrutinee_type(
87-
e,
88-
pat.contains_explicit_ref_binding(),
89-
false,
90-
);
91-
self.check_pat_top(&pat, scrutinee_ty, None, true);
85+
hir::Guard::IfLet(l) => {
86+
self.check_expr_let(l);
9287
}
9388
};
9489
}

compiler/rustc_typeck/src/check/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1105,7 +1105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11051105
}
11061106
}
11071107

1108-
fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>) -> Ty<'tcx> {
1108+
pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>) -> Ty<'tcx> {
11091109
// for let statements, this is done in check_stmt
11101110
let init = let_expr.init;
11111111
self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression");

compiler/rustc_typeck/src/check/generator_interior.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,8 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
298298
Guard::If(ref e) => {
299299
self.visit_expr(e);
300300
}
301-
Guard::IfLet(ref pat, ref e) => {
302-
self.visit_pat(pat);
303-
self.visit_expr(e);
301+
Guard::IfLet(ref l) => {
302+
self.visit_let_expr(l);
304303
}
305304
}
306305

compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
344344
// B -> C and E -> F are added implicitly due to the traversal order.
345345
match guard {
346346
Some(Guard::If(expr)) => self.visit_expr(expr),
347-
Some(Guard::IfLet(pat, expr)) => {
348-
self.visit_pat(pat);
349-
self.visit_expr(expr);
347+
Some(Guard::IfLet(let_expr)) => {
348+
self.visit_let_expr(let_expr);
350349
}
351350
None => (),
352351
}

compiler/rustc_typeck/src/expr_use_visitor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
625625

626626
if let Some(hir::Guard::If(e)) = arm.guard {
627627
self.consume_expr(e)
628-
} else if let Some(hir::Guard::IfLet(_, ref e)) = arm.guard {
629-
self.consume_expr(e)
628+
} else if let Some(hir::Guard::IfLet(ref l)) = arm.guard {
629+
self.consume_expr(l.init)
630630
}
631631

632632
self.consume_expr(arm.body);

src/test/ui/rfc-2294-if-let-guard/typeck.stderr

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/typeck.rs:9:22
33
|
44
LL | Ok(x) if let Err(_) = x => {},
5-
| ^^^^^^ expected enum `Option`, found enum `Result`
5+
| ^^^^^^ - this expression has type `Option<bool>`
6+
| |
7+
| expected enum `Option`, found enum `Result`
68
|
79
= note: expected enum `Option<bool>`
810
found enum `Result<_, _>`
@@ -11,7 +13,9 @@ error[E0308]: mismatched types
1113
--> $DIR/typeck.rs:11:22
1214
|
1315
LL | Ok(x) if let 0 = x => {},
14-
| ^ expected enum `Option`, found integer
16+
| ^ - this expression has type `Option<bool>`
17+
| |
18+
| expected enum `Option`, found integer
1519
|
1620
= note: expected enum `Option<bool>`
1721
found type `{integer}`

src/tools/clippy/clippy_lints/src/collapsible_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use clippy_utils::{is_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_s
55
use if_chain::if_chain;
66
use rustc_errors::MultiSpan;
77
use rustc_hir::LangItem::OptionNone;
8-
use rustc_hir::{Arm, Expr, Guard, HirId, Pat, PatKind};
8+
use rustc_hir::{Arm, Expr, Guard, HirId, Let, Pat, PatKind};
99
use rustc_lint::{LateContext, LateLintPass};
1010
use rustc_session::{declare_lint_pass, declare_tool_lint};
1111
use rustc_span::Span;
@@ -109,7 +109,7 @@ fn check_arm<'tcx>(
109109
(Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b),
110110
};
111111
// the binding must not be used in the if guard
112-
if outer_guard.map_or(true, |(Guard::If(e) | Guard::IfLet(_, e))| !is_local_used(cx, *e, binding_id));
112+
if outer_guard.map_or(true, |(Guard::If(e) | Guard::IfLet(Let { init: e, .. }))| !is_local_used(cx, *e, binding_id));
113113
// ...or anywhere in the inner expression
114114
if match inner {
115115
IfLetOrMatch::IfLet(_, _, body, els) => {

src/tools/clippy/clippy_lints/src/entry.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_errors::Applicability;
1111
use rustc_hir::{
1212
hir_id::HirIdSet,
1313
intravisit::{walk_expr, Visitor},
14-
Block, Expr, ExprKind, Guard, HirId, Pat, Stmt, StmtKind, UnOp,
14+
Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp,
1515
};
1616
use rustc_lint::{LateContext, LateLintPass};
1717
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -478,7 +478,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
478478
let mut is_map_used = self.is_map_used;
479479
for arm in arms {
480480
self.visit_pat(arm.pat);
481-
if let Some(Guard::If(guard) | Guard::IfLet(_, guard)) = arm.guard {
481+
if let Some(Guard::If(guard) | Guard::IfLet(&Let { init: guard, .. })) = arm.guard {
482482
self.visit_non_tail_expr(guard);
483483
}
484484
is_map_used |= self.visit_cond_arm(arm.body);

src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ impl<'tcx> SideEffectVisit<'tcx> {
596596
let mut vars = std::mem::take(&mut self.ret_vars);
597597
let _ = arm.guard.as_ref().map(|guard| {
598598
self.visit_expr(match guard {
599-
Guard::If(expr) | Guard::IfLet(_, expr) => expr,
599+
Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => expr,
600600
});
601601
vars.append(&mut self.ret_vars);
602602
});

src/tools/clippy/clippy_lints/src/utils/author.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
315315
out!("if let Some(Guard::If({expr})) = {arm}.guard;");
316316
self.expr(expr);
317317
},
318-
Some(hir::Guard::IfLet(pat, expr)) => {
319-
bind!(self, pat, expr);
320-
out!("if let Some(Guard::IfLet({pat}, {expr}) = {arm}.guard;");
321-
self.pat(pat);
322-
self.expr(expr);
318+
Some(hir::Guard::IfLet(let_expr)) => {
319+
bind!(self, let_expr);
320+
out!("if let Some(Guard::IfLet({let_expr}) = {arm}.guard;");
321+
self.pat(field!(let_expr.pat));
322+
self.expr(field!(let_expr.init));
323323
},
324324
}
325325
self.expr(field!(arm.body));

src/tools/clippy/clippy_utils/src/hir_utils.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ impl HirEqInterExpr<'_, '_, '_> {
301301
fn eq_guard(&mut self, left: &Guard<'_>, right: &Guard<'_>) -> bool {
302302
match (left, right) {
303303
(Guard::If(l), Guard::If(r)) => self.eq_expr(l, r),
304-
(Guard::IfLet(lp, le), Guard::IfLet(rp, re)) => self.eq_pat(lp, rp) && self.eq_expr(le, re),
304+
(Guard::IfLet(l), Guard::IfLet(r)) => {
305+
self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
306+
},
305307
_ => false,
306308
}
307309
}
@@ -894,7 +896,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
894896

895897
pub fn hash_guard(&mut self, g: &Guard<'_>) {
896898
match g {
897-
Guard::If(expr) | Guard::IfLet(_, expr) => {
899+
Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => {
898900
self.hash_expr(expr);
899901
},
900902
}

0 commit comments

Comments
 (0)