Skip to content

Commit

Permalink
repr: handle tuple structs sanely
Browse files Browse the repository at this point in the history
Closes #8919
  • Loading branch information
thestinger committed Sep 2, 2013
1 parent cc1f002 commit 331d2d6
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 34 deletions.
13 changes: 11 additions & 2 deletions src/librustc/middle/trans/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ impl Reflector {
C_int(self.bcx.ccx(), i)
}

pub fn c_bool(&mut self, b: bool) -> ValueRef {
C_bool(b)
}

pub fn c_slice(&mut self, s: @str) -> ValueRef {
// We're careful to not use first class aggregates here because that
// will kick us off fast isel. (Issue #4352.)
Expand Down Expand Up @@ -250,14 +254,19 @@ impl Reflector {

ty::ty_struct(did, ref substs) => {
let fields = ty::struct_fields(tcx, did, substs);
let mut named_fields = false;
if !fields.is_empty() {
named_fields = fields[0].ident != special_idents::unnamed_field;
}

let extra = ~[self.c_slice(ty_to_str(tcx, t).to_managed()),
self.c_bool(named_fields),
self.c_uint(fields.len())] + self.c_size_and_align(t);
do self.bracketed("class", extra) |this| {
for (i, field) in fields.iter().enumerate() {
let extra = ~[this.c_uint(i),
this.c_slice(
bcx.ccx().sess.str_of(field.ident))]
this.c_slice(bcx.ccx().sess.str_of(field.ident)),
this.c_bool(named_fields)]
+ this.c_mt(&field.mt);
this.visit("class_field", extra);
}
Expand Down
15 changes: 9 additions & 6 deletions src/libstd/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,25 +331,28 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
true
}

fn visit_enter_class(&mut self, name: &str, n_fields: uint, sz: uint, align: uint) -> bool {
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint, sz: uint,
align: uint) -> bool {
self.align(align);
if ! self.inner.visit_enter_class(name, n_fields, sz, align) {
if ! self.inner.visit_enter_class(name, named_fields, n_fields, sz, align) {
return false;
}
true
}

fn visit_class_field(&mut self, i: uint, name: &str, mtbl: uint, inner: *TyDesc) -> bool {
fn visit_class_field(&mut self, i: uint, name: &str, named: bool, mtbl: uint,
inner: *TyDesc) -> bool {
unsafe { self.align((*inner).align); }
if ! self.inner.visit_class_field(i, name, mtbl, inner) {
if ! self.inner.visit_class_field(i, name, named, mtbl, inner) {
return false;
}
unsafe { self.bump((*inner).size); }
true
}

fn visit_leave_class(&mut self, name: &str, n_fields: uint, sz: uint, align: uint) -> bool {
if ! self.inner.visit_leave_class(name, n_fields, sz, align) {
fn visit_leave_class(&mut self, name: &str, named_fields: bool, n_fields: uint, sz: uint,
align: uint) -> bool {
if ! self.inner.visit_leave_class(name, named_fields, n_fields, sz, align) {
return false;
}
true
Expand Down
30 changes: 21 additions & 9 deletions src/libstd/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,31 +412,40 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
true
}

fn visit_enter_class(&mut self, name: &str, n_fields: uint,
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
_sz: uint, _align: uint) -> bool {
self.writer.write(name.as_bytes());
if n_fields != 0 {
self.writer.write(['{' as u8]);
if named_fields {
self.writer.write(['{' as u8]);
} else {
self.writer.write(['(' as u8]);
}
}
true
}

fn visit_class_field(&mut self, i: uint, name: &str,
mtbl: uint, inner: *TyDesc) -> bool {
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
_mtbl: uint, inner: *TyDesc) -> bool {
if i != 0 {
self.writer.write(", ".as_bytes());
}
self.write_mut_qualifier(mtbl);
self.writer.write(name.as_bytes());
self.writer.write(": ".as_bytes());
if named {
self.writer.write(name.as_bytes());
self.writer.write(": ".as_bytes());
}
self.visit_inner(inner);
true
}

fn visit_leave_class(&mut self, _name: &str, n_fields: uint,
fn visit_leave_class(&mut self, _name: &str, named_fields: bool, n_fields: uint,
_sz: uint, _align: uint) -> bool {
if n_fields != 0 {
self.writer.write(['}' as u8]);
if named_fields {
self.writer.write(['}' as u8]);
} else {
self.writer.write([')' as u8]);
}
}
true
}
Expand Down Expand Up @@ -669,4 +678,7 @@ fn test_repr() {

struct Foo;
exact_test(&(~[Foo, Foo]), "~[repr::test_repr::Foo, repr::test_repr::Foo]");

struct Bar(int, int);
exact_test(&(Bar(2, 2)), "repr::test_repr::Bar(2, 2)");
}
6 changes: 3 additions & 3 deletions src/libstd/unstable/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ pub trait TyVisitor {
fn visit_leave_rec(&mut self, n_fields: uint,
sz: uint, align: uint) -> bool;

fn visit_enter_class(&mut self, name: &str, n_fields: uint,
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_class_field(&mut self, i: uint, name: &str,
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
mtbl: uint, inner: *TyDesc) -> bool;
fn visit_leave_class(&mut self, name: &str, n_fields: uint,
fn visit_leave_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
sz: uint, align: uint) -> bool;

fn visit_enter_tup(&mut self, n_fields: uint,
Expand Down
22 changes: 11 additions & 11 deletions src/test/run-pass/reflect-visit-data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,26 +317,26 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
true
}

fn visit_enter_class(&mut self, name: &str, n_fields: uint, sz: uint, align: uint)
-> bool {
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint, sz: uint,
align: uint) -> bool {
self.align(align);
if ! self.inner.visit_enter_class(name, n_fields, sz, align) {
if ! self.inner.visit_enter_class(name, named_fields, n_fields, sz, align) {
return false;
}
true
}

fn visit_class_field(&mut self, i: uint, name: &str,
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
mtbl: uint, inner: *TyDesc) -> bool {
if ! self.inner.visit_class_field(i, name, mtbl, inner) {
if ! self.inner.visit_class_field(i, name, named, mtbl, inner) {
return false;
}
true
}

fn visit_leave_class(&mut self, name: &str, n_fields: uint, sz: uint, align: uint)
-> bool {
if ! self.inner.visit_leave_class(name, n_fields, sz, align) {
fn visit_leave_class(&mut self, name: &str, named_fields: bool, n_fields: uint, sz: uint,
align: uint) -> bool {
if ! self.inner.visit_leave_class(name, named_fields, n_fields, sz, align) {
return false;
}
true
Expand Down Expand Up @@ -565,13 +565,13 @@ impl TyVisitor for my_visitor {
fn visit_leave_rec(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }

fn visit_enter_class(&mut self, _name: &str, _n_fields: uint,
fn visit_enter_class(&mut self, _name: &str, _named_fields: bool, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }
fn visit_class_field(&mut self, _i: uint, _name: &str,
fn visit_class_field(&mut self, _i: uint, _name: &str, _named: bool,
_mtbl: uint, inner: *TyDesc) -> bool {
self.visit_inner(inner)
}
fn visit_leave_class(&mut self, _name: &str, _n_fields: uint,
fn visit_leave_class(&mut self, _name: &str, _named_fields: bool, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }

fn visit_enter_tup(&mut self, _n_fields: uint,
Expand Down
6 changes: 3 additions & 3 deletions src/test/run-pass/reflect-visit-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ impl TyVisitor for MyVisitor {
fn visit_leave_rec(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }

fn visit_enter_class(&mut self, _name: &str, _n_fields: uint,
fn visit_enter_class(&mut self, _name: &str, _named_fields: bool, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }
fn visit_class_field(&mut self, _i: uint, _name: &str,
fn visit_class_field(&mut self, _i: uint, _name: &str, _named: bool,
_mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_leave_class(&mut self, _name: &str, _n_fields: uint,
fn visit_leave_class(&mut self, _name: &str, _named_fields: bool, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }

fn visit_enter_tup(&mut self, _n_fields: uint,
Expand Down

0 comments on commit 331d2d6

Please sign in to comment.