Skip to content

use hir::Let in hir::Guard::IfLet #96863

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
let pat = self.lower_pat(&arm.pat);
let guard = arm.guard.as_ref().map(|cond| {
if let ExprKind::Let(ref pat, ref scrutinee, _) = cond.kind {
hir::Guard::IfLet(self.lower_pat(pat), self.lower_expr(scrutinee))
if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind {
hir::Guard::IfLet(self.arena.alloc(hir::Let {
hir_id: self.next_id(),
span: self.lower_span(span),
pat: self.lower_pat(pat),
ty: None,
init: self.lower_expr(scrutinee),
}))
} else {
hir::Guard::If(self.lower_expr(cond))
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1312,8 +1312,7 @@ pub struct Let<'hir> {
#[derive(Debug, HashStable_Generic)]
pub enum Guard<'hir> {
If(&'hir Expr<'hir>),
// FIXME use hir::Let for this.
IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>),
IfLet(&'hir Let<'hir>),
}

#[derive(Debug, HashStable_Generic)]
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,9 +1233,8 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
if let Some(ref g) = arm.guard {
match g {
Guard::If(ref e) => visitor.visit_expr(e),
Guard::IfLet(ref pat, ref e) => {
visitor.visit_pat(pat);
visitor.visit_expr(e);
Guard::IfLet(ref l) => {
visitor.visit_let_expr(l);
}
}
}
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1915,14 +1915,9 @@ impl<'a> State<'a> {
self.print_expr(&e);
self.space();
}
hir::Guard::IfLet(pat, e) => {
hir::Guard::IfLet(hir::Let { pat, ty, init, .. }) => {
self.word_nbsp("if");
self.word_nbsp("let");
self.print_pat(&pat);
self.space();
self.word_space("=");
self.print_expr(&e);
self.space();
self.print_let(pat, *ty, init);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,8 +798,8 @@ impl<'tcx> Cx<'tcx> {
pattern: self.pattern_from_hir(&arm.pat),
guard: arm.guard.as_ref().map(|g| match g {
hir::Guard::If(ref e) => Guard::If(self.mirror_expr(e)),
hir::Guard::IfLet(ref pat, ref e) => {
Guard::IfLet(self.pattern_from_hir(pat), self.mirror_expr(e))
hir::Guard::IfLet(ref l) => {
Guard::IfLet(self.pattern_from_hir(l.pat), self.mirror_expr(l.init))
}
}),
body: self.mirror_expr(arm.body),
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
for arm in hir_arms {
// Check the arm for some things unrelated to exhaustiveness.
self.check_patterns(&arm.pat, Refutable);
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
self.check_patterns(pat, Refutable);
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
self.check_let_reachability(&mut cx, pat.hir_id, tpat, tpat.span());
if let Some(hir::Guard::IfLet(ref let_expr)) = arm.guard {
self.check_patterns(let_expr.pat, Refutable);
let tpat = self.lower_pattern(&mut cx, let_expr.pat, &mut false);
self.check_let_reachability(&mut cx, let_expr.pat.hir_id, tpat, tpat.span());
}
}

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

match parent_node {
hir::Node::Arm(hir::Arm {
guard: Some(hir::Guard::IfLet(&hir::Pat { hir_id, .. }, _)),
guard: Some(hir::Guard::IfLet(&hir::Let { pat: hir::Pat { hir_id, .. }, .. })),
..
}) if Some(hir_id) == pat_id => {
}) if Some(*hir_id) == pat_id => {
return LetSource::IfLetGuard;
}
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Let(..), span, .. }) => {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,8 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {

fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
self.add_from_pat(&arm.pat);
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
self.add_from_pat(pat);
if let Some(hir::Guard::IfLet(ref let_expr)) = arm.guard {
self.add_from_pat(let_expr.pat);
}
intravisit::walk_arm(self, arm);
}
Expand Down Expand Up @@ -914,9 +914,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

let guard_succ = arm.guard.as_ref().map_or(body_succ, |g| match g {
hir::Guard::If(e) => self.propagate_through_expr(e, body_succ),
hir::Guard::IfLet(pat, e) => {
let let_bind = self.define_bindings_in_pat(pat, body_succ);
self.propagate_through_expr(e, let_bind)
hir::Guard::IfLet(let_expr) => {
let let_bind = self.define_bindings_in_pat(let_expr.pat, body_succ);
self.propagate_through_expr(let_expr.init, let_bind)
}
});
let arm_succ = self.define_bindings_in_pat(&arm.pat, guard_succ);
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_typeck/src/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Guard::If(e) => {
self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {});
}
hir::Guard::IfLet(pat, e) => {
let scrutinee_ty = self.demand_scrutinee_type(
e,
pat.contains_explicit_ref_binding(),
false,
);
self.check_pat_top(&pat, scrutinee_ty, None, true);
hir::Guard::IfLet(l) => {
self.check_expr_let(l);
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>) -> Ty<'tcx> {
pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>) -> Ty<'tcx> {
// for let statements, this is done in check_stmt
let init = let_expr.init;
self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression");
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_typeck/src/check/generator_interior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,8 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
Guard::If(ref e) => {
self.visit_expr(e);
}
Guard::IfLet(ref pat, ref e) => {
self.visit_pat(pat);
self.visit_expr(e);
Guard::IfLet(ref l) => {
self.visit_let_expr(l);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
// B -> C and E -> F are added implicitly due to the traversal order.
match guard {
Some(Guard::If(expr)) => self.visit_expr(expr),
Some(Guard::IfLet(pat, expr)) => {
self.visit_pat(pat);
self.visit_expr(expr);
Some(Guard::IfLet(let_expr)) => {
self.visit_let_expr(let_expr);
}
None => (),
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,8 +625,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {

if let Some(hir::Guard::If(e)) = arm.guard {
self.consume_expr(e)
} else if let Some(hir::Guard::IfLet(_, ref e)) = arm.guard {
self.consume_expr(e)
} else if let Some(hir::Guard::IfLet(ref l)) = arm.guard {
self.consume_expr(l.init)
}

self.consume_expr(arm.body);
Expand Down
8 changes: 6 additions & 2 deletions src/test/ui/rfc-2294-if-let-guard/typeck.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/typeck.rs:9:22
|
LL | Ok(x) if let Err(_) = x => {},
| ^^^^^^ expected enum `Option`, found enum `Result`
| ^^^^^^ - this expression has type `Option<bool>`
| |
| expected enum `Option`, found enum `Result`
|
= note: expected enum `Option<bool>`
found enum `Result<_, _>`
Expand All @@ -11,7 +13,9 @@ error[E0308]: mismatched types
--> $DIR/typeck.rs:11:22
|
LL | Ok(x) if let 0 = x => {},
| ^ expected enum `Option`, found integer
| ^ - this expression has type `Option<bool>`
| |
| expected enum `Option`, found integer
|
= note: expected enum `Option<bool>`
found type `{integer}`
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/collapsible_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use clippy_utils::{is_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_s
use if_chain::if_chain;
use rustc_errors::MultiSpan;
use rustc_hir::LangItem::OptionNone;
use rustc_hir::{Arm, Expr, Guard, HirId, Pat, PatKind};
use rustc_hir::{Arm, Expr, Guard, HirId, Let, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span;
Expand Down Expand Up @@ -109,7 +109,7 @@ fn check_arm<'tcx>(
(Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b),
};
// the binding must not be used in the if guard
if outer_guard.map_or(true, |(Guard::If(e) | Guard::IfLet(_, e))| !is_local_used(cx, *e, binding_id));
if outer_guard.map_or(true, |(Guard::If(e) | Guard::IfLet(Let { init: e, .. }))| !is_local_used(cx, *e, binding_id));
// ...or anywhere in the inner expression
if match inner {
IfLetOrMatch::IfLet(_, _, body, els) => {
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_errors::Applicability;
use rustc_hir::{
hir_id::HirIdSet,
intravisit::{walk_expr, Visitor},
Block, Expr, ExprKind, Guard, HirId, Pat, Stmt, StmtKind, UnOp,
Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
Expand Down Expand Up @@ -478,7 +478,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
let mut is_map_used = self.is_map_used;
for arm in arms {
self.visit_pat(arm.pat);
if let Some(Guard::If(guard) | Guard::IfLet(_, guard)) = arm.guard {
if let Some(Guard::If(guard) | Guard::IfLet(&Let { init: guard, .. })) = arm.guard {
self.visit_non_tail_expr(guard);
}
is_map_used |= self.visit_cond_arm(arm.body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ impl<'tcx> SideEffectVisit<'tcx> {
let mut vars = std::mem::take(&mut self.ret_vars);
let _ = arm.guard.as_ref().map(|guard| {
self.visit_expr(match guard {
Guard::If(expr) | Guard::IfLet(_, expr) => expr,
Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => expr,
});
vars.append(&mut self.ret_vars);
});
Expand Down
10 changes: 5 additions & 5 deletions src/tools/clippy/clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
out!("if let Some(Guard::If({expr})) = {arm}.guard;");
self.expr(expr);
},
Some(hir::Guard::IfLet(pat, expr)) => {
bind!(self, pat, expr);
out!("if let Some(Guard::IfLet({pat}, {expr}) = {arm}.guard;");
self.pat(pat);
self.expr(expr);
Some(hir::Guard::IfLet(let_expr)) => {
bind!(self, let_expr);
out!("if let Some(Guard::IfLet({let_expr}) = {arm}.guard;");
self.pat(field!(let_expr.pat));
self.expr(field!(let_expr.init));
},
}
self.expr(field!(arm.body));
Expand Down
6 changes: 4 additions & 2 deletions src/tools/clippy/clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,9 @@ impl HirEqInterExpr<'_, '_, '_> {
fn eq_guard(&mut self, left: &Guard<'_>, right: &Guard<'_>) -> bool {
match (left, right) {
(Guard::If(l), Guard::If(r)) => self.eq_expr(l, r),
(Guard::IfLet(lp, le), Guard::IfLet(rp, re)) => self.eq_pat(lp, rp) && self.eq_expr(le, re),
(Guard::IfLet(l), Guard::IfLet(r)) => {
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)
},
_ => false,
}
}
Expand Down Expand Up @@ -894,7 +896,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {

pub fn hash_guard(&mut self, g: &Guard<'_>) {
match g {
Guard::If(expr) | Guard::IfLet(_, expr) => {
Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => {
self.hash_expr(expr);
},
}
Expand Down