@@ -31,6 +31,7 @@ use hir::def_id::DefId;
3131use hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
3232use hir:: { Block , Arm , Pat , PatKind , Stmt , Expr , Local } ;
3333use mir:: transform:: MirSource ;
34+ use rustc_data_structures:: indexed_vec:: Idx ;
3435use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher ,
3536 StableHasherResult } ;
3637
@@ -96,7 +97,12 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
9697/// actually attach a more meaningful ordering to scopes than the one
9798/// generated via deriving here.
9899#[ 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 {
100106 Node ( hir:: ItemLocalId ) ,
101107
102108 // Scope of the call-site for a function or closure
@@ -135,7 +141,64 @@ pub enum Scope {
135141 RustcDecodable , Debug , Copy ) ]
136142pub struct BlockRemainder {
137143 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+ }
139202}
140203
141204impl Scope {
@@ -144,15 +207,16 @@ impl Scope {
144207 /// NB: likely to be replaced as API is refined; e.g. pnkfelix
145208 /// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
146209 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,
149213
150214 // These cases all return rough approximations to the
151215 // 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,
156220 }
157221 }
158222
@@ -177,7 +241,7 @@ impl Scope {
177241 return DUMMY_SP ;
178242 }
179243 let span = tcx. hir . span ( node_id) ;
180- if let Scope :: Remainder ( r) = * self {
244+ if let ScopeData :: Remainder ( r) = self . data ( ) {
181245 if let hir:: map:: NodeBlock ( ref blk) = tcx. hir . get ( node_id) {
182246 // Want span for scope starting after the
183247 // indexed statement and ending at end of
@@ -187,7 +251,7 @@ impl Scope {
187251 // (This is the special case aluded to in the
188252 // doc-comment for this method)
189253
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 ;
191255
192256 // To avoid issues with macro-generated spans, the span
193257 // of the statement must be nested in that of the block.
@@ -387,7 +451,7 @@ impl<'tcx> ScopeTree {
387451 }
388452
389453 // 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 ( ) {
391455 self . destruction_scopes . insert ( n, child) ;
392456 }
393457 }
@@ -482,8 +546,8 @@ impl<'tcx> ScopeTree {
482546 let mut id = Scope :: Node ( expr_id) ;
483547
484548 while let Some ( & p) = self . parent_map . get ( & id) {
485- match p {
486- Scope :: Destruction ( ..) => {
549+ match p. data ( ) {
550+ ScopeData :: Destruction ( ..) => {
487551 debug ! ( "temporary_scope({:?}) = {:?} [enclosing]" ,
488552 expr_id, id) ;
489553 return Some ( id) ;
@@ -573,9 +637,9 @@ impl<'tcx> ScopeTree {
573637 // infer::region_inference for more details.
574638 let a_root_scope = a_ancestors[ a_index] ;
575639 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) ) => {
579643 if self . closure_is_enclosed_by ( a_root_id, b_root_id) {
580644 // `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
581645 scope_b
@@ -764,7 +828,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
764828 visitor. enter_scope (
765829 Scope :: Remainder ( BlockRemainder {
766830 block : blk. hir_id . local_id ,
767- first_statement_index : i as u32
831+ first_statement_index : FirstStatementIndex :: new ( i )
768832 } )
769833 ) ;
770834 visitor. cx . var_parent = visitor. cx . parent ;
@@ -915,8 +979,10 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
915979 // Keep traversing up while we can.
916980 match visitor. scope_tree . parent_map . get ( & scope) {
917981 // 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+ } ,
920986 None => break
921987 }
922988 }
0 commit comments