@@ -118,12 +118,29 @@ impl char : Repr {
118
118
fn write_repr ( writer : @Writer ) { writer. write_char ( self ) ; }
119
119
}
120
120
121
+ enum EnumVisitState {
122
+ PreVariant , // We're before the variant we're interested in.
123
+ InVariant , // We're inside the variant we're interested in.
124
+ PostVariant // We're after the variant we're interested in.
125
+ }
126
+
127
+ impl EnumVisitState : cmp:: Eq {
128
+ pure fn eq ( & & other: EnumVisitState ) -> bool {
129
+ ( self as uint ) == ( other as uint )
130
+ }
131
+ pure fn ne ( & & other: EnumVisitState ) -> bool { !self . eq ( other) }
132
+ }
133
+
134
+ struct EnumState {
135
+ end_ptr : * c_void ,
136
+ state : EnumVisitState
137
+ }
138
+
121
139
/// XXX: This should not use a boxed writer!
122
140
struct ReprPrinter {
123
141
mut ptr : * c_void ,
124
142
writer : @Writer , // XXX: This should not use a boxed trait.
125
- mut skip : bool ,
126
- enum_stack : DVec < * c_void >
143
+ enum_stack : DVec < EnumState >
127
144
}
128
145
129
146
/// FIXME (issue #3462): This is horrible.
@@ -467,8 +484,9 @@ impl ReprPrinterWrapper : TyVisitor {
467
484
self . printer . align ( align) ;
468
485
469
486
// Write in the location of the end of this enum.
470
- let new_pos = self . printer . ptr as uint + sz;
471
- self . printer . enum_stack . push ( transmute ( new_pos) ) ;
487
+ let end_ptr = transmute ( self . printer . ptr as uint + sz) ;
488
+ let new_state = EnumState { end_ptr : end_ptr, state : PreVariant } ;
489
+ self . printer . enum_stack . push ( new_state) ;
472
490
473
491
true
474
492
}
@@ -479,20 +497,26 @@ impl ReprPrinterWrapper : TyVisitor {
479
497
_n_fields : uint ,
480
498
name : & str ) -> bool {
481
499
unsafe {
482
- let disr_ptr = self . printer . ptr as * int ;
483
- if * disr_ptr == disr_val {
484
- self . printer . skip = false ; // Don't skip this variant.
485
- self . printer . writer . write_str ( name) ;
486
- self . printer . bump ( sys:: size_of :: < int > ( ) ) ;
487
- } else {
488
- self . printer . skip = true ; // Skip this variant.
500
+ let stack = & self . printer . enum_stack ;
501
+ let mut enum_state = stack. last ( ) ;
502
+ match enum_state. state {
503
+ PreVariant => {
504
+ let disr_ptr = self . printer . ptr as * int ;
505
+ if * disr_ptr == disr_val {
506
+ enum_state. state = InVariant ;
507
+ self . printer . writer . write_str ( name) ;
508
+ self . printer . bump ( sys:: size_of :: < int > ( ) ) ;
509
+ stack. set_elt ( stack. len ( ) - 1 , enum_state) ;
510
+ }
511
+ }
512
+ InVariant | PostVariant => { }
489
513
}
490
514
true
491
515
}
492
516
}
493
517
494
518
fn visit_enum_variant_field ( i : uint , inner : * TyDesc ) -> bool {
495
- if ! self . printer . skip {
519
+ if self . printer . enum_stack . last ( ) . state == InVariant {
496
520
if i == 0 {
497
521
self . printer . writer . write_char ( '(' ) ;
498
522
} else {
@@ -508,14 +532,21 @@ impl ReprPrinterWrapper : TyVisitor {
508
532
_disr_val : int ,
509
533
n_fields : uint ,
510
534
_name : & str ) -> bool {
511
- if !self . printer . skip && n_fields >= 1 {
512
- self . printer . writer . write_char ( ')' ) ;
535
+ let stack = & self . printer . enum_stack ;
536
+ let mut enum_state = stack. last ( ) ;
537
+ match enum_state. state {
538
+ InVariant => {
539
+ if n_fields >= 1 { self . printer . writer . write_char ( ')' ) ; }
540
+ enum_state. state = PostVariant ;
541
+ stack. set_elt ( stack. len ( ) - 1 , enum_state) ;
542
+ }
543
+ PreVariant | PostVariant => { }
513
544
}
514
545
true
515
546
}
516
547
517
548
fn visit_leave_enum ( _n_variants : uint , _sz : uint , _align : uint ) -> bool {
518
- self . printer . ptr = self . printer . enum_stack . pop ( ) ;
549
+ self . printer . ptr = self . printer . enum_stack . pop ( ) . end_ptr ;
519
550
true
520
551
}
521
552
@@ -564,7 +595,6 @@ pub fn write_repr<T>(writer: @Writer, object: &T) {
564
595
let repr_printer = @ReprPrinter {
565
596
ptr : ptr,
566
597
writer : writer,
567
- skip : false ,
568
598
enum_stack : DVec ( )
569
599
} ;
570
600
0 commit comments