@@ -382,29 +382,38 @@ fn compile_submatch(@block_ctxt bcx, &match m, ValueRef[] vals, &mk_fail f,
382
382
}
383
383
}
384
384
385
- // FIXME breaks on unreacheable cases
385
+ // Returns false for unreachable blocks
386
386
fn make_phi_bindings( & @block_ctxt bcx, & exit_node[ ] map,
387
- & ast:: pat_id_map ids) {
388
- fn assoc( str key, & tup ( str, ValueRef ) [ ] list) -> ValueRef {
387
+ & ast:: pat_id_map ids) -> bool {
388
+ fn assoc( str key, & tup ( str, ValueRef ) [ ] list) -> option :: t [ ValueRef ] {
389
389
for ( tup( str, ValueRef ) elt in list) {
390
- if ( str:: eq ( elt. _0 , key) ) { ret elt. _1 ; }
390
+ if ( str:: eq ( elt. _0 , key) ) { ret some ( elt. _1 ) ; }
391
391
}
392
- fail ;
392
+ ret none ;
393
393
}
394
394
395
395
auto our_block = bcx. llbb as uint ;
396
+ auto success = true ;
396
397
for each ( @tup( ast:: ident, ast:: node_id) item in ids. items ( ) ) {
397
398
auto llbbs = ~[ ] ;
398
399
auto vals = ~[ ] ;
399
400
for ( exit_node ex in map) {
400
401
if ( ex. to as uint == our_block) {
401
- llbbs += ~[ ex. from ] ;
402
- vals += ~[ assoc ( item. _0 , ex. bound ) ] ;
402
+ alt ( assoc ( item. _0 , ex. bound ) ) {
403
+ some ( ?val) {
404
+ llbbs += ~[ ex. from ] ;
405
+ vals += ~[ val] ;
406
+ }
407
+ none { }
408
+ }
403
409
}
404
410
}
405
- auto phi = bcx. build . Phi ( val_ty ( vals. ( 0 ) ) , vals, llbbs) ;
406
- bcx. fcx . lllocals . insert ( item. _1 , phi) ;
411
+ if ( ivec:: len ( vals) > 0 u) {
412
+ auto phi = bcx. build . Phi ( val_ty ( vals. ( 0 ) ) , vals, llbbs) ;
413
+ bcx. fcx . lllocals . insert ( item. _1 , phi) ;
414
+ } else { success = false ; }
407
415
}
416
+ ret success;
408
417
}
409
418
410
419
fn trans_alt( & @block_ctxt cx , & @ast:: expr expr, & ast:: arm[ ] arms,
@@ -444,9 +453,13 @@ fn trans_alt(&@block_ctxt cx, &@ast::expr expr, &ast::arm[] arms,
444
453
auto arm_results = ~[ ] ;
445
454
for ( ast:: arm a in arms) {
446
455
auto body_cx = bodies. ( i) ;
447
- make_phi_bindings( body_cx, exit_map, ast:: pat_id_map( a. pats. ( 0 ) ) ) ;
448
- auto block_res = trans:: trans_block( body_cx, a. block, output) ;
449
- arm_results += ~[ block_res] ;
456
+ if ( make_phi_bindings( body_cx, exit_map,
457
+ ast:: pat_id_map( a. pats. ( 0 ) ) ) ) {
458
+ auto block_res = trans:: trans_block( body_cx, a. block, output) ;
459
+ arm_results += ~[ block_res] ;
460
+ } else { // Unreachable
461
+ arm_results += ~[ rslt( body_cx, C_nil ( ) ) ] ;
462
+ }
450
463
i += 1 u;
451
464
}
452
465
ret rslt( trans:: join_branches( cx, arm_results) , C_nil ( ) ) ;
0 commit comments