55//! This also includes code for pattern bindings in `let` statements and 
66//! function parameters. 
77
8+ use  std:: assert_matches:: assert_matches; 
9+ use  std:: borrow:: Borrow ; 
10+ use  std:: mem; 
11+ use  std:: sync:: Arc ; 
12+ 
813use  rustc_abi:: VariantIdx ; 
914use  rustc_data_structures:: fx:: FxIndexMap ; 
1015use  rustc_data_structures:: stack:: ensure_sufficient_stack; 
@@ -19,6 +24,7 @@ use tracing::{debug, instrument};
1924
2025use  crate :: builder:: ForGuard :: { self ,  OutsideGuard ,  RefWithinGuard } ; 
2126use  crate :: builder:: expr:: as_place:: PlaceBuilder ; 
27+ use  crate :: builder:: matches:: user_ty:: ProjectedUserTypesNode ; 
2228use  crate :: builder:: scope:: DropKind ; 
2329use  crate :: builder:: { 
2430    BlockAnd ,  BlockAndExtension ,  Builder ,  GuardFrame ,  GuardFrameLocal ,  LocalsForNode , 
@@ -27,13 +33,9 @@ use crate::builder::{
2733// helper functions, broken out by category: 
2834mod  match_pair; 
2935mod  test; 
36+ mod  user_ty; 
3037mod  util; 
3138
32- use  std:: assert_matches:: assert_matches; 
33- use  std:: borrow:: Borrow ; 
34- use  std:: mem; 
35- use  std:: sync:: Arc ; 
36- 
3739/// Arguments to [`Builder::then_else_break_inner`] that are usually forwarded 
3840/// to recursive invocations. 
3941#[ derive( Clone ,  Copy ) ]  
@@ -757,11 +759,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
757759    )  -> Option < SourceScope >  { 
758760        self . visit_primary_bindings_special ( 
759761            pattern, 
760-             UserTypeProjections :: none ( ) , 
761-             & mut  |this,  name,  mode,  var,  span,  ty,  user_ty | { 
762+             & ProjectedUserTypesNode :: None , 
763+             & mut  |this,  name,  mode,  var,  span,  ty,  user_tys | { 
762764                let  vis_scope = * visibility_scope
763765                    . get_or_insert_with ( || this. new_source_scope ( scope_span,  LintLevel :: Inherited ) ) ; 
764766                let  source_info = SourceInfo  {  span,  scope :  this. source_scope  } ; 
767+                 let  user_tys = user_tys. build_user_type_projections ( ) ; 
765768
766769                this. declare_binding ( 
767770                    source_info, 
@@ -770,7 +773,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
770773                    mode, 
771774                    var, 
772775                    ty, 
773-                     user_ty , 
776+                     user_tys , 
774777                    ArmHasGuard ( guard. is_some ( ) ) , 
775778                    opt_match_place. map ( |( x,  y) | ( x. cloned ( ) ,  y) ) , 
776779                    pattern. span , 
@@ -874,29 +877,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
874877    fn  visit_primary_bindings_special ( 
875878        & mut  self , 
876879        pattern :  & Pat < ' tcx > , 
877-         pattern_user_ty :   UserTypeProjections , 
880+         user_tys :   & ProjectedUserTypesNode < ' _ > , 
878881        f :  & mut  impl  FnMut ( 
879882            & mut  Self , 
880883            Symbol , 
881884            BindingMode , 
882885            LocalVarId , 
883886            Span , 
884887            Ty < ' tcx > , 
885-             UserTypeProjections , 
888+             & ProjectedUserTypesNode < ' _ > , 
886889        ) , 
887890    )  { 
888891        // Avoid having to write the full method name at each recursive call. 
889-         let  visit_subpat = |this :  & mut  Self ,  subpat,  user_tys,  f :  & mut  _ | { 
892+         let  visit_subpat = |this :  & mut  Self ,  subpat,  user_tys :   & _ ,  f :  & mut  _ | { 
890893            this. visit_primary_bindings_special ( subpat,  user_tys,  f) 
891894        } ; 
892895
893896        match  pattern. kind  { 
894897            PatKind :: Binding  {  name,  mode,  var,  ty,  ref  subpattern,  is_primary,  .. }  => { 
895898                if  is_primary { 
896-                     f ( self ,  name,  mode,  var,  pattern. span ,  ty,  pattern_user_ty . clone ( ) ) ; 
899+                     f ( self ,  name,  mode,  var,  pattern. span ,  ty,  user_tys ) ; 
897900                } 
898901                if  let  Some ( subpattern)  = subpattern. as_ref ( )  { 
899-                     visit_subpat ( self ,  subpattern,  pattern_user_ty ,  f) ; 
902+                     visit_subpat ( self ,  subpattern,  user_tys ,  f) ; 
900903                } 
901904            } 
902905
@@ -905,13 +908,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
905908                let  from = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ; 
906909                let  to = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ; 
907910                for  subpattern in  prefix. iter ( )  { 
908-                     visit_subpat ( self ,  subpattern,  pattern_user_ty . clone ( ) . index ( ) ,  f) ; 
911+                     visit_subpat ( self ,  subpattern,  & user_tys . index ( ) ,  f) ; 
909912                } 
910913                if  let  Some ( subpattern)  = slice { 
911-                     visit_subpat ( self ,  subpattern,  pattern_user_ty . clone ( ) . subslice ( from,  to) ,  f) ; 
914+                     visit_subpat ( self ,  subpattern,  & user_tys . subslice ( from,  to) ,  f) ; 
912915                } 
913916                for  subpattern in  suffix. iter ( )  { 
914-                     visit_subpat ( self ,  subpattern,  pattern_user_ty . clone ( ) . index ( ) ,  f) ; 
917+                     visit_subpat ( self ,  subpattern,  & user_tys . index ( ) ,  f) ; 
915918                } 
916919            } 
917920
@@ -922,11 +925,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
922925            | PatKind :: Error ( _)  => { } 
923926
924927            PatKind :: Deref  {  ref  subpattern }  => { 
925-                 visit_subpat ( self ,  subpattern,  pattern_user_ty . deref ( ) ,  f) ; 
928+                 visit_subpat ( self ,  subpattern,  & user_tys . deref ( ) ,  f) ; 
926929            } 
927930
928931            PatKind :: DerefPattern  {  ref  subpattern,  .. }  => { 
929-                 visit_subpat ( self ,  subpattern,  UserTypeProjections :: none ( ) ,  f) ; 
932+                 visit_subpat ( self ,  subpattern,  & ProjectedUserTypesNode :: None ,  f) ; 
930933            } 
931934
932935            PatKind :: AscribeUserType  { 
@@ -942,28 +945,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
942945                // Note that the variance doesn't apply here, as we are tracking the effect 
943946                // of `user_ty` on any bindings contained with subpattern. 
944947
948+                 // Caution: Pushing this user type here is load-bearing even for 
949+                 // patterns containing no bindings, to ensure that the type ends 
950+                 // up represented in MIR _somewhere_. 
945951                let  base_user_ty = self . canonical_user_type_annotations . push ( annotation. clone ( ) ) ; 
946-                 let  subpattern_user_ty  = pattern_user_ty . push_user_type ( base_user_ty) ; 
947-                 visit_subpat ( self ,  subpattern,  subpattern_user_ty ,  f) 
952+                 let  subpattern_user_tys  = user_tys . push_user_type ( base_user_ty) ; 
953+                 visit_subpat ( self ,  subpattern,  & subpattern_user_tys ,  f) 
948954            } 
949955
950956            PatKind :: ExpandedConstant  {  ref  subpattern,  .. }  => { 
951-                 visit_subpat ( self ,  subpattern,  pattern_user_ty ,  f) 
957+                 visit_subpat ( self ,  subpattern,  user_tys ,  f) 
952958            } 
953959
954960            PatKind :: Leaf  {  ref  subpatterns }  => { 
955961                for  subpattern in  subpatterns { 
956-                     let  subpattern_user_ty  = pattern_user_ty . clone ( ) . leaf ( subpattern. field ) ; 
957-                     debug ! ( "visit_primary_bindings: subpattern_user_ty={ :?}" ,  subpattern_user_ty ) ; 
958-                     visit_subpat ( self ,  & subpattern. pattern ,  subpattern_user_ty ,  f) ; 
962+                     let  subpattern_user_tys  = user_tys . leaf ( subpattern. field ) ; 
963+                     debug ! ( "visit_primary_bindings: subpattern_user_tys={subpattern_user_tys :?}" ) ; 
964+                     visit_subpat ( self ,  & subpattern. pattern ,  & subpattern_user_tys ,  f) ; 
959965                } 
960966            } 
961967
962968            PatKind :: Variant  {  adt_def,  args :  _,  variant_index,  ref  subpatterns }  => { 
963969                for  subpattern in  subpatterns { 
964-                     let  subpattern_user_ty  =
965-                         pattern_user_ty . clone ( ) . variant ( adt_def,  variant_index,  subpattern. field ) ; 
966-                     visit_subpat ( self ,  & subpattern. pattern ,  subpattern_user_ty ,  f) ; 
970+                     let  subpattern_user_tys  =
971+                         user_tys . variant ( adt_def,  variant_index,  subpattern. field ) ; 
972+                     visit_subpat ( self ,  & subpattern. pattern ,  & subpattern_user_tys ,  f) ; 
967973                } 
968974            } 
969975            PatKind :: Or  {  ref  pats }  => { 
@@ -972,7 +978,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
972978                // `let (x | y) = ...`, the primary binding of `y` occurs in 
973979                // the right subpattern 
974980                for  subpattern in  pats. iter ( )  { 
975-                     visit_subpat ( self ,  subpattern,  pattern_user_ty . clone ( ) ,  f) ; 
981+                     visit_subpat ( self ,  subpattern,  user_tys ,  f) ; 
976982                } 
977983            } 
978984        } 
@@ -2764,7 +2770,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
27642770        mode :  BindingMode , 
27652771        var_id :  LocalVarId , 
27662772        var_ty :  Ty < ' tcx > , 
2767-         user_ty :  UserTypeProjections , 
2773+         user_ty :  Option < Box < UserTypeProjections > > , 
27682774        has_guard :  ArmHasGuard , 
27692775        opt_match_place :  Option < ( Option < Place < ' tcx > > ,  Span ) > , 
27702776        pat_span :  Span , 
@@ -2774,7 +2780,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
27742780        let  local = LocalDecl  { 
27752781            mutability :  mode. 1 , 
27762782            ty :  var_ty, 
2777-             user_ty :   if  user_ty . is_empty ( )   {   None   }   else   {   Some ( Box :: new ( user_ty ) )   } , 
2783+             user_ty, 
27782784            source_info, 
27792785            local_info :  ClearCrossCrate :: Set ( Box :: new ( LocalInfo :: User ( BindingForm :: Var ( 
27802786                VarBindingForm  { 
0 commit comments