@@ -66,9 +66,12 @@ pub enum categorization {
66
66
cat_local( ast:: node_id ) , // local variable
67
67
cat_arg( ast:: node_id ) , // formal argument
68
68
cat_deref( cmt , uint , ptr_kind ) , // deref of a ptr
69
- cat_interior( cmt , interior_kind ) , // something interior
69
+ cat_interior( cmt , InteriorKind ) , // something interior: field, tuple, etc
70
+ cat_downcast( cmt ) , // selects a particular enum variant (*)
70
71
cat_discr( cmt , ast:: node_id ) , // match discriminant (see preserve())
71
72
cat_self( ast:: node_id ) , // explicit `self`
73
+
74
+ // (*) downcast is only required if the enum has more than one variant
72
75
}
73
76
74
77
#[ deriving( Eq ) ]
@@ -89,14 +92,15 @@ pub enum ptr_kind {
89
92
// We use the term "interior" to mean "something reachable from the
90
93
// base without a pointer dereference", e.g. a field
91
94
#[ deriving( Eq ) ]
92
- pub enum interior_kind {
93
- interior_tuple, // elt in a tuple
94
- interior_anon_field, // anonymous field (in e.g.
95
- // struct Foo(int, int);
96
- interior_variant( ast:: def_id ) , // internals to a variant of given enum
97
- interior_field( ast:: ident ) , // name of field
98
- interior_index( ty:: t , // type of vec/str/etc being deref'd
99
- ast:: mutability ) // mutability of vec content
95
+ pub enum InteriorKind {
96
+ InteriorField ( FieldName ) ,
97
+ InteriorElement ( ty:: t ) , // ty::t is the type of the vec/str
98
+ }
99
+
100
+ #[ deriving( Eq ) ]
101
+ pub enum FieldName {
102
+ NamedField ( ast:: ident ) ,
103
+ PositionalField ( uint )
100
104
}
101
105
102
106
#[ deriving( Eq ) ]
@@ -134,7 +138,10 @@ pub type cmt = @cmt_;
134
138
135
139
// We pun on *T to mean both actual deref of a ptr as well
136
140
// as accessing of components:
137
- pub enum deref_kind { deref_ptr( ptr_kind ) , deref_interior( interior_kind ) }
141
+ pub enum deref_kind {
142
+ deref_ptr( ptr_kind ) ,
143
+ deref_interior( InteriorKind ) ,
144
+ }
138
145
139
146
// Categorizes a derefable type. Note that we include vectors and strings as
140
147
// derefable (we model an index as the combination of a deref and then a
@@ -176,20 +183,14 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
176
183
Some ( deref_ptr ( unsafe_ptr) )
177
184
}
178
185
179
- ty:: ty_enum( did, _) => {
180
- Some ( deref_interior ( interior_variant ( did) ) )
181
- }
182
-
183
- ty:: ty_struct( _, _) => {
184
- Some ( deref_interior ( interior_anon_field) )
185
- }
186
-
187
- ty:: ty_evec( mt, ty:: vstore_fixed( _) ) => {
188
- Some ( deref_interior ( interior_index ( t, mt. mutbl ) ) )
186
+ ty:: ty_enum( * ) |
187
+ ty:: ty_struct( * ) => { // newtype
188
+ Some ( deref_interior ( InteriorField ( PositionalField ( 0 ) ) ) )
189
189
}
190
190
191
+ ty:: ty_evec( _, ty:: vstore_fixed( _) ) |
191
192
ty:: ty_estr( ty:: vstore_fixed( _) ) => {
192
- Some ( deref_interior ( interior_index ( t , m_imm ) ) )
193
+ Some ( deref_interior ( InteriorElement ( t ) ) )
193
194
}
194
195
195
196
_ => None
@@ -579,7 +580,7 @@ pub impl mem_categorization_ctxt {
579
580
@cmt_ {
580
581
id : node. id ( ) ,
581
582
span : node. span ( ) ,
582
- cat : cat_interior ( base_cmt, interior_field ( f_name) ) ,
583
+ cat : cat_interior ( base_cmt, InteriorField ( NamedField ( f_name) ) ) ,
583
584
mutbl : base_cmt. mutbl . inherit ( ) ,
584
585
ty : f_ty
585
586
}
@@ -737,15 +738,16 @@ pub impl mem_categorization_ctxt {
737
738
}
738
739
} ;
739
740
740
- fn interior < N : ast_node > ( elt : N , of_cmt : cmt ,
741
- vect : ty:: t , mutbl : MutabilityCategory ,
741
+ fn interior < N : ast_node > ( elt : N ,
742
+ of_cmt : cmt ,
743
+ vec_ty : ty:: t ,
744
+ mutbl : MutabilityCategory ,
742
745
mt : ty:: mt ) -> cmt
743
746
{
744
- let interior = interior_index ( vect, mt. mutbl ) ;
745
747
@cmt_ {
746
748
id : elt. id ( ) ,
747
749
span : elt. span ( ) ,
748
- cat : cat_interior ( of_cmt, interior ) ,
750
+ cat : cat_interior ( of_cmt, InteriorElement ( vec_ty ) ) ,
749
751
mutbl : mutbl,
750
752
ty : mt. ty
751
753
}
@@ -756,7 +758,7 @@ pub impl mem_categorization_ctxt {
756
758
node : N ,
757
759
base_cmt : cmt ,
758
760
interior_ty : ty:: t ,
759
- interior : interior_kind ) -> cmt {
761
+ interior : InteriorKind ) -> cmt {
760
762
@cmt_ {
761
763
id : node. id ( ) ,
762
764
span : node. span ( ) ,
@@ -766,6 +768,19 @@ pub impl mem_categorization_ctxt {
766
768
}
767
769
}
768
770
771
+ fn cat_downcast < N : ast_node > ( & self ,
772
+ node : N ,
773
+ base_cmt : cmt ,
774
+ downcast_ty : ty:: t ) -> cmt {
775
+ @cmt_ {
776
+ id : node. id ( ) ,
777
+ span : node. span ( ) ,
778
+ cat : cat_downcast ( base_cmt) ,
779
+ mutbl : base_cmt. mutbl . inherit ( ) ,
780
+ ty : downcast_ty
781
+ }
782
+ }
783
+
769
784
fn cat_pattern ( & self ,
770
785
cmt : cmt ,
771
786
pat : @ast:: pat ,
@@ -835,21 +850,34 @@ pub impl mem_categorization_ctxt {
835
850
match self . tcx . def_map . find ( & pat. id ) {
836
851
Some ( & ast:: def_variant( enum_did, _) ) => {
837
852
// variant(x, y, z)
838
- for subpats. each |& subpat| {
853
+
854
+ let downcast_cmt = {
855
+ if ty:: enum_is_univariant ( tcx, enum_did) {
856
+ cmt // univariant, no downcast needed
857
+ } else {
858
+ self . cat_downcast ( pat, cmt, cmt. ty )
859
+ }
860
+ } ;
861
+
862
+ for subpats. eachi |i, & subpat| {
839
863
let subpat_ty = self . pat_ty ( subpat) ; // see (*)
864
+
840
865
let subcmt =
841
- self . cat_imm_interior ( pat, cmt, subpat_ty,
842
- interior_variant ( enum_did) ) ;
866
+ self . cat_imm_interior (
867
+ pat, downcast_cmt, subpat_ty,
868
+ InteriorField ( PositionalField ( i) ) ) ;
869
+
843
870
self . cat_pattern ( subcmt, subpat, op) ;
844
871
}
845
872
}
846
873
Some ( & ast:: def_fn( * ) ) |
847
874
Some ( & ast:: def_struct( * ) ) => {
848
- for subpats. each | & subpat| {
875
+ for subpats. eachi |i , & subpat| {
849
876
let subpat_ty = self . pat_ty ( subpat) ; // see (*)
850
877
let cmt_field =
851
- self . cat_imm_interior ( pat, cmt, subpat_ty,
852
- interior_anon_field) ;
878
+ self . cat_imm_interior (
879
+ pat, cmt, subpat_ty,
880
+ InteriorField ( PositionalField ( i) ) ) ;
853
881
self . cat_pattern ( cmt_field, subpat, op) ;
854
882
}
855
883
}
@@ -885,10 +913,12 @@ pub impl mem_categorization_ctxt {
885
913
886
914
ast:: pat_tup( ref subpats) => {
887
915
// (p1, ..., pN)
888
- for subpats. each | & subpat| {
916
+ for subpats. eachi |i , & subpat| {
889
917
let subpat_ty = self . pat_ty ( subpat) ; // see (*)
890
- let subcmt = self . cat_imm_interior ( pat, cmt, subpat_ty,
891
- interior_tuple) ;
918
+ let subcmt =
919
+ self . cat_imm_interior (
920
+ pat, cmt, subpat_ty,
921
+ InteriorField ( PositionalField ( i) ) ) ;
892
922
self . cat_pattern ( subcmt, subpat, op) ;
893
923
}
894
924
}
@@ -931,22 +961,37 @@ pub impl mem_categorization_ctxt {
931
961
932
962
fn cmt_to_str ( & self , cmt : cmt ) -> ~str {
933
963
match cmt. cat {
934
- cat_static_item => ~"static item",
935
- cat_implicit_self => ~"self reference",
964
+ cat_static_item => {
965
+ ~"static item"
966
+ }
967
+ cat_implicit_self => {
968
+ ~"self reference"
969
+ }
936
970
cat_copied_upvar( _) => {
937
971
~"captured outer variable in a heap closure"
938
972
}
939
- cat_rvalue => ~"non-lvalue",
940
- cat_local( _) => ~"local variable",
941
- cat_self( _) => ~"self value",
942
- cat_arg( * ) => ~"argument",
943
- cat_deref( _, _, pk) => fmt ! ( "dereference of %s pointer" ,
944
- ptr_sigil( pk) ) ,
945
- cat_interior( _, interior_field( * ) ) => ~"field",
946
- cat_interior( _, interior_tuple) => ~"tuple content",
947
- cat_interior( _, interior_anon_field) => ~"anonymous field",
948
- cat_interior( _, interior_variant( _) ) => ~"enum content",
949
- cat_interior( _, interior_index( t, _) ) => {
973
+ cat_rvalue => {
974
+ ~"non-lvalue"
975
+ }
976
+ cat_local( _) => {
977
+ ~"local variable"
978
+ }
979
+ cat_self( _) => {
980
+ ~"self value"
981
+ }
982
+ cat_arg( * ) => {
983
+ ~"argument"
984
+ }
985
+ cat_deref( _, _, pk) => {
986
+ fmt ! ( "dereference of %s pointer" , ptr_sigil( pk) )
987
+ }
988
+ cat_interior( _, InteriorField ( NamedField ( _) ) ) => {
989
+ ~"field"
990
+ }
991
+ cat_interior( _, InteriorField ( PositionalField ( _) ) ) => {
992
+ ~"anonymous field"
993
+ }
994
+ cat_interior( _, InteriorElement ( t) ) => {
950
995
match ty:: get ( t) . sty {
951
996
ty:: ty_evec( * ) => ~"vec content",
952
997
ty:: ty_estr( * ) => ~"str content",
@@ -959,6 +1004,9 @@ pub impl mem_categorization_ctxt {
959
1004
cat_discr( cmt, _) => {
960
1005
self . cmt_to_str ( cmt)
961
1006
}
1007
+ cat_downcast( cmt) => {
1008
+ self . cmt_to_str ( cmt)
1009
+ }
962
1010
}
963
1011
}
964
1012
@@ -1027,6 +1075,7 @@ pub impl cmt_ {
1027
1075
cat_deref( _, _, region_ptr( * ) ) => {
1028
1076
self
1029
1077
}
1078
+ cat_downcast( b) |
1030
1079
cat_stack_upvar( b) |
1031
1080
cat_discr( b, _) |
1032
1081
cat_interior( b, _) |
@@ -1075,6 +1124,7 @@ pub impl cmt_ {
1075
1124
Some ( AliasableBorrowed ( m) )
1076
1125
}
1077
1126
1127
+ cat_downcast( b) |
1078
1128
cat_stack_upvar( b) |
1079
1129
cat_deref( b, _, uniq_ptr( * ) ) |
1080
1130
cat_interior( b, _) |
@@ -1114,6 +1164,9 @@ impl Repr for categorization {
1114
1164
cmt. cat. repr( tcx) ,
1115
1165
interior. repr( tcx) )
1116
1166
}
1167
+ cat_downcast( cmt) => {
1168
+ fmt ! ( "%s->(enum)" , cmt. cat. repr( tcx) )
1169
+ }
1117
1170
cat_stack_upvar( cmt) |
1118
1171
cat_discr( cmt, _) => cmt. cat . repr ( tcx)
1119
1172
}
@@ -1129,14 +1182,12 @@ pub fn ptr_sigil(ptr: ptr_kind) -> ~str {
1129
1182
}
1130
1183
}
1131
1184
1132
- impl Repr for interior_kind {
1185
+ impl Repr for InteriorKind {
1133
1186
fn repr(&self, tcx: ty::ctxt) -> ~str {
1134
1187
match *self {
1135
- interior_field(fld) => copy *tcx.sess.str_of(fld),
1136
- interior_index(*) => ~" [ ] ",
1137
- interior_tuple => ~"( ) ",
1138
- interior_anon_field => ~"<anonymous field>",
1139
- interior_variant(_) => ~" <enum>"
1188
+ InteriorField(NamedField(fld)) => copy *tcx.sess.str_of(fld),
1189
+ InteriorField(PositionalField(i)) => fmt!(" #%?", i) ,
1190
+ InteriorElement ( _) => ~"[ ] ",
1140
1191
}
1141
1192
}
1142
1193
}
5 commit comments
bors commentedon May 21, 2013
saw approval from graydon
at nikomatsakis@5ca383b
bors commentedon May 21, 2013
merging nikomatsakis/rust/issue-5362-tuple-indices = 5ca383b into auto
bors commentedon May 21, 2013
nikomatsakis/rust/issue-5362-tuple-indices = 5ca383b merged ok, testing candidate = 32e30aa
bors commentedon May 21, 2013
all tests pass:
http://buildbot.rust-lang.org/builders/auto-linux/builds/1348
http://buildbot.rust-lang.org/builders/auto-win/builds/1343
http://buildbot.rust-lang.org/builders/auto-mac/builds/1361
bors commentedon May 21, 2013
fast-forwarding incoming to auto = 32e30aa