@@ -327,9 +327,23 @@ struct LiteralExpander;
327327impl < ' tcx >  PatternFolder < ' tcx >  for  LiteralExpander  { 
328328    fn  fold_pattern ( & mut  self ,  pat :  & Pat < ' tcx > )  -> Pat < ' tcx >  { 
329329        debug ! ( "fold_pattern {:?} {:?} {:?}" ,  pat,  pat. ty. kind( ) ,  pat. kind) ; 
330-         match  ( pat. ty . kind ( ) ,  & * pat. kind )  { 
331-             ( _,  & PatKind :: Binding  {  subpattern :  Some ( ref  s) ,  .. } )  => s. fold_with ( self ) , 
332-             ( _,  & PatKind :: AscribeUserType  {  subpattern :  ref  s,  .. } )  => s. fold_with ( self ) , 
330+         match  ( pat. ty . kind ( ) ,  pat. kind . as_ref ( ) )  { 
331+             ( _,  PatKind :: Binding  {  subpattern :  Some ( s) ,  .. } )  => s. fold_with ( self ) , 
332+             ( _,  PatKind :: AscribeUserType  {  subpattern :  s,  .. } )  => s. fold_with ( self ) , 
333+             ( ty:: Ref ( _,  t,  _) ,  PatKind :: Constant  {  .. } )  if  t. is_str ( )  => { 
334+                 // Treat string literal patterns as deref patterns to a `str` constant, i.e. 
335+                 // `&CONST`. This expands them like other const patterns. This could have been done 
336+                 // in `const_to_pat`, but that causes issues with the rest of the matching code. 
337+                 let  mut  new_pat = pat. super_fold_with ( self ) ; 
338+                 // Make a fake const pattern of type `str` (instead of `&str`). That the carried 
339+                 // constant value still knows it is of type `&str`. 
340+                 new_pat. ty  = t; 
341+                 Pat  { 
342+                     kind :  Box :: new ( PatKind :: Deref  {  subpattern :  new_pat } ) , 
343+                     span :  pat. span , 
344+                     ty :  pat. ty , 
345+                 } 
346+             } 
333347            _ => pat. super_fold_with ( self ) , 
334348        } 
335349    } 
@@ -782,11 +796,9 @@ enum Constructor<'tcx> {
782796     /// boxes for the purposes of exhaustiveness: we must not inspect them, and they 
783797     /// don't count towards making a match exhaustive. 
784798     Opaque , 
785-     /// Fake extra constructor for enums that aren't allowed to be matched exhaustively. 
799+     /// Fake extra constructor for enums that aren't allowed to be matched exhaustively. Also used 
800+      /// for those types for which we cannot list constructors explicitly, like `f64` and `str`. 
786801     NonExhaustive , 
787-     /// Fake constructor for those types for which we can't list constructors explicitly, like 
788-      /// `f64` and `&str`. 
789-      Unlistable , 
790802    /// Wildcard pattern. 
791803     Wildcard , 
792804} 
@@ -880,6 +892,7 @@ impl<'tcx> Constructor<'tcx> {
880892     /// For the simple cases, this is simply checking for equality. For the "grouped" constructors, 
881893     /// this checks for inclusion. 
882894     fn  is_covered_by < ' p > ( & self ,  pcx :  PatCtxt < ' _ ,  ' p ,  ' tcx > ,  other :  & Self )  -> bool  { 
895+         // This must be kept in sync with `is_covered_by_any`. 
883896        match  ( self ,  other)  { 
884897            // Wildcards cover anything 
885898            ( _,  Wildcard )  => true , 
@@ -922,18 +935,19 @@ impl<'tcx> Constructor<'tcx> {
922935            ( Opaque ,  _)  | ( _,  Opaque )  => false , 
923936            // Only a wildcard pattern can match the special extra constructor. 
924937            ( NonExhaustive ,  _)  => false , 
925-             // If we encounter a `Single` here, this means there was only one constructor for this 
926-             // type after all. 
927-             ( Unlistable ,  Single )  => true , 
928-             // Otherwise, only a wildcard pattern can match the special extra constructor. 
929-             ( Unlistable ,  _)  => false , 
930938
931-             _ => bug ! ( "trying to compare incompatible constructors {:?} and {:?}" ,  self ,  other) , 
939+             _ => span_bug ! ( 
940+                 pcx. span, 
941+                 "trying to compare incompatible constructors {:?} and {:?}" , 
942+                 self , 
943+                 other
944+             ) , 
932945        } 
933946    } 
934947
935948    /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is 
936-      /// assumed to be built from `matrix.head_ctors()`, and `self` is assumed to have been split. 
949+      /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is 
950+      /// assumed to have been split from a wildcard. 
937951     fn  is_covered_by_any < ' p > ( 
938952        & self , 
939953        pcx :  PatCtxt < ' _ ,  ' p ,  ' tcx > , 
@@ -943,8 +957,9 @@ impl<'tcx> Constructor<'tcx> {
943957            return  false ; 
944958        } 
945959
960+         // This must be kept in sync with `is_covered_by`. 
946961        match  self  { 
947-             // `used_ctors` cannot contain anything else than `Single`s. 
962+             // If `self` is `Single`,  `used_ctors` cannot contain anything else than `Single`s. 
948963            Single  => !used_ctors. is_empty ( ) , 
949964            Variant ( _)  => used_ctors. iter ( ) . any ( |c| c == self ) , 
950965            IntRange ( range)  => used_ctors
@@ -957,8 +972,6 @@ impl<'tcx> Constructor<'tcx> {
957972                . any ( |other| slice. is_covered_by ( other) ) , 
958973            // This constructor is never covered by anything else 
959974            NonExhaustive  => false , 
960-             // This constructor is only covered by `Single`s 
961-             Unlistable  => used_ctors. iter ( ) . any ( |c| * c == Single ) , 
962975            Str ( ..)  | FloatRange ( ..)  | Opaque  | Wildcard  => { 
963976                bug ! ( "found unexpected ctor in all_ctors: {:?}" ,  self ) 
964977            } 
@@ -1006,6 +1019,10 @@ impl<'tcx> Constructor<'tcx> {
10061019                        PatKind :: Leaf  {  subpatterns } 
10071020                    } 
10081021                } 
1022+                 // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should 
1023+                 // be careful to reconstruct the correct constant pattern here. However a string 
1024+                 // literal pattern will never be reported as a non-exhaustiveness witness, so we 
1025+                 // can ignore this issue. 
10091026                ty:: Ref ( ..)  => PatKind :: Deref  {  subpattern :  subpatterns. next ( ) . unwrap ( )  } , 
10101027                ty:: Slice ( _)  | ty:: Array ( ..)  => bug ! ( "bad slice pattern {:?} {:?}" ,  self ,  pcx. ty) , 
10111028                _ => PatKind :: Wild , 
@@ -1038,7 +1055,7 @@ impl<'tcx> Constructor<'tcx> {
10381055            & Str ( value)  => PatKind :: Constant  {  value } , 
10391056            & FloatRange ( lo,  hi,  end)  => PatKind :: Range ( PatRange  {  lo,  hi,  end } ) , 
10401057            IntRange ( range)  => return  range. to_pat ( pcx. cx . tcx ) , 
1041-             NonExhaustive  |  Unlistable   => PatKind :: Wild , 
1058+             NonExhaustive  => PatKind :: Wild , 
10421059            Opaque  => bug ! ( "we should not try to apply an opaque constructor" ) , 
10431060            Wildcard  => bug ! ( 
10441061                "trying to apply a wildcard constructor; this should have been done in `apply_constructors`" 
@@ -1187,8 +1204,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
11871204                } 
11881205                _ => bug ! ( "bad slice pattern {:?} {:?}" ,  constructor,  ty) , 
11891206            } , 
1190-             Str ( ..)  | FloatRange ( ..)  | IntRange ( ..)  | NonExhaustive  | Opaque  | Unlistable 
1191-             | Wildcard  => Fields :: empty ( ) , 
1207+             Str ( ..)  | FloatRange ( ..)  | IntRange ( ..)  | NonExhaustive  | Opaque  | Wildcard  => { 
1208+                 Fields :: empty ( ) 
1209+             } 
11921210        } ; 
11931211        debug ! ( "Fields::wildcards({:?}, {:?}) = {:#?}" ,  constructor,  ty,  ret) ; 
11941212        ret
@@ -1300,9 +1318,13 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
13001318     ///     [Some(0), ..] => {} 
13011319     /// } 
13021320     /// ``` 
1321+      /// This is guaranteed to preserve the number of patterns in `self`. 
13031322     fn  replace_with_pattern_arguments ( & self ,  pat :  & ' p  Pat < ' tcx > )  -> Self  { 
13041323        match  pat. kind . as_ref ( )  { 
1305-             PatKind :: Deref  {  subpattern }  => Self :: from_single_pattern ( subpattern) , 
1324+             PatKind :: Deref  {  subpattern }  => { 
1325+                 assert_eq ! ( self . len( ) ,  1 ) ; 
1326+                 Fields :: from_single_pattern ( subpattern) 
1327+             } 
13061328            PatKind :: Leaf  {  subpatterns }  | PatKind :: Variant  {  subpatterns,  .. }  => { 
13071329                self . replace_with_fieldpats ( subpatterns) 
13081330            } 
@@ -1590,10 +1612,9 @@ fn all_constructors<'p, 'tcx>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Vec<Constructor<'tc
15901612            vec ! [ make_range( 0 ,  max) ] 
15911613        } 
15921614        _ if  cx. is_uninhabited ( pcx. ty )  => vec ! [ ] , 
1593-         ty:: Adt ( ..)  | ty:: Tuple ( ..)  => vec ! [ Single ] , 
1594-         ty:: Ref ( _,  t,  _)  if  !t. is_str ( )  => vec ! [ Single ] , 
1595-         // This type is one for which we don't know how to list constructors, like `&str` or `f64`. 
1596-         _ => vec ! [ Unlistable ] , 
1615+         ty:: Adt ( ..)  | ty:: Tuple ( ..)  | ty:: Ref ( ..)  => vec ! [ Single ] , 
1616+         // This type is one for which we cannot list constructors, like `str` or `f64`. 
1617+         _ => vec ! [ NonExhaustive ] , 
15971618    } 
15981619} 
15991620
@@ -2152,28 +2173,31 @@ fn pat_constructor<'p, 'tcx>(
21522173    cx :  & MatchCheckCtxt < ' p ,  ' tcx > , 
21532174    pat :  & ' p  Pat < ' tcx > , 
21542175)  -> Constructor < ' tcx >  { 
2155-     match  * pat. kind  { 
2176+     match  pat. kind . as_ref ( )  { 
21562177        PatKind :: AscribeUserType  {  .. }  => bug ! ( ) ,  // Handled by `expand_pattern` 
21572178        PatKind :: Binding  {  .. }  | PatKind :: Wild  => Wildcard , 
21582179        PatKind :: Leaf  {  .. }  | PatKind :: Deref  {  .. }  => Single , 
2159-         PatKind :: Variant  {  adt_def,  variant_index,  .. }  => { 
2180+         & PatKind :: Variant  {  adt_def,  variant_index,  .. }  => { 
21602181            Variant ( adt_def. variants [ variant_index] . def_id ) 
21612182        } 
21622183        PatKind :: Constant  {  value }  => { 
21632184            if  let  Some ( int_range)  = IntRange :: from_const ( cx. tcx ,  cx. param_env ,  value,  pat. span )  { 
21642185                IntRange ( int_range) 
21652186            }  else  { 
2166-                 match  value . ty . kind ( )  { 
2187+                 match  pat . ty . kind ( )  { 
21672188                    ty:: Float ( _)  => FloatRange ( value,  value,  RangeEnd :: Included ) , 
2168-                     ty:: Ref ( _,  t,  _)  if  t. is_str ( )  => Str ( value) , 
2189+                     // In `expand_pattern`, we convert string literals to `&CONST` patterns with 
2190+                     // `CONST` a pattern of type `str`. In truth this contains a constant of type 
2191+                     // `&str`. 
2192+                     ty:: Str  => Str ( value) , 
21692193                    // All constants that can be structurally matched have already been expanded 
21702194                    // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are 
21712195                    // opaque. 
21722196                    _ => Opaque , 
21732197                } 
21742198            } 
21752199        } 
2176-         PatKind :: Range ( PatRange  {  lo,  hi,  end } )  => { 
2200+         & PatKind :: Range ( PatRange  {  lo,  hi,  end } )  => { 
21772201            let  ty = lo. ty ; 
21782202            if  let  Some ( int_range)  = IntRange :: from_range ( 
21792203                cx. tcx , 
@@ -2188,8 +2212,7 @@ fn pat_constructor<'p, 'tcx>(
21882212                FloatRange ( lo,  hi,  end) 
21892213            } 
21902214        } 
2191-         PatKind :: Array  {  ref  prefix,  ref  slice,  ref  suffix } 
2192-         | PatKind :: Slice  {  ref  prefix,  ref  slice,  ref  suffix }  => { 
2215+         PatKind :: Array  {  prefix,  slice,  suffix }  | PatKind :: Slice  {  prefix,  slice,  suffix }  => { 
21932216            let  array_len = match  pat. ty . kind ( )  { 
21942217                ty:: Array ( _,  length)  => Some ( length. eval_usize ( cx. tcx ,  cx. param_env ) ) , 
21952218                ty:: Slice ( _)  => None , 
0 commit comments