@@ -650,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
650650 match & pat. kind {
651651 // Type checking these product-like types successfully always require
652652 // that the expected type be of those types and not reference types.
653- PatKind :: Tuple ( ..)
654- | PatKind :: Range ( ..)
655- | PatKind :: Slice ( ..) => AdjustMode :: peel_all ( ) ,
653+ PatKind :: Tuple ( ..) | PatKind :: Range ( ..) | PatKind :: Slice ( ..) => AdjustMode :: peel_all ( ) ,
656654 // When checking an explicit deref pattern, only peel reference types.
657655 // FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
658656 // patterns may want `PeelKind::Implicit`, stopping on encountering a box.
659- | PatKind :: Box ( _)
660- | PatKind :: Deref ( _) => AdjustMode :: Peel { kind : PeelKind :: ExplicitDerefPat } ,
657+ PatKind :: Box ( _) | PatKind :: Deref ( _) => {
658+ AdjustMode :: Peel { kind : PeelKind :: ExplicitDerefPat }
659+ }
661660 // A never pattern behaves somewhat like a literal or unit variant.
662661 PatKind :: Never => AdjustMode :: peel_all ( ) ,
663662 // For patterns with paths, how we peel the scrutinee depends on the path's resolution.
@@ -679,25 +678,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
679678 && self . tcx . features ( ) . deref_patterns ( )
680679 && !matches ! ( lt. kind, PatExprKind :: Lit { .. } )
681680 {
682- span_bug ! ( lt. span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}" , lt. kind) ;
681+ span_bug ! (
682+ lt. span,
683+ "FIXME(deref_patterns): adjust mode unimplemented for {:?}" ,
684+ lt. kind
685+ ) ;
683686 }
684687 // Call `resolve_vars_if_possible` here for inline const blocks.
685688 let lit_ty = self . resolve_vars_if_possible ( self . check_pat_expr_unadjusted ( lt) ) ;
686689 // If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`.
687690 if self . tcx . features ( ) . deref_patterns ( ) {
688691 let mut peeled_ty = lit_ty;
689692 let mut pat_ref_layers = 0 ;
690- while let ty:: Ref ( _, inner_ty, mutbl) = * peeled_ty. kind ( ) {
693+ while let ty:: Ref ( _, inner_ty, mutbl) =
694+ * self . try_structurally_resolve_type ( pat. span , peeled_ty) . kind ( )
695+ {
691696 // We rely on references at the head of constants being immutable.
692697 debug_assert ! ( mutbl. is_not( ) ) ;
693698 pat_ref_layers += 1 ;
694699 peeled_ty = inner_ty;
695700 }
696- AdjustMode :: Peel { kind : PeelKind :: Implicit { until_adt : None , pat_ref_layers } }
701+ AdjustMode :: Peel {
702+ kind : PeelKind :: Implicit { until_adt : None , pat_ref_layers } ,
703+ }
697704 } else {
698705 if lit_ty. is_ref ( ) { AdjustMode :: Pass } else { AdjustMode :: peel_all ( ) }
699706 }
700- } ,
707+ }
701708
702709 // Ref patterns are complicated, we handle them in `check_pat_ref`.
703710 PatKind :: Ref ( ..)
@@ -928,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
928935 // be peeled to `str` while ty here is still `&str`, if we don't
929936 // err early here, a rather confusing unification error will be
930937 // emitted instead).
938+ let ty = self . try_structurally_resolve_type ( expr. span , ty) ;
931939 let fail =
932940 !( ty. is_numeric ( ) || ty. is_char ( ) || ty. is_ty_var ( ) || ty. references_error ( ) ) ;
933941 Some ( ( fail, ty, expr. span ) )
0 commit comments