]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_mir_build/src/thir/pattern/check_match.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / compiler / rustc_mir_build / src / thir / pattern / check_match.rs
index 58e484e413dab4d5a1a4d4ca14f40479ec059328..76333b755b747d540a1ad3d526070ac92b368613 100644 (file)
@@ -23,7 +23,7 @@ use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span};
 
-crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
+pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
     let body_id = match def_id.as_local() {
         None => return,
         Some(id) => tcx.hir().body_owned_by(tcx.hir().local_def_id_to_hir_id(id)),
@@ -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());
             }
         }
 
@@ -803,7 +803,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     let mut suggestion = None;
     let sm = cx.tcx.sess.source_map();
     match arms {
-        [] if sp.ctxt() == expr_span.ctxt() => {
+        [] if sp.eq_ctxt(expr_span) => {
             // Get the span for the empty match body `{}`.
             let (indentation, more) = if let Some(snippet) = sm.indentation_before(sp) {
                 (format!("\n{}", snippet), "    ")
@@ -821,24 +821,36 @@ fn non_exhaustive_match<'p, 'tcx>(
             ));
         }
         [only] => {
-            let pre_indentation = if let (Some(snippet), true) = (
-                sm.indentation_before(only.span),
-                sm.is_multiline(sp.shrink_to_hi().with_hi(only.span.lo())),
-            ) {
-                format!("\n{}", snippet)
+            let (pre_indentation, is_multiline) = if let Some(snippet) = sm.indentation_before(only.span)
+                && let Ok(with_trailing) = sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',')
+                && sm.is_multiline(with_trailing)
+            {
+                (format!("\n{}", snippet), true)
+            } else {
+                (" ".to_string(), false)
+            };
+            let comma = if matches!(only.body.kind, hir::ExprKind::Block(..))
+                && only.span.eq_ctxt(only.body.span)
+                && is_multiline
+            {
+                ""
             } else {
-                " ".to_string()
+                ","
             };
-            let comma = if matches!(only.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
             suggestion = Some((
                 only.span.shrink_to_hi(),
                 format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
             ));
         }
-        [.., prev, last] if prev.span.ctxt() == last.span.ctxt() => {
+        [.., prev, last] if prev.span.eq_ctxt(last.span) => {
             if let Ok(snippet) = sm.span_to_snippet(prev.span.between(last.span)) {
-                let comma =
-                    if matches!(last.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
+                let comma = if matches!(last.body.kind, hir::ExprKind::Block(..))
+                    && last.span.eq_ctxt(last.body.span)
+                {
+                    ""
+                } else {
+                    ","
+                };
                 suggestion = Some((
                     last.span.shrink_to_hi(),
                     format!(
@@ -880,7 +892,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     err.emit();
 }
 
-crate fn joined_uncovered_patterns<'p, 'tcx>(
+pub(crate) fn joined_uncovered_patterns<'p, 'tcx>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
     witnesses: &[DeconstructedPat<'p, 'tcx>],
 ) -> String {
@@ -901,7 +913,7 @@ crate fn joined_uncovered_patterns<'p, 'tcx>(
     }
 }
 
-crate fn pattern_not_covered_label(
+pub(crate) fn pattern_not_covered_label(
     witnesses: &[DeconstructedPat<'_, '_>],
     joined_patterns: &str,
 ) -> String {
@@ -1108,9 +1120,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, .. }) => {