@@ -759,19 +759,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
759759
760760 // Byte string patterns behave the same way as array patterns
761761 // They can denote both statically and dynamically-sized byte arrays.
762+ // Additionally, when `deref_patterns` is enabled, byte string literal patterns may have
763+ // types `[u8]` or `[u8; N]`, in order to type, e.g., `deref!(b"..."): Vec<u8>`.
762764 let mut pat_ty = ty;
763765 if let hir:: PatExprKind :: Lit {
764766 lit : Spanned { node : ast:: LitKind :: ByteStr ( ..) , .. } , ..
765767 } = lt. kind
766768 {
769+ let tcx = self . tcx ;
767770 let expected = self . structurally_resolve_type ( span, expected) ;
768- if let ty:: Ref ( _, inner_ty, _) = * expected. kind ( )
769- && self . try_structurally_resolve_type ( span, inner_ty) . is_slice ( )
770- {
771- let tcx = self . tcx ;
772- trace ! ( ?lt. hir_id. local_id, "polymorphic byte string lit" ) ;
773- pat_ty =
774- Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_static , Ty :: new_slice ( tcx, tcx. types . u8 ) ) ;
771+ match * expected. kind ( ) {
772+ // Allow `b"...": &[u8]`
773+ ty:: Ref ( _, inner_ty, _)
774+ if self . try_structurally_resolve_type ( span, inner_ty) . is_slice ( ) =>
775+ {
776+ trace ! ( ?lt. hir_id. local_id, "polymorphic byte string lit" ) ;
777+ pat_ty = Ty :: new_imm_ref (
778+ tcx,
779+ tcx. lifetimes . re_static ,
780+ Ty :: new_slice ( tcx, tcx. types . u8 ) ,
781+ ) ;
782+ }
783+ // Allow `b"...": [u8; 3]` for `deref_patterns`
784+ ty:: Array ( ..) if tcx. features ( ) . deref_patterns ( ) => {
785+ pat_ty = match * ty. kind ( ) {
786+ ty:: Ref ( _, inner_ty, _) => inner_ty,
787+ _ => span_bug ! ( span, "found byte string literal with non-ref type {ty:?}" ) ,
788+ }
789+ }
790+ // Allow `b"...": [u8]` for `deref_patterns`
791+ ty:: Slice ( ..) if tcx. features ( ) . deref_patterns ( ) => {
792+ pat_ty = Ty :: new_slice ( tcx, tcx. types . u8 ) ;
793+ }
794+ // Otherwise, `b"...": &[u8; 3]`
795+ _ => { }
775796 }
776797 }
777798
0 commit comments