Rollup merge of #79051 - LeSeulArtichaut:if-let-guard, r=matthewjasper
Implement if-let match guards Implements rust-lang/rfcs#2294 (tracking issue: #51114). I probably should do a few more things before this can be merged: - [x] Add tests (added basic tests, more advanced tests could be done in the future?) - [x] Add lint for exhaustive if-let guard (comparable to normal if-let statements) - [x] Fix clippy However since this is a nightly feature maybe it's fine to land this and do those steps in follow-up PRs. Thanks a lot `@matthewjasper` ❤️ for helping me with lowering to MIR! Would you be interested in reviewing this? r? `@ghost` for now
This commit is contained in:
commit
286e492343
|
@ -342,6 +342,10 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut
|
|||
if let Some(ref guard) = arm.guard {
|
||||
match guard {
|
||||
Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
|
||||
Guard::IfLet(guard_pat, guard_expr) => {
|
||||
check_pat(cx, guard_pat, Some(*guard_expr), guard_pat.span, bindings);
|
||||
check_expr(cx, guard_expr, bindings);
|
||||
},
|
||||
}
|
||||
}
|
||||
check_expr(cx, &arm.body, bindings);
|
||||
|
|
|
@ -372,6 +372,18 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.current = if_expr_pat;
|
||||
self.visit_expr(if_expr);
|
||||
},
|
||||
hir::Guard::IfLet(ref if_let_pat, ref if_let_expr) => {
|
||||
let if_let_pat_pat = self.next("pat");
|
||||
let if_let_expr_pat = self.next("expr");
|
||||
println!(
|
||||
" if let Guard::IfLet(ref {}, ref {}) = {};",
|
||||
if_let_pat_pat, if_let_expr_pat, guard_pat
|
||||
);
|
||||
self.current = if_let_expr_pat;
|
||||
self.visit_expr(if_let_expr);
|
||||
self.current = if_let_pat_pat;
|
||||
self.visit_pat(if_let_pat);
|
||||
},
|
||||
}
|
||||
}
|
||||
self.current = format!("{}[{}].pat", arms_pat, i);
|
||||
|
@ -730,6 +742,7 @@ fn desugaring_name(des: hir::MatchSource) -> String {
|
|||
"MatchSource::IfLetDesugar {{ contains_else_clause: {} }}",
|
||||
contains_else_clause
|
||||
),
|
||||
hir::MatchSource::IfLetGuardDesugar => "MatchSource::IfLetGuardDesugar".to_string(),
|
||||
hir::MatchSource::IfDesugar { contains_else_clause } => format!(
|
||||
"MatchSource::IfDesugar {{ contains_else_clause: {} }}",
|
||||
contains_else_clause
|
||||
|
|
|
@ -169,6 +169,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
|
|||
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),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,7 +671,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
|
||||
pub fn hash_guard(&mut self, g: &Guard<'_>) {
|
||||
match g {
|
||||
Guard::If(ref expr) => {
|
||||
Guard::If(ref expr) | Guard::IfLet(_, ref expr) => {
|
||||
self.hash_expr(expr);
|
||||
},
|
||||
}
|
||||
|
|
|
@ -560,5 +560,10 @@ fn print_guard(cx: &LateContext<'_>, guard: &hir::Guard<'_>, indent: usize) {
|
|||
println!("{}If", ind);
|
||||
print_expr(cx, expr, indent + 1);
|
||||
},
|
||||
hir::Guard::IfLet(pat, expr) => {
|
||||
println!("{}IfLet", ind);
|
||||
print_pat(cx, pat, indent + 1);
|
||||
print_expr(cx, expr, indent + 1);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue