@@ -650,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
650
650
match & pat. kind {
651
651
// Type checking these product-like types successfully always require
652
652
// 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 ( ) ,
656
654
// When checking an explicit deref pattern, only peel reference types.
657
655
// FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
658
656
// 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
+ }
661
660
// A never pattern behaves somewhat like a literal or unit variant.
662
661
PatKind :: Never => AdjustMode :: peel_all ( ) ,
663
662
// 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> {
679
678
&& self . tcx . features ( ) . deref_patterns ( )
680
679
&& !matches ! ( lt. kind, PatExprKind :: Lit { .. } )
681
680
{
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
+ ) ;
683
686
}
684
687
// Call `resolve_vars_if_possible` here for inline const blocks.
685
688
let lit_ty = self . resolve_vars_if_possible ( self . check_pat_expr_unadjusted ( lt) ) ;
686
689
// If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`.
687
690
if self . tcx . features ( ) . deref_patterns ( ) {
688
691
let mut peeled_ty = lit_ty;
689
692
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
+ {
691
696
// We rely on references at the head of constants being immutable.
692
697
debug_assert ! ( mutbl. is_not( ) ) ;
693
698
pat_ref_layers += 1 ;
694
699
peeled_ty = inner_ty;
695
700
}
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
+ }
697
704
} else {
698
705
if lit_ty. is_ref ( ) { AdjustMode :: Pass } else { AdjustMode :: peel_all ( ) }
699
706
}
700
- } ,
707
+ }
701
708
702
709
// Ref patterns are complicated, we handle them in `check_pat_ref`.
703
710
PatKind :: Ref ( ..)
@@ -928,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
928
935
// be peeled to `str` while ty here is still `&str`, if we don't
929
936
// err early here, a rather confusing unification error will be
930
937
// emitted instead).
938
+ let ty = self . try_structurally_resolve_type ( expr. span , ty) ;
931
939
let fail =
932
940
!( ty. is_numeric ( ) || ty. is_char ( ) || ty. is_ty_var ( ) || ty. references_error ( ) ) ;
933
941
Some ( ( fail, ty, expr. span ) )
0 commit comments