Skip to content

Commit bbfc6f8

Browse files
committed
libcore: Make enum logging significantly less clownshoes.
Fixes the log-knows-the-names* tests.
1 parent 127c0d4 commit bbfc6f8

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

src/libcore/repr.rs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,29 @@ impl char : Repr {
118118
fn write_repr(writer: @Writer) { writer.write_char(self); }
119119
}
120120

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+
121139
/// XXX: This should not use a boxed writer!
122140
struct ReprPrinter {
123141
mut ptr: *c_void,
124142
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>
127144
}
128145

129146
/// FIXME (issue #3462): This is horrible.
@@ -467,8 +484,9 @@ impl ReprPrinterWrapper : TyVisitor {
467484
self.printer.align(align);
468485

469486
// 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);
472490

473491
true
474492
}
@@ -479,20 +497,26 @@ impl ReprPrinterWrapper : TyVisitor {
479497
_n_fields: uint,
480498
name: &str) -> bool {
481499
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 => {}
489513
}
490514
true
491515
}
492516
}
493517

494518
fn visit_enum_variant_field(i: uint, inner: *TyDesc) -> bool {
495-
if !self.printer.skip {
519+
if self.printer.enum_stack.last().state == InVariant {
496520
if i == 0 {
497521
self.printer.writer.write_char('(');
498522
} else {
@@ -508,14 +532,21 @@ impl ReprPrinterWrapper : TyVisitor {
508532
_disr_val: int,
509533
n_fields: uint,
510534
_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 => {}
513544
}
514545
true
515546
}
516547

517548
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;
519550
true
520551
}
521552

@@ -564,7 +595,6 @@ pub fn write_repr<T>(writer: @Writer, object: &T) {
564595
let repr_printer = @ReprPrinter {
565596
ptr: ptr,
566597
writer: writer,
567-
skip: false,
568598
enum_stack: DVec()
569599
};
570600

0 commit comments

Comments
 (0)