@@ -863,10 +863,10 @@ pub fn need_invoke(bcx: block) -> bool {
863
863
864
864
// Walk the scopes to look for cleanups
865
865
let mut cur = bcx;
866
+ let mut cur_scope = cur. scope;
866
867
loop {
867
- match cur. kind {
868
- block_scope( inf) => {
869
- let inf = & mut * inf; // FIXME(#5074) workaround old borrowck
868
+ cur_scope = match cur_scope {
869
+ Some ( inf) => {
870
870
for inf. cleanups. iter( ) . advance |cleanup| {
871
871
match * cleanup {
872
872
clean( _, cleanup_type) | clean_temp( _, _, cleanup_type) => {
@@ -876,12 +876,15 @@ pub fn need_invoke(bcx: block) -> bool {
876
876
}
877
877
}
878
878
}
879
+ inf. parent
880
+ }
881
+ None => {
882
+ cur = match cur. parent {
883
+ Some ( next) => next,
884
+ None => return false
885
+ } ;
886
+ cur. scope
879
887
}
880
- _ => ( )
881
- }
882
- cur = match cur. parent {
883
- Some ( next) => next,
884
- None => return false
885
888
}
886
889
}
887
890
}
@@ -899,23 +902,21 @@ pub fn have_cached_lpad(bcx: block) -> bool {
899
902
900
903
pub fn in_lpad_scope_cx( bcx: block, f: & fn ( si: & mut scope_info) ) {
901
904
let mut bcx = bcx;
905
+ let mut cur_scope = bcx. scope;
902
906
loop {
903
- {
904
- match bcx. kind {
905
- block_scope( inf) => {
906
- let len = { // FIXME(#5074) workaround old borrowck
907
- let inf = & mut * inf;
908
- inf. cleanups. len( )
909
- } ;
910
- if len > 0 u || bcx. parent. is_none( ) {
911
- f( inf) ;
912
- return ;
913
- }
907
+ cur_scope = match cur_scope {
908
+ Some ( inf) => {
909
+ if !inf. empty_cleanups( ) || ( inf. parent. is_none( ) && bcx. parent. is_none( ) ) {
910
+ f( inf) ;
911
+ return ;
914
912
}
915
- _ => ( )
913
+ inf. parent
914
+ }
915
+ None => {
916
+ bcx = block_parent( bcx) ;
917
+ bcx. scope
916
918
}
917
919
}
918
- bcx = block_parent( bcx) ;
919
920
}
920
921
}
921
922
@@ -972,27 +973,31 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef {
972
973
973
974
pub fn find_bcx_for_scope( bcx: block, scope_id: ast:: node_id) -> block {
974
975
let mut bcx_sid = bcx;
976
+ let mut cur_scope = bcx_sid. scope;
975
977
loop {
976
- bcx_sid = match bcx_sid. node_info {
977
- Some ( NodeInfo { id, _ } ) if id == scope_id => {
978
- return bcx_sid
979
- }
980
-
981
- // FIXME(#6268, #6248) hacky cleanup for nested method calls
982
- Some ( NodeInfo { callee_id: Some ( id) , _ } ) if id == scope_id => {
983
- return bcx_sid
984
- }
985
-
986
- _ => {
987
- match bcx_sid. parent {
988
- None => bcx. tcx( ) . sess. bug(
989
- fmt!( "no enclosing scope with id %d" , scope_id) ) ,
990
- Some ( bcx_par) => bcx_par
978
+ cur_scope = match cur_scope {
979
+ Some ( inf) => {
980
+ match inf. node_info {
981
+ Some ( NodeInfo { id, _ } ) if id == scope_id => {
982
+ return bcx_sid
991
983
}
984
+ // FIXME(#6268, #6248) hacky cleanup for nested method calls
985
+ Some ( NodeInfo { callee_id: Some ( id) , _ } ) if id == scope_id => {
986
+ return bcx_sid
987
+ }
988
+ _ => inf. parent
992
989
}
993
990
}
991
+ None => {
992
+ bcx_sid = match bcx_sid. parent {
993
+ None => bcx. tcx( ) . sess. bug( fmt!( "no enclosing scope with id %d" , scope_id) ) ,
994
+ Some ( bcx_par) => bcx_par
995
+ } ;
996
+ bcx_sid. scope
997
+ }
994
998
}
995
999
}
1000
+ }
996
1001
997
1002
998
1003
pub fn do_spill( bcx: block, v: ValueRef , t: ty:: t) -> ValueRef {
@@ -1145,7 +1150,7 @@ pub fn trans_stmt(cx: block, s: &ast::stmt) -> block {
1145
1150
1146
1151
// You probably don't want to use this one. See the
1147
1152
// next three functions instead.
1148
- pub fn new_block( cx: fn_ctxt, parent: Option <block>, kind : block_kind ,
1153
+ pub fn new_block( cx: fn_ctxt, parent: Option <block>, scope : Option <@ mut scope_info> ,
1149
1154
is_lpad: bool , name: & str , opt_node_info: Option <NodeInfo >)
1150
1155
-> block {
1151
1156
@@ -1155,10 +1160,10 @@ pub fn new_block(cx: fn_ctxt, parent: Option<block>, kind: block_kind,
1155
1160
} ;
1156
1161
let bcx = mk_block( llbb,
1157
1162
parent,
1158
- kind,
1159
1163
is_lpad,
1160
1164
opt_node_info,
1161
1165
cx) ;
1166
+ bcx. scope = scope;
1162
1167
for parent. iter( ) . advance |cx| {
1163
1168
if cx. unreachable {
1164
1169
Unreachable ( bcx) ;
@@ -1169,27 +1174,30 @@ pub fn new_block(cx: fn_ctxt, parent: Option<block>, kind: block_kind,
1169
1174
}
1170
1175
}
1171
1176
1172
- pub fn simple_block_scope( ) -> block_kind {
1173
- block_scope( @mut scope_info {
1177
+ pub fn simple_block_scope( parent: Option <@mut scope_info>,
1178
+ node_info: Option <NodeInfo >) -> @mut scope_info {
1179
+ @mut scope_info {
1180
+ parent: parent,
1174
1181
loop_break: None ,
1175
1182
loop_label: None ,
1176
1183
cleanups: ~[ ] ,
1177
1184
cleanup_paths: ~[ ] ,
1178
- landing_pad: None
1179
- } )
1185
+ landing_pad: None ,
1186
+ node_info: node_info,
1187
+ }
1180
1188
}
1181
1189
1182
1190
// Use this when you're at the top block of a function or the like.
1183
1191
pub fn top_scope_block( fcx: fn_ctxt, opt_node_info: Option <NodeInfo >)
1184
1192
-> block {
1185
- return new_block( fcx, None , simple_block_scope( ) , false ,
1193
+ return new_block( fcx, None , Some ( simple_block_scope( None , opt_node_info ) ) , false ,
1186
1194
"function top level" , opt_node_info) ;
1187
1195
}
1188
1196
1189
1197
pub fn scope_block( bcx: block,
1190
1198
opt_node_info: Option <NodeInfo >,
1191
1199
n: & str ) -> block {
1192
- return new_block( bcx. fcx, Some ( bcx) , simple_block_scope( ) , bcx. is_lpad,
1200
+ return new_block( bcx. fcx, Some ( bcx) , Some ( simple_block_scope( None , opt_node_info ) ) , bcx. is_lpad,
1193
1201
n, opt_node_info) ;
1194
1202
}
1195
1203
@@ -1198,27 +1206,29 @@ pub fn loop_scope_block(bcx: block,
1198
1206
loop_label: Option <ident>,
1199
1207
n: & str ,
1200
1208
opt_node_info: Option <NodeInfo >) -> block {
1201
- return new_block( bcx. fcx, Some ( bcx) , block_scope( @mut scope_info {
1209
+ return new_block( bcx. fcx, Some ( bcx) , Some ( @mut scope_info {
1210
+ parent: None ,
1202
1211
loop_break: Some ( loop_break) ,
1203
1212
loop_label: loop_label,
1204
1213
cleanups: ~[ ] ,
1205
1214
cleanup_paths: ~[ ] ,
1206
- landing_pad: None
1215
+ landing_pad: None ,
1216
+ node_info: opt_node_info,
1207
1217
} ) , bcx. is_lpad, n, opt_node_info) ;
1208
1218
}
1209
1219
1210
1220
// Use this when creating a block for the inside of a landing pad.
1211
1221
pub fn lpad_block( bcx: block, n: & str ) -> block {
1212
- new_block( bcx. fcx, Some ( bcx) , block_non_scope , true , n, None )
1222
+ new_block( bcx. fcx, Some ( bcx) , None , true , n, None )
1213
1223
}
1214
1224
1215
1225
// Use this when you're making a general CFG BB within a scope.
1216
1226
pub fn sub_block( bcx: block, n: & str ) -> block {
1217
- new_block( bcx. fcx, Some ( bcx) , block_non_scope , bcx. is_lpad, n, None )
1227
+ new_block( bcx. fcx, Some ( bcx) , None , bcx. is_lpad, n, None )
1218
1228
}
1219
1229
1220
1230
pub fn raw_block( fcx: fn_ctxt, is_lpad: bool , llbb: BasicBlockRef ) -> block {
1221
- mk_block( llbb, None , block_non_scope , is_lpad, None , fcx)
1231
+ mk_block( llbb, None , is_lpad, None , fcx)
1222
1232
}
1223
1233
1224
1234
@@ -1277,42 +1287,47 @@ pub fn cleanup_and_leave(bcx: block,
1277
1287
( fmt!( "cleanup_and_leave(%s)" , cur. to_str( ) ) ) . to_managed( ) ) ;
1278
1288
}
1279
1289
1280
- match cur. kind {
1281
- block_scope( inf) if !inf. empty_cleanups( ) => {
1282
- let ( sub_cx, dest, inf_cleanups) = {
1283
- let inf = & mut * inf;
1284
- let mut skip = 0 ;
1285
- let mut dest = None ;
1286
- {
1287
- let r = ( * inf) . cleanup_paths. rev_iter( ) . find_( |cp| cp. target == leave) ;
1288
- for r. iter( ) . advance |cp| {
1289
- if cp. size == inf. cleanups. len( ) {
1290
- Br ( bcx, cp. dest) ;
1291
- return ;
1290
+ let mut cur_scope = cur. scope;
1291
+ loop {
1292
+ cur_scope = match cur_scope {
1293
+ Some ( inf) if !inf. empty_cleanups( ) => {
1294
+ let ( sub_cx, dest, inf_cleanups) = {
1295
+ let inf = & mut * inf;
1296
+ let mut skip = 0 ;
1297
+ let mut dest = None ;
1298
+ {
1299
+ let r = ( * inf) . cleanup_paths. rev_iter( ) . find_( |cp| cp. target == leave) ;
1300
+ for r. iter( ) . advance |cp| {
1301
+ if cp. size == inf. cleanups. len( ) {
1302
+ Br ( bcx, cp. dest) ;
1303
+ return ;
1304
+ }
1305
+
1306
+ skip = cp. size;
1307
+ dest = Some ( cp. dest) ;
1292
1308
}
1293
-
1294
- skip = cp. size;
1295
- dest = Some ( cp. dest) ;
1296
1309
}
1310
+ let sub_cx = sub_block( bcx, "cleanup" ) ;
1311
+ Br ( bcx, sub_cx. llbb) ;
1312
+ inf. cleanup_paths. push( cleanup_path {
1313
+ target: leave,
1314
+ size: inf. cleanups. len( ) ,
1315
+ dest: sub_cx. llbb
1316
+ } ) ;
1317
+ ( sub_cx, dest, inf. cleanups. tailn( skip) . to_owned( ) )
1318
+ } ;
1319
+ bcx = trans_block_cleanups_( sub_cx,
1320
+ inf_cleanups,
1321
+ is_lpad) ;
1322
+ for dest. iter( ) . advance |& dest| {
1323
+ Br ( bcx, dest) ;
1324
+ return ;
1297
1325
}
1298
- let sub_cx = sub_block( bcx, "cleanup" ) ;
1299
- Br ( bcx, sub_cx. llbb) ;
1300
- inf. cleanup_paths. push( cleanup_path {
1301
- target: leave,
1302
- size: inf. cleanups. len( ) ,
1303
- dest: sub_cx. llbb
1304
- } ) ;
1305
- ( sub_cx, dest, inf. cleanups. tailn( skip) . to_owned( ) )
1306
- } ;
1307
- bcx = trans_block_cleanups_( sub_cx,
1308
- inf_cleanups,
1309
- is_lpad) ;
1310
- for dest. iter( ) . advance |& dest| {
1311
- Br ( bcx, dest) ;
1312
- return ;
1326
+ inf. parent
1313
1327
}
1328
+ Some ( inf) => inf. parent,
1329
+ None => break
1314
1330
}
1315
- _ => ( )
1316
1331
}
1317
1332
1318
1333
match upto {
@@ -1353,20 +1368,27 @@ pub fn with_scope(bcx: block,
1353
1368
bcx. to_str( ) , opt_node_info, name) ;
1354
1369
let _indenter = indenter( ) ;
1355
1370
1356
- let scope_cx = scope_block( bcx, opt_node_info, name) ;
1357
- Br ( bcx, scope_cx. llbb) ;
1358
- leave_block( f( scope_cx) , scope_cx)
1371
+ let scope = simple_block_scope( bcx. scope, opt_node_info) ;
1372
+ bcx. scope = Some ( scope) ;
1373
+ let ret = f( bcx) ;
1374
+ let ret = trans_block_cleanups_( ret, /*bad*/ copy scope. cleanups, false ) ;
1375
+ bcx. scope = scope. parent;
1376
+ ret
1359
1377
}
1360
1378
1361
1379
pub fn with_scope_result( bcx: block,
1362
1380
opt_node_info: Option <NodeInfo >,
1363
1381
name: & str ,
1364
1382
f: & fn ( block) -> Result ) -> Result {
1365
1383
let _icx = push_ctxt( "with_scope_result" ) ;
1366
- let scope_cx = scope_block( bcx, opt_node_info, name) ;
1367
- Br ( bcx, scope_cx. llbb) ;
1368
- let Result { bcx, val} = f( scope_cx) ;
1369
- rslt( leave_block( bcx, scope_cx) , val)
1384
+
1385
+ let scope = simple_block_scope( bcx. scope, opt_node_info) ;
1386
+ bcx. scope = Some ( scope) ;
1387
+ let Result { bcx: out_bcx, val } = f( bcx) ;
1388
+ let out_bcx = trans_block_cleanups_( out_bcx, /*bad*/ copy scope. cleanups, false ) ;
1389
+ bcx. scope = scope. parent;
1390
+
1391
+ rslt( out_bcx, val)
1370
1392
}
1371
1393
1372
1394
pub fn with_scope_datumblock( bcx: block, opt_node_info: Option <NodeInfo >,
0 commit comments