]> git.lizzy.rs Git - rust.git/commitdiff
typeck/pat.rs: extract `check_pat_lit`.
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 24 Aug 2019 01:52:09 +0000 (03:52 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Sat, 24 Aug 2019 17:15:11 +0000 (19:15 +0200)
src/librustc_typeck/check/pat.rs

index a9e6cfb41a469fc3f7128e9f78d7d7fa14912309..95013f60cd6de0e694b9756eb15561c47c296573 100644 (file)
@@ -68,49 +68,7 @@ pub fn check_pat_walk(
                 expected
             }
             PatKind::Lit(ref lt) => {
-                // We've already computed the type above (when checking for a non-ref pat), so
-                // avoid computing it again.
-                let ty = self.node_ty(lt.hir_id);
-
-                // Byte string patterns behave the same way as array patterns
-                // They can denote both statically and dynamically-sized byte arrays.
-                let mut pat_ty = ty;
-                if let hir::ExprKind::Lit(ref lt) = lt.node {
-                    if let ast::LitKind::ByteStr(_) = lt.node {
-                        let expected_ty = self.structurally_resolved_type(pat.span, expected);
-                        if let ty::Ref(_, r_ty, _) = expected_ty.sty {
-                            if let ty::Slice(_) = r_ty.sty {
-                                pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
-                                                        tcx.mk_slice(tcx.types.u8))
-                            }
-                        }
-                    }
-                }
-
-                // Somewhat surprising: in this case, the subtyping
-                // relation goes the opposite way as the other
-                // cases. Actually what we really want is not a subtyping
-                // relation at all but rather that there exists a LUB (so
-                // that they can be compared). However, in practice,
-                // constants are always scalars or strings.  For scalars
-                // subtyping is irrelevant, and for strings `ty` is
-                // type is `&'static str`, so if we say that
-                //
-                //     &'static str <: expected
-                //
-                // then that's equivalent to there existing a LUB.
-                if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
-                    err.emit_unless(discrim_span
-                        .filter(|&s| {
-                            // In the case of `if`- and `while`-expressions we've already checked
-                            // that `scrutinee: bool`. We know that the pattern is `true`,
-                            // so an error here would be a duplicate and from the wrong POV.
-                            s.is_desugaring(DesugaringKind::CondTemporary)
-                        })
-                        .is_some());
-                }
-
-                pat_ty
+                self.check_pat_lit(pat.span, lt, expected, discrim_span)
             }
             PatKind::Range(ref begin, ref end, _) => {
                 let lhs_ty = self.check_expr(begin);
@@ -586,6 +544,60 @@ fn peel_off_references(
         (expected, def_bm)
     }
 
+    fn check_pat_lit(
+        &self,
+        span: Span,
+        lt: &hir::Expr,
+        expected: Ty<'tcx>,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        // We've already computed the type above (when checking for a non-ref pat),
+        // so avoid computing it again.
+        let ty = self.node_ty(lt.hir_id);
+
+        // Byte string patterns behave the same way as array patterns
+        // They can denote both statically and dynamically-sized byte arrays.
+        let mut pat_ty = ty;
+        if let hir::ExprKind::Lit(ref lt) = lt.node {
+            if let ast::LitKind::ByteStr(_) = lt.node {
+                let expected_ty = self.structurally_resolved_type(span, expected);
+                if let ty::Ref(_, r_ty, _) = expected_ty.sty {
+                    if let ty::Slice(_) = r_ty.sty {
+                        let tcx = self.tcx;
+                        pat_ty = tcx.mk_imm_ref(
+                            tcx.lifetimes.re_static,
+                            tcx.mk_slice(tcx.types.u8),
+                        );
+                    }
+                }
+            }
+        }
+
+        // Somewhat surprising: in this case, the subtyping relation goes the
+        // opposite way as the other cases. Actually what we really want is not
+        // a subtyping relation at all but rather that there exists a LUB
+        // (so that they can be compared). However, in practice, constants are
+        // always scalars or strings. For scalars subtyping is irrelevant,
+        // and for strings `ty` is type is `&'static str`, so if we say that
+        //
+        //     &'static str <: expected
+        //
+        // then that's equivalent to there existing a LUB.
+        if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
+            err.emit_unless(discrim_span
+                .filter(|&s| {
+                    // In the case of `if`- and `while`-expressions we've already checked
+                    // that `scrutinee: bool`. We know that the pattern is `true`,
+                    // so an error here would be a duplicate and from the wrong POV.
+                    s.is_desugaring(DesugaringKind::CondTemporary)
+                })
+                .is_some());
+        }
+
+        pat_ty
+    }
+
+
     fn borrow_pat_suggestion(
         &self,
         err: &mut DiagnosticBuilder<'_>,