@@ -18,22 +18,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
1818 /// Converts an evaluated constant to a pattern (if possible).
1919 /// This means aggregate values (like structs and enums) are converted
2020 /// to a pattern that matches the value (as if you'd compared via structural equality).
21+ #[ instrument( skip( self ) ) ]
2122 pub ( super ) fn const_to_pat (
2223 & self ,
2324 cv : & ' tcx ty:: Const < ' tcx > ,
2425 id : hir:: HirId ,
2526 span : Span ,
2627 mir_structural_match_violation : bool ,
2728 ) -> Pat < ' tcx > {
28- debug ! ( "const_to_pat: cv={:#?} id={:?}" , cv, id) ;
29- debug ! ( "const_to_pat: cv.ty={:?} span={:?}" , cv. ty, span) ;
30-
3129 let pat = self . tcx . infer_ctxt ( ) . enter ( |infcx| {
3230 let mut convert = ConstToPat :: new ( self , id, span, infcx) ;
3331 convert. to_pat ( cv, mir_structural_match_violation)
3432 } ) ;
3533
36- debug ! ( "const_to_pat: pat={:?}" , pat) ;
34+ debug ! ( ? pat) ;
3735 pat
3836 }
3937}
@@ -61,6 +59,8 @@ struct ConstToPat<'a, 'tcx> {
6159 infcx : InferCtxt < ' a , ' tcx > ,
6260
6361 include_lint_checks : bool ,
62+
63+ treat_byte_string_as_slice : bool ,
6464}
6565
6666mod fallback_to_const_ref {
@@ -88,6 +88,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
8888 span : Span ,
8989 infcx : InferCtxt < ' a , ' tcx > ,
9090 ) -> Self {
91+ trace ! ( ?pat_ctxt. typeck_results. hir_owner) ;
9192 ConstToPat {
9293 id,
9394 span,
@@ -97,6 +98,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
9798 saw_const_match_error : Cell :: new ( false ) ,
9899 saw_const_match_lint : Cell :: new ( false ) ,
99100 behind_reference : Cell :: new ( false ) ,
101+ treat_byte_string_as_slice : pat_ctxt
102+ . typeck_results
103+ . treat_byte_string_as_slice
104+ . contains ( & id. local_id ) ,
100105 }
101106 }
102107
@@ -153,6 +158,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
153158 cv : & ' tcx ty:: Const < ' tcx > ,
154159 mir_structural_match_violation : bool ,
155160 ) -> Pat < ' tcx > {
161+ trace ! ( self . treat_byte_string_as_slice) ;
156162 // This method is just a wrapper handling a validity check; the heavy lifting is
157163 // performed by the recursive `recur` method, which is not meant to be
158164 // invoked except by this method.
@@ -384,7 +390,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
384390 }
385391 PatKind :: Wild
386392 }
387- // `&str` and `&[u8]` are represented as `ConstValue::Slice`, let's keep using this
393+ // `&str` is represented as `ConstValue::Slice`, let's keep using this
388394 // optimization for now.
389395 ty:: Str => PatKind :: Constant { value : cv } ,
390396 // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
@@ -393,11 +399,33 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
393399 // as slices. This means we turn `&[T; N]` constants into slice patterns, which
394400 // has no negative effects on pattern matching, even if we're actually matching on
395401 // arrays.
396- ty:: Array ( ..) |
402+ ty:: Array ( ..) if !self . treat_byte_string_as_slice => {
403+ let old = self . behind_reference . replace ( true ) ;
404+ let array = tcx. deref_const ( self . param_env . and ( cv) ) ;
405+ let val = PatKind :: Deref {
406+ subpattern : Pat {
407+ kind : Box :: new ( PatKind :: Array {
408+ prefix : tcx
409+ . destructure_const ( param_env. and ( array) )
410+ . fields
411+ . iter ( )
412+ . map ( |val| self . recur ( val, false ) )
413+ . collect :: < Result < _ , _ > > ( ) ?,
414+ slice : None ,
415+ suffix : vec ! [ ] ,
416+ } ) ,
417+ span,
418+ ty : pointee_ty,
419+ } ,
420+ } ;
421+ self . behind_reference . set ( old) ;
422+ val
423+ }
424+ ty:: Array ( elem_ty, _) |
397425 // Cannot merge this with the catch all branch below, because the `const_deref`
398426 // changes the type from slice to array, we need to keep the original type in the
399427 // pattern.
400- ty:: Slice ( .. ) => {
428+ ty:: Slice ( elem_ty ) => {
401429 let old = self . behind_reference . replace ( true ) ;
402430 let array = tcx. deref_const ( self . param_env . and ( cv) ) ;
403431 let val = PatKind :: Deref {
@@ -413,7 +441,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
413441 suffix : vec ! [ ] ,
414442 } ) ,
415443 span,
416- ty : pointee_ty ,
444+ ty : tcx . mk_slice ( elem_ty ) ,
417445 } ,
418446 } ;
419447 self . behind_reference . set ( old) ;
0 commit comments