@@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer};
1111use  rustc_errors:: codes:: * ; 
1212use  rustc_hir:: def:: { CtorOf ,  DefKind ,  Res } ; 
1313use  rustc_hir:: pat_util:: EnumerateAndAdjustIterator ; 
14- use  rustc_hir:: { self  as  hir,  RangeEnd } ; 
14+ use  rustc_hir:: { self  as  hir,  LangItem ,   RangeEnd } ; 
1515use  rustc_index:: Idx ; 
1616use  rustc_middle:: mir:: interpret:: LitToConstInput ; 
1717use  rustc_middle:: thir:: { 
@@ -650,7 +650,26 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
650650        // the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the 
651651        // pattern's type means we'll properly translate it to a slice reference pattern. This works 
652652        // because slices and arrays have the same valtree representation. 
653-         let  ct_ty = pat_ty. unwrap_or_else ( || self . typeck_results . node_type ( expr. hir_id ) ) ; 
653+         // HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if 
654+         // `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR. 
655+         // FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is 
656+         // superseded by a more general implementation of deref patterns. 
657+         let  ct_ty = match  pat_ty { 
658+             Some ( pat_ty) 
659+                 if  let  ty:: Adt ( def,  _)  = * pat_ty. kind ( ) 
660+                     && self . tcx . is_lang_item ( def. did ( ) ,  LangItem :: String )  =>
661+             { 
662+                 if  !self . tcx . features ( ) . string_deref_patterns ( )  { 
663+                     span_bug ! ( 
664+                         expr. span, 
665+                         "matching on `String` went through without enabling string_deref_patterns" 
666+                     ) ; 
667+                 } 
668+                 self . typeck_results . node_type ( expr. hir_id ) 
669+             } 
670+             Some ( pat_ty)  => pat_ty, 
671+             None  => self . typeck_results . node_type ( expr. hir_id ) , 
672+         } ; 
654673        let  lit_input = LitToConstInput  {  lit :  & lit. node ,  ty :  ct_ty,  neg } ; 
655674        let  constant = self . tcx . at ( expr. span ) . lit_to_const ( lit_input) ; 
656675        self . const_to_pat ( constant,  ct_ty,  expr. hir_id ,  lit. span ) . kind 
0 commit comments