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 ,
@@ -28,13 +34,9 @@ use crate::builder::{
28
34
mod match_pair;
29
35
mod simplify;
30
36
mod test;
37
+ mod user_ty;
31
38
mod util;
32
39
33
- use std:: assert_matches:: assert_matches;
34
- use std:: borrow:: Borrow ;
35
- use std:: mem;
36
- use std:: sync:: Arc ;
37
-
38
40
/// Arguments to [`Builder::then_else_break_inner`] that are usually forwarded
39
41
/// to recursive invocations.
40
42
#[ derive( Clone , Copy ) ]
@@ -758,11 +760,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
758
760
) -> Option < SourceScope > {
759
761
self . visit_primary_bindings_special (
760
762
pattern,
761
- UserTypeProjections :: none ( ) ,
762
- & mut |this, name, mode, var, span, ty, user_ty | {
763
+ & ProjectedUserTypesNode :: None ,
764
+ & mut |this, name, mode, var, span, ty, user_tys | {
763
765
let vis_scope = * visibility_scope
764
766
. get_or_insert_with ( || this. new_source_scope ( scope_span, LintLevel :: Inherited ) ) ;
765
767
let source_info = SourceInfo { span, scope : this. source_scope } ;
768
+ let user_tys = user_tys. build_user_type_projections ( ) ;
766
769
767
770
this. declare_binding (
768
771
source_info,
@@ -771,7 +774,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
771
774
mode,
772
775
var,
773
776
ty,
774
- user_ty ,
777
+ user_tys ,
775
778
ArmHasGuard ( guard. is_some ( ) ) ,
776
779
opt_match_place. map ( |( x, y) | ( x. cloned ( ) , y) ) ,
777
780
pattern. span ,
@@ -875,29 +878,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
875
878
fn visit_primary_bindings_special (
876
879
& mut self ,
877
880
pattern : & Pat < ' tcx > ,
878
- pattern_user_ty : UserTypeProjections ,
881
+ user_tys : & ProjectedUserTypesNode < ' _ > ,
879
882
f : & mut impl FnMut (
880
883
& mut Self ,
881
884
Symbol ,
882
885
BindingMode ,
883
886
LocalVarId ,
884
887
Span ,
885
888
Ty < ' tcx > ,
886
- UserTypeProjections ,
889
+ & ProjectedUserTypesNode < ' _ > ,
887
890
) ,
888
891
) {
889
892
// Avoid having to write the full method name at each recursive call.
890
- let visit_subpat = |this : & mut Self , subpat, user_tys, f : & mut _ | {
893
+ let visit_subpat = |this : & mut Self , subpat, user_tys : & _ , f : & mut _ | {
891
894
this. visit_primary_bindings_special ( subpat, user_tys, f)
892
895
} ;
893
896
894
897
match pattern. kind {
895
898
PatKind :: Binding { name, mode, var, ty, ref subpattern, is_primary, .. } => {
896
899
if is_primary {
897
- f ( self , name, mode, var, pattern. span , ty, pattern_user_ty . clone ( ) ) ;
900
+ f ( self , name, mode, var, pattern. span , ty, user_tys ) ;
898
901
}
899
902
if let Some ( subpattern) = subpattern. as_ref ( ) {
900
- visit_subpat ( self , subpattern, pattern_user_ty , f) ;
903
+ visit_subpat ( self , subpattern, user_tys , f) ;
901
904
}
902
905
}
903
906
@@ -906,13 +909,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
906
909
let from = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
907
910
let to = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
908
911
for subpattern in prefix. iter ( ) {
909
- visit_subpat ( self , subpattern, pattern_user_ty . clone ( ) . index ( ) , f) ;
912
+ visit_subpat ( self , subpattern, & user_tys . index ( ) , f) ;
910
913
}
911
914
if let Some ( subpattern) = slice {
912
- visit_subpat ( self , subpattern, pattern_user_ty . clone ( ) . subslice ( from, to) , f) ;
915
+ visit_subpat ( self , subpattern, & user_tys . subslice ( from, to) , f) ;
913
916
}
914
917
for subpattern in suffix. iter ( ) {
915
- visit_subpat ( self , subpattern, pattern_user_ty . clone ( ) . index ( ) , f) ;
918
+ visit_subpat ( self , subpattern, & user_tys . index ( ) , f) ;
916
919
}
917
920
}
918
921
@@ -923,11 +926,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
923
926
| PatKind :: Error ( _) => { }
924
927
925
928
PatKind :: Deref { ref subpattern } => {
926
- visit_subpat ( self , subpattern, pattern_user_ty . deref ( ) , f) ;
929
+ visit_subpat ( self , subpattern, & user_tys . deref ( ) , f) ;
927
930
}
928
931
929
932
PatKind :: DerefPattern { ref subpattern, .. } => {
930
- visit_subpat ( self , subpattern, UserTypeProjections :: none ( ) , f) ;
933
+ visit_subpat ( self , subpattern, & ProjectedUserTypesNode :: None , f) ;
931
934
}
932
935
933
936
PatKind :: AscribeUserType {
@@ -943,28 +946,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
943
946
// Note that the variance doesn't apply here, as we are tracking the effect
944
947
// of `user_ty` on any bindings contained with subpattern.
945
948
949
+ // Caution: Pushing this user type here is load-bearing even for
950
+ // patterns containing no bindings, to ensure that the type ends
951
+ // up represented in MIR _somewhere_.
946
952
let base_user_ty = self . canonical_user_type_annotations . push ( annotation. clone ( ) ) ;
947
- let subpattern_user_ty = pattern_user_ty . push_user_type ( base_user_ty) ;
948
- visit_subpat ( self , subpattern, subpattern_user_ty , f)
953
+ let subpattern_user_tys = user_tys . push_user_type ( base_user_ty) ;
954
+ visit_subpat ( self , subpattern, & subpattern_user_tys , f)
949
955
}
950
956
951
957
PatKind :: ExpandedConstant { ref subpattern, .. } => {
952
- visit_subpat ( self , subpattern, pattern_user_ty , f)
958
+ visit_subpat ( self , subpattern, user_tys , f)
953
959
}
954
960
955
961
PatKind :: Leaf { ref subpatterns } => {
956
962
for subpattern in subpatterns {
957
- let subpattern_user_ty = pattern_user_ty . clone ( ) . leaf ( subpattern. field ) ;
958
- debug ! ( "visit_primary_bindings: subpattern_user_ty={ :?}" , subpattern_user_ty ) ;
959
- visit_subpat ( self , & subpattern. pattern , subpattern_user_ty , f) ;
963
+ let subpattern_user_tys = user_tys . leaf ( subpattern. field ) ;
964
+ debug ! ( "visit_primary_bindings: subpattern_user_tys={subpattern_user_tys :?}" ) ;
965
+ visit_subpat ( self , & subpattern. pattern , & subpattern_user_tys , f) ;
960
966
}
961
967
}
962
968
963
969
PatKind :: Variant { adt_def, args : _, variant_index, ref subpatterns } => {
964
970
for subpattern in subpatterns {
965
- let subpattern_user_ty =
966
- pattern_user_ty . clone ( ) . variant ( adt_def, variant_index, subpattern. field ) ;
967
- visit_subpat ( self , & subpattern. pattern , subpattern_user_ty , f) ;
971
+ let subpattern_user_tys =
972
+ user_tys . variant ( adt_def, variant_index, subpattern. field ) ;
973
+ visit_subpat ( self , & subpattern. pattern , & subpattern_user_tys , f) ;
968
974
}
969
975
}
970
976
PatKind :: Or { ref pats } => {
@@ -973,7 +979,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
973
979
// `let (x | y) = ...`, the primary binding of `y` occurs in
974
980
// the right subpattern
975
981
for subpattern in pats. iter ( ) {
976
- visit_subpat ( self , subpattern, pattern_user_ty . clone ( ) , f) ;
982
+ visit_subpat ( self , subpattern, user_tys , f) ;
977
983
}
978
984
}
979
985
}
@@ -2781,7 +2787,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2781
2787
mode : BindingMode ,
2782
2788
var_id : LocalVarId ,
2783
2789
var_ty : Ty < ' tcx > ,
2784
- user_ty : UserTypeProjections ,
2790
+ user_ty : Option < Box < UserTypeProjections > > ,
2785
2791
has_guard : ArmHasGuard ,
2786
2792
opt_match_place : Option < ( Option < Place < ' tcx > > , Span ) > ,
2787
2793
pat_span : Span ,
@@ -2791,7 +2797,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2791
2797
let local = LocalDecl {
2792
2798
mutability : mode. 1 ,
2793
2799
ty : var_ty,
2794
- user_ty : if user_ty . is_empty ( ) { None } else { Some ( Box :: new ( user_ty ) ) } ,
2800
+ user_ty,
2795
2801
source_info,
2796
2802
local_info : ClearCrossCrate :: Set ( Box :: new ( LocalInfo :: User ( BindingForm :: Var (
2797
2803
VarBindingForm {
0 commit comments