5
5
//! This also includes code for pattern bindings in `let` statements and
6
6
//! function parameters.
7
7
8
+ use std:: assert_matches:: assert_matches;
9
+ use std:: borrow:: Borrow ;
10
+ use std:: mem;
11
+ use std:: sync:: Arc ;
12
+
8
13
use rustc_abi:: VariantIdx ;
9
14
use rustc_data_structures:: fx:: FxIndexMap ;
10
15
use rustc_data_structures:: stack:: ensure_sufficient_stack;
@@ -19,6 +24,7 @@ use tracing::{debug, instrument};
19
24
20
25
use crate :: builder:: ForGuard :: { self , OutsideGuard , RefWithinGuard } ;
21
26
use crate :: builder:: expr:: as_place:: PlaceBuilder ;
27
+ use crate :: builder:: matches:: user_ty:: ProjectedUserTypesNode ;
22
28
use crate :: builder:: scope:: DropKind ;
23
29
use crate :: builder:: {
24
30
BlockAnd , BlockAndExtension , Builder , GuardFrame , GuardFrameLocal , LocalsForNode ,
@@ -27,13 +33,9 @@ use crate::builder::{
27
33
// helper functions, broken out by category:
28
34
mod match_pair;
29
35
mod test;
36
+ mod user_ty;
30
37
mod util;
31
38
32
- use std:: assert_matches:: assert_matches;
33
- use std:: borrow:: Borrow ;
34
- use std:: mem;
35
- use std:: sync:: Arc ;
36
-
37
39
/// Arguments to [`Builder::then_else_break_inner`] that are usually forwarded
38
40
/// to recursive invocations.
39
41
#[ derive( Clone , Copy ) ]
@@ -757,11 +759,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
757
759
) -> Option < SourceScope > {
758
760
self . visit_primary_bindings_special (
759
761
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 | {
762
764
let vis_scope = * visibility_scope
763
765
. get_or_insert_with ( || this. new_source_scope ( scope_span, LintLevel :: Inherited ) ) ;
764
766
let source_info = SourceInfo { span, scope : this. source_scope } ;
767
+ let user_tys = user_tys. build_user_type_projections ( ) ;
765
768
766
769
this. declare_binding (
767
770
source_info,
@@ -770,7 +773,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
770
773
mode,
771
774
var,
772
775
ty,
773
- user_ty ,
776
+ user_tys ,
774
777
ArmHasGuard ( guard. is_some ( ) ) ,
775
778
opt_match_place. map ( |( x, y) | ( x. cloned ( ) , y) ) ,
776
779
pattern. span ,
@@ -874,29 +877,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
874
877
fn visit_primary_bindings_special (
875
878
& mut self ,
876
879
pattern : & Pat < ' tcx > ,
877
- pattern_user_ty : UserTypeProjections ,
880
+ user_tys : & ProjectedUserTypesNode < ' _ > ,
878
881
f : & mut impl FnMut (
879
882
& mut Self ,
880
883
Symbol ,
881
884
BindingMode ,
882
885
LocalVarId ,
883
886
Span ,
884
887
Ty < ' tcx > ,
885
- UserTypeProjections ,
888
+ & ProjectedUserTypesNode < ' _ > ,
886
889
) ,
887
890
) {
888
891
// 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 _ | {
890
893
this. visit_primary_bindings_special ( subpat, user_tys, f)
891
894
} ;
892
895
893
896
match pattern. kind {
894
897
PatKind :: Binding { name, mode, var, ty, ref subpattern, is_primary, .. } => {
895
898
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 ) ;
897
900
}
898
901
if let Some ( subpattern) = subpattern. as_ref ( ) {
899
- visit_subpat ( self , subpattern, pattern_user_ty , f) ;
902
+ visit_subpat ( self , subpattern, user_tys , f) ;
900
903
}
901
904
}
902
905
@@ -905,13 +908,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
905
908
let from = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
906
909
let to = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
907
910
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) ;
909
912
}
910
913
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) ;
912
915
}
913
916
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) ;
915
918
}
916
919
}
917
920
@@ -922,11 +925,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
922
925
| PatKind :: Error ( _) => { }
923
926
924
927
PatKind :: Deref { ref subpattern } => {
925
- visit_subpat ( self , subpattern, pattern_user_ty . deref ( ) , f) ;
928
+ visit_subpat ( self , subpattern, & user_tys . deref ( ) , f) ;
926
929
}
927
930
928
931
PatKind :: DerefPattern { ref subpattern, .. } => {
929
- visit_subpat ( self , subpattern, UserTypeProjections :: none ( ) , f) ;
932
+ visit_subpat ( self , subpattern, & ProjectedUserTypesNode :: None , f) ;
930
933
}
931
934
932
935
PatKind :: AscribeUserType {
@@ -942,28 +945,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
942
945
// Note that the variance doesn't apply here, as we are tracking the effect
943
946
// of `user_ty` on any bindings contained with subpattern.
944
947
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_.
945
951
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)
948
954
}
949
955
950
956
PatKind :: ExpandedConstant { ref subpattern, .. } => {
951
- visit_subpat ( self , subpattern, pattern_user_ty , f)
957
+ visit_subpat ( self , subpattern, user_tys , f)
952
958
}
953
959
954
960
PatKind :: Leaf { ref subpatterns } => {
955
961
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) ;
959
965
}
960
966
}
961
967
962
968
PatKind :: Variant { adt_def, args : _, variant_index, ref subpatterns } => {
963
969
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) ;
967
973
}
968
974
}
969
975
PatKind :: Or { ref pats } => {
@@ -972,7 +978,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
972
978
// `let (x | y) = ...`, the primary binding of `y` occurs in
973
979
// the right subpattern
974
980
for subpattern in pats. iter ( ) {
975
- visit_subpat ( self , subpattern, pattern_user_ty . clone ( ) , f) ;
981
+ visit_subpat ( self , subpattern, user_tys , f) ;
976
982
}
977
983
}
978
984
}
@@ -2764,7 +2770,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2764
2770
mode : BindingMode ,
2765
2771
var_id : LocalVarId ,
2766
2772
var_ty : Ty < ' tcx > ,
2767
- user_ty : UserTypeProjections ,
2773
+ user_ty : Option < Box < UserTypeProjections > > ,
2768
2774
has_guard : ArmHasGuard ,
2769
2775
opt_match_place : Option < ( Option < Place < ' tcx > > , Span ) > ,
2770
2776
pat_span : Span ,
@@ -2774,7 +2780,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2774
2780
let local = LocalDecl {
2775
2781
mutability : mode. 1 ,
2776
2782
ty : var_ty,
2777
- user_ty : if user_ty . is_empty ( ) { None } else { Some ( Box :: new ( user_ty ) ) } ,
2783
+ user_ty,
2778
2784
source_info,
2779
2785
local_info : ClearCrossCrate :: Set ( Box :: new ( LocalInfo :: User ( BindingForm :: Var (
2780
2786
VarBindingForm {
0 commit comments