@@ -31,6 +31,7 @@ use hir::def_id::DefId;
31
31
use hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
32
32
use hir:: { Block , Arm , Pat , PatKind , Stmt , Expr , Local } ;
33
33
use mir:: transform:: MirSource ;
34
+ use rustc_data_structures:: indexed_vec:: Idx ;
34
35
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher ,
35
36
StableHasherResult } ;
36
37
@@ -96,7 +97,12 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
96
97
/// actually attach a more meaningful ordering to scopes than the one
97
98
/// generated via deriving here.
98
99
#[ derive( Clone , PartialEq , PartialOrd , Eq , Ord , Hash , Debug , Copy , RustcEncodable , RustcDecodable ) ]
99
- pub enum Scope {
100
+ pub struct Scope {
101
+ pub scope_data : ScopeData
102
+ }
103
+
104
+ #[ derive( Clone , PartialEq , PartialOrd , Eq , Ord , Hash , Debug , Copy , RustcEncodable , RustcDecodable ) ]
105
+ pub enum ScopeData {
100
106
Node ( hir:: ItemLocalId ) ,
101
107
102
108
// Scope of the call-site for a function or closure
@@ -135,7 +141,64 @@ pub enum Scope {
135
141
RustcDecodable , Debug , Copy ) ]
136
142
pub struct BlockRemainder {
137
143
pub block : hir:: ItemLocalId ,
138
- pub first_statement_index : u32 ,
144
+ pub first_statement_index : FirstStatementIndex ,
145
+ }
146
+
147
+ #[ derive( Clone , PartialEq , PartialOrd , Eq , Ord , Hash , RustcEncodable ,
148
+ RustcDecodable , Debug , Copy ) ]
149
+ pub struct FirstStatementIndex { pub idx : u32 }
150
+
151
+ pub const FIRST_STATEMENT_MAX : usize = !0u32 as usize ;
152
+
153
+ impl Idx for FirstStatementIndex {
154
+ fn new ( idx : usize ) -> Self {
155
+ assert ! ( idx <= FIRST_STATEMENT_MAX ) ;
156
+ FirstStatementIndex { idx : idx as u32 }
157
+ }
158
+
159
+ fn index ( self ) -> usize {
160
+ self . idx as usize
161
+ }
162
+ }
163
+
164
+ impl From < ScopeData > for Scope {
165
+ #[ inline]
166
+ fn from ( scope_data : ScopeData ) -> Self {
167
+ Self { scope_data }
168
+ }
169
+ }
170
+
171
+ #[ allow( non_snake_case) ]
172
+ impl Scope {
173
+ #[ inline]
174
+ pub fn data ( self ) -> ScopeData {
175
+ self . scope_data
176
+ }
177
+
178
+ #[ inline]
179
+ pub fn Node ( id : hir:: ItemLocalId ) -> Self {
180
+ Self :: from ( ScopeData :: Node ( id) )
181
+ }
182
+
183
+ #[ inline]
184
+ pub fn CallSite ( id : hir:: ItemLocalId ) -> Self {
185
+ Self :: from ( ScopeData :: CallSite ( id) )
186
+ }
187
+
188
+ #[ inline]
189
+ pub fn Arguments ( id : hir:: ItemLocalId ) -> Self {
190
+ Self :: from ( ScopeData :: Arguments ( id) )
191
+ }
192
+
193
+ #[ inline]
194
+ pub fn Destruction ( id : hir:: ItemLocalId ) -> Self {
195
+ Self :: from ( ScopeData :: Destruction ( id) )
196
+ }
197
+
198
+ #[ inline]
199
+ pub fn Remainder ( r : BlockRemainder ) -> Self {
200
+ Self :: from ( ScopeData :: Remainder ( r) )
201
+ }
139
202
}
140
203
141
204
impl Scope {
@@ -144,15 +207,16 @@ impl Scope {
144
207
/// NB: likely to be replaced as API is refined; e.g. pnkfelix
145
208
/// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
146
209
pub fn item_local_id ( & self ) -> hir:: ItemLocalId {
147
- match * self {
148
- Scope :: Node ( id) => id,
210
+ // TODO: killme
211
+ match self . data ( ) {
212
+ ScopeData :: Node ( id) => id,
149
213
150
214
// These cases all return rough approximations to the
151
215
// precise scope denoted by `self`.
152
- Scope :: Remainder ( br) => br. block ,
153
- Scope :: Destruction ( id) |
154
- Scope :: CallSite ( id) |
155
- Scope :: Arguments ( id) => id,
216
+ ScopeData :: Remainder ( br) => br. block ,
217
+ ScopeData :: Destruction ( id) |
218
+ ScopeData :: CallSite ( id) |
219
+ ScopeData :: Arguments ( id) => id,
156
220
}
157
221
}
158
222
@@ -177,7 +241,7 @@ impl Scope {
177
241
return DUMMY_SP ;
178
242
}
179
243
let span = tcx. hir . span ( node_id) ;
180
- if let Scope :: Remainder ( r) = * self {
244
+ if let ScopeData :: Remainder ( r) = self . data ( ) {
181
245
if let hir:: map:: NodeBlock ( ref blk) = tcx. hir . get ( node_id) {
182
246
// Want span for scope starting after the
183
247
// indexed statement and ending at end of
@@ -187,7 +251,7 @@ impl Scope {
187
251
// (This is the special case aluded to in the
188
252
// doc-comment for this method)
189
253
190
- let stmt_span = blk. stmts [ r. first_statement_index as usize ] . span ;
254
+ let stmt_span = blk. stmts [ r. first_statement_index . index ( ) ] . span ;
191
255
192
256
// To avoid issues with macro-generated spans, the span
193
257
// of the statement must be nested in that of the block.
@@ -387,7 +451,7 @@ impl<'tcx> ScopeTree {
387
451
}
388
452
389
453
// record the destruction scopes for later so we can query them
390
- if let Scope :: Destruction ( n) = child {
454
+ if let ScopeData :: Destruction ( n) = child. data ( ) {
391
455
self . destruction_scopes . insert ( n, child) ;
392
456
}
393
457
}
@@ -482,8 +546,8 @@ impl<'tcx> ScopeTree {
482
546
let mut id = Scope :: Node ( expr_id) ;
483
547
484
548
while let Some ( & p) = self . parent_map . get ( & id) {
485
- match p {
486
- Scope :: Destruction ( ..) => {
549
+ match p. data ( ) {
550
+ ScopeData :: Destruction ( ..) => {
487
551
debug ! ( "temporary_scope({:?}) = {:?} [enclosing]" ,
488
552
expr_id, id) ;
489
553
return Some ( id) ;
@@ -573,9 +637,9 @@ impl<'tcx> ScopeTree {
573
637
// infer::region_inference for more details.
574
638
let a_root_scope = a_ancestors[ a_index] ;
575
639
let b_root_scope = a_ancestors[ a_index] ;
576
- return match ( a_root_scope, b_root_scope) {
577
- ( Scope :: Destruction ( a_root_id) ,
578
- Scope :: Destruction ( b_root_id) ) => {
640
+ return match ( a_root_scope. data ( ) , b_root_scope. data ( ) ) {
641
+ ( ScopeData :: Destruction ( a_root_id) ,
642
+ ScopeData :: Destruction ( b_root_id) ) => {
579
643
if self . closure_is_enclosed_by ( a_root_id, b_root_id) {
580
644
// `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
581
645
scope_b
@@ -764,7 +828,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
764
828
visitor. enter_scope (
765
829
Scope :: Remainder ( BlockRemainder {
766
830
block : blk. hir_id . local_id ,
767
- first_statement_index : i as u32
831
+ first_statement_index : FirstStatementIndex :: new ( i )
768
832
} )
769
833
) ;
770
834
visitor. cx . var_parent = visitor. cx . parent ;
@@ -915,8 +979,10 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
915
979
// Keep traversing up while we can.
916
980
match visitor. scope_tree . parent_map . get ( & scope) {
917
981
// Don't cross from closure bodies to their parent.
918
- Some ( & Scope :: CallSite ( _) ) => break ,
919
- Some ( & superscope) => scope = superscope,
982
+ Some ( & superscope) => match superscope. data ( ) {
983
+ ScopeData :: CallSite ( _) => break ,
984
+ _ => scope = superscope
985
+ } ,
920
986
None => break
921
987
}
922
988
}
0 commit comments