@@ -17,14 +17,14 @@ use middle::def;
1717use middle:: mem_categorization:: Typer ;
1818use middle:: resolve;
1919use middle:: ty;
20- use util:: nodemap:: { DefIdSet , NodeMap , NodeSet } ;
20+ use util:: nodemap:: { NodeMap , NodeSet } ;
2121
22+ use syntax:: ast;
2223use syntax:: codemap:: Span ;
23- use syntax:: { ast} ;
24- use syntax:: visit;
2524use syntax:: visit:: Visitor ;
25+ use syntax:: visit;
2626
27- #[ deriving( Show ) ]
27+ #[ deriving( Clone , Decodable , Encodable , Show ) ]
2828pub enum CaptureMode {
2929 /// Copy/move the value from this llvm ValueRef into the environment.
3030 CaptureByValue ,
@@ -43,12 +43,13 @@ pub struct freevar_entry {
4343
4444pub type freevar_map = NodeMap < Vec < freevar_entry > > ;
4545
46- pub type UnboxedClosureList = DefIdSet ;
46+ pub type CaptureModeMap = NodeMap < CaptureMode > ;
4747
4848struct CollectFreevarsVisitor < ' a > {
4949 seen : NodeSet ,
5050 refs : Vec < freevar_entry > ,
5151 def_map : & ' a resolve:: DefMap ,
52+ capture_mode_map : & ' a mut CaptureModeMap ,
5253}
5354
5455impl < ' a > Visitor < int > for CollectFreevarsVisitor < ' a > {
@@ -58,8 +59,27 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
5859
5960 fn visit_expr ( & mut self , expr : & ast:: Expr , depth : int ) {
6061 match expr. node {
61- ast:: ExprFnBlock ( ..) | ast:: ExprProc ( ..) |
62- ast:: ExprUnboxedFn ( ..) => {
62+ ast:: ExprProc ( ..) => {
63+ self . capture_mode_map . insert ( expr. id , CaptureByValue ) ;
64+ visit:: walk_expr ( self , expr, depth + 1 )
65+ }
66+ ast:: ExprFnBlock ( _, _, _) => {
67+ // NOTE(stage0): After snapshot, change to:
68+ //
69+ //let capture_mode = match capture_clause {
70+ // ast::CaptureByValue => CaptureByValue,
71+ // ast::CaptureByRef => CaptureByRef,
72+ //};
73+ let capture_mode = CaptureByRef ;
74+ self . capture_mode_map . insert ( expr. id , capture_mode) ;
75+ visit:: walk_expr ( self , expr, depth + 1 )
76+ }
77+ ast:: ExprUnboxedFn ( capture_clause, _, _) => {
78+ let capture_mode = match capture_clause {
79+ ast:: CaptureByValue => CaptureByValue ,
80+ ast:: CaptureByRef => CaptureByRef ,
81+ } ;
82+ self . capture_mode_map . insert ( expr. id , capture_mode) ;
6383 visit:: walk_expr ( self , expr, depth + 1 )
6484 }
6585 ast:: ExprPath ( ..) => {
@@ -91,35 +111,41 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
91111 _ => visit:: walk_expr ( self , expr, depth)
92112 }
93113 }
94-
95-
96114}
97115
98116// Searches through part of the AST for all references to locals or
99117// upvars in this frame and returns the list of definition IDs thus found.
100118// Since we want to be able to collect upvars in some arbitrary piece
101119// of the AST, we take a walker function that we invoke with a visitor
102120// in order to start the search.
103- fn collect_freevars ( def_map : & resolve:: DefMap , blk : & ast:: Block ) -> Vec < freevar_entry > {
121+ fn collect_freevars ( def_map : & resolve:: DefMap ,
122+ blk : & ast:: Block ,
123+ capture_mode_map : & mut CaptureModeMap )
124+ -> Vec < freevar_entry > {
104125 let mut v = CollectFreevarsVisitor {
105126 seen : NodeSet :: new ( ) ,
106127 refs : Vec :: new ( ) ,
107128 def_map : def_map,
129+ capture_mode_map : & mut * capture_mode_map,
108130 } ;
109131
110132 v. visit_block ( blk, 1 ) ;
133+
111134 v. refs
112135}
113136
114137struct AnnotateFreevarsVisitor < ' a > {
115138 def_map : & ' a resolve:: DefMap ,
116139 freevars : freevar_map ,
140+ capture_mode_map : CaptureModeMap ,
117141}
118142
119143impl < ' a > Visitor < ( ) > for AnnotateFreevarsVisitor < ' a > {
120144 fn visit_fn ( & mut self , fk : & visit:: FnKind , fd : & ast:: FnDecl ,
121145 blk : & ast:: Block , s : Span , nid : ast:: NodeId , _: ( ) ) {
122- let vars = collect_freevars ( self . def_map , blk) ;
146+ let vars = collect_freevars ( self . def_map ,
147+ blk,
148+ & mut self . capture_mode_map ) ;
123149 self . freevars . insert ( nid, vars) ;
124150 visit:: walk_fn ( self , fk, fd, blk, s, ( ) ) ;
125151 }
@@ -131,14 +157,20 @@ impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> {
131157// node of interest rather than building up the free variables in
132158// one pass. This could be improved upon if it turns out to matter.
133159pub fn annotate_freevars ( def_map : & resolve:: DefMap , krate : & ast:: Crate )
134- -> freevar_map {
160+ -> ( freevar_map , CaptureModeMap ) {
135161 let mut visitor = AnnotateFreevarsVisitor {
136162 def_map : def_map,
137163 freevars : NodeMap :: new ( ) ,
164+ capture_mode_map : NodeMap :: new ( ) ,
138165 } ;
139166 visit:: walk_crate ( & mut visitor, krate, ( ) ) ;
140167
141- visitor. freevars
168+ let AnnotateFreevarsVisitor {
169+ freevars,
170+ capture_mode_map,
171+ ..
172+ } = visitor;
173+ ( freevars, capture_mode_map)
142174}
143175
144176pub fn with_freevars < T > ( tcx : & ty:: ctxt , fid : ast:: NodeId , f: |& [ freevar_entry] | -> T ) -> T {
@@ -148,10 +180,7 @@ pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]|
148180 }
149181}
150182
151- pub fn get_capture_mode < T : Typer > ( tcx : & T , closure_expr_id : ast:: NodeId ) -> CaptureMode {
152- let fn_ty = tcx. node_ty ( closure_expr_id) . ok ( ) . expect ( "couldn't find closure ty?" ) ;
153- match ty:: ty_closure_store ( fn_ty) {
154- ty:: RegionTraitStore ( ..) => CaptureByRef ,
155- ty:: UniqTraitStore => CaptureByValue
156- }
183+ pub fn get_capture_mode < T : Typer > ( tcx : & T , closure_expr_id : ast:: NodeId )
184+ -> CaptureMode {
185+ tcx. capture_mode ( closure_expr_id)
157186}
0 commit comments