@@ -521,20 +521,32 @@ type deref = @rec(bool mut, deref_t kind, ty::t outer_t);
521
521
// ds=[field(baz),field(bar)])
522
522
fn expr_root ( & ctx cx, @ast:: expr ex, bool autoderef ) ->
523
523
rec ( @ast:: expr ex, @deref[ ] ds) {
524
- fn maybe_auto_unbox ( & ctx cx, & ty:: t t) ->
525
- rec ( ty:: t t, option:: t[ deref] d ) {
526
- alt ( ty:: struct ( cx. tcx , t) ) {
527
- case ( ty:: ty_box ( ?mt) ) {
528
- ret rec ( t=mt. ty ,
529
- d=some ( @rec ( mut=mt. mut != ast:: imm,
530
- kind=unbox,
531
- outer_t=t) ) ) ;
524
+ fn maybe_auto_unbox ( & ctx cx, ty:: t t) -> rec ( ty:: t t, deref[ ] ds) {
525
+ auto ds = ~[ ] ;
526
+ while ( true ) {
527
+ alt ( ty:: struct ( cx. tcx , t ) ) {
528
+ ty:: ty_box ( ?mt ) {
529
+ ds += ~[ @rec ( mut =mt. mut != ast:: imm, kind=unbox , outer_t =t) ] ;
530
+ t = mt. ty ;
531
+ }
532
+ ty:: ty_res ( _, ?inner, ?tps) {
533
+ ds += ~[ @rec ( mut=false , kind=unbox, outer_t=t) ] ;
534
+ t = ty:: substitute_type_params ( cx. tcx , tps, inner) ;
535
+ }
536
+ ty:: ty_tag ( ?did, ?tps) {
537
+ auto variants = ty:: tag_variants ( cx. tcx , did) ;
538
+ if ( ivec:: len ( variants) != 1 u ||
539
+ ivec:: len ( variants. ( 0 ) . args ) != 1 u) {
540
+ break ;
541
+ }
542
+ ds += ~[ @rec ( mut=false , kind=unbox, outer_t=t) ] ;
543
+ t = ty:: substitute_type_params ( cx. tcx , tps,
544
+ variants. ( 0 ) . args . ( 0 ) ) ;
545
+ }
546
+ _ { break; }
532
547
}
533
- case ( _) { ret rec ( t=t, d=none) ; }
534
548
}
535
- }
536
- fn maybe_push_auto_unbox( & option:: t[ deref] d , & mutable deref[ ] ds) {
537
- alt ( d) { case ( some ( ?d ) ) { ds += ~[ d ] ; } case ( none) { } }
549
+ ret rec( t=t, ds =ds) ;
538
550
}
539
551
let deref[ ] ds = ~[ ] ;
540
552
while ( true ) {
@@ -559,7 +571,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef) ->
559
571
case ( ty:: ty_obj ( _) ) { }
560
572
}
561
573
ds += ~[ @rec ( mut=mut, kind=field, outer_t=auto_unbox. t ) ] ;
562
- maybe_push_auto_unbox ( auto_unbox. d , ds ) ;
574
+ ds += auto_unbox. ds ;
563
575
ex = base;
564
576
}
565
577
case ( ast:: expr_index ( ?base, _) ) {
@@ -577,7 +589,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef) ->
577
589
outer_t=auto_unbox. t ) ] ;
578
590
}
579
591
}
580
- maybe_push_auto_unbox ( auto_unbox. d , ds ) ;
592
+ ds += auto_unbox. ds ;
581
593
ex = base;
582
594
}
583
595
case ( ast:: expr_unary ( ?op, ?base) ) {
@@ -599,7 +611,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef) ->
599
611
}
600
612
if ( autoderef) {
601
613
auto auto_unbox = maybe_auto_unbox ( cx, ty:: expr_ty ( cx. tcx , ex) ) ;
602
- maybe_push_auto_unbox ( auto_unbox. d , ds ) ;
614
+ ds += auto_unbox. ds ;
603
615
}
604
616
ret rec( ex=ex, ds=@ds) ;
605
617
}
0 commit comments