Skip to content

Commit d891e70

Browse files
committed
typeck/pat.rs: extract check_pat_lit.
1 parent 23dc37d commit d891e70

File tree

1 file changed

+55
-43
lines changed
  • src/librustc_typeck/check

1 file changed

+55
-43
lines changed

src/librustc_typeck/check/pat.rs

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -68,49 +68,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6868
expected
6969
}
7070
PatKind::Lit(ref lt) => {
71-
// We've already computed the type above (when checking for a non-ref pat), so
72-
// avoid computing it again.
73-
let ty = self.node_ty(lt.hir_id);
74-
75-
// Byte string patterns behave the same way as array patterns
76-
// They can denote both statically and dynamically-sized byte arrays.
77-
let mut pat_ty = ty;
78-
if let hir::ExprKind::Lit(ref lt) = lt.node {
79-
if let ast::LitKind::ByteStr(_) = lt.node {
80-
let expected_ty = self.structurally_resolved_type(pat.span, expected);
81-
if let ty::Ref(_, r_ty, _) = expected_ty.sty {
82-
if let ty::Slice(_) = r_ty.sty {
83-
pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
84-
tcx.mk_slice(tcx.types.u8))
85-
}
86-
}
87-
}
88-
}
89-
90-
// Somewhat surprising: in this case, the subtyping
91-
// relation goes the opposite way as the other
92-
// cases. Actually what we really want is not a subtyping
93-
// relation at all but rather that there exists a LUB (so
94-
// that they can be compared). However, in practice,
95-
// constants are always scalars or strings. For scalars
96-
// subtyping is irrelevant, and for strings `ty` is
97-
// type is `&'static str`, so if we say that
98-
//
99-
// &'static str <: expected
100-
//
101-
// then that's equivalent to there existing a LUB.
102-
if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
103-
err.emit_unless(discrim_span
104-
.filter(|&s| {
105-
// In the case of `if`- and `while`-expressions we've already checked
106-
// that `scrutinee: bool`. We know that the pattern is `true`,
107-
// so an error here would be a duplicate and from the wrong POV.
108-
s.is_desugaring(DesugaringKind::CondTemporary)
109-
})
110-
.is_some());
111-
}
112-
113-
pat_ty
71+
self.check_pat_lit(pat.span, lt, expected, discrim_span)
11472
}
11573
PatKind::Range(ref begin, ref end, _) => {
11674
let lhs_ty = self.check_expr(begin);
@@ -586,6 +544,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
586544
(expected, def_bm)
587545
}
588546

547+
fn check_pat_lit(
548+
&self,
549+
span: Span,
550+
lt: &hir::Expr,
551+
expected: Ty<'tcx>,
552+
discrim_span: Option<Span>,
553+
) -> Ty<'tcx> {
554+
// We've already computed the type above (when checking for a non-ref pat),
555+
// so avoid computing it again.
556+
let ty = self.node_ty(lt.hir_id);
557+
558+
// Byte string patterns behave the same way as array patterns
559+
// They can denote both statically and dynamically-sized byte arrays.
560+
let mut pat_ty = ty;
561+
if let hir::ExprKind::Lit(ref lt) = lt.node {
562+
if let ast::LitKind::ByteStr(_) = lt.node {
563+
let expected_ty = self.structurally_resolved_type(span, expected);
564+
if let ty::Ref(_, r_ty, _) = expected_ty.sty {
565+
if let ty::Slice(_) = r_ty.sty {
566+
let tcx = self.tcx;
567+
pat_ty = tcx.mk_imm_ref(
568+
tcx.lifetimes.re_static,
569+
tcx.mk_slice(tcx.types.u8),
570+
);
571+
}
572+
}
573+
}
574+
}
575+
576+
// Somewhat surprising: in this case, the subtyping relation goes the
577+
// opposite way as the other cases. Actually what we really want is not
578+
// a subtyping relation at all but rather that there exists a LUB
579+
// (so that they can be compared). However, in practice, constants are
580+
// always scalars or strings. For scalars subtyping is irrelevant,
581+
// and for strings `ty` is type is `&'static str`, so if we say that
582+
//
583+
// &'static str <: expected
584+
//
585+
// then that's equivalent to there existing a LUB.
586+
if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
587+
err.emit_unless(discrim_span
588+
.filter(|&s| {
589+
// In the case of `if`- and `while`-expressions we've already checked
590+
// that `scrutinee: bool`. We know that the pattern is `true`,
591+
// so an error here would be a duplicate and from the wrong POV.
592+
s.is_desugaring(DesugaringKind::CondTemporary)
593+
})
594+
.is_some());
595+
}
596+
597+
pat_ty
598+
}
599+
600+
589601
fn borrow_pat_suggestion(
590602
&self,
591603
err: &mut DiagnosticBuilder<'_>,

0 commit comments

Comments
 (0)