@@ -68,49 +68,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
68
68
expected
69
69
}
70
70
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)
114
72
}
115
73
PatKind :: Range ( ref begin, ref end, _) => {
116
74
let lhs_ty = self . check_expr ( begin) ;
@@ -586,6 +544,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
586
544
( expected, def_bm)
587
545
}
588
546
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
+
589
601
fn borrow_pat_suggestion (
590
602
& self ,
591
603
err : & mut DiagnosticBuilder < ' _ > ,
0 commit comments