Skip to content

more repr improvements #8927

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 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 @@ -146,6 +150,7 @@ impl Reflector {
// Entrypoint
pub fn visit_ty(&mut self, t: ty::t) {
let bcx = self.bcx;
let tcx = bcx.ccx().tcx;
debug!("reflect::visit_ty %s", ty_to_str(bcx.ccx().tcx, t));

match ty::get(t).sty {
Expand Down Expand Up @@ -248,17 +253,20 @@ impl Reflector {
}

ty::ty_struct(did, ref substs) => {
let bcx = self.bcx;
let tcx = bcx.ccx().tcx;
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 All @@ -270,7 +278,6 @@ impl Reflector {
// let the visitor tell us if it wants to visit only a particular
// variant?
ty::ty_enum(did, ref substs) => {
let bcx = self.bcx;
let ccx = bcx.ccx();
let repr = adt::represent_type(bcx.ccx(), t);
let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
Expand Down Expand Up @@ -336,8 +343,12 @@ impl Reflector {
}
}

// Miscallaneous extra types
ty::ty_trait(_, _, _, _, _) => self.leaf("trait"),
ty::ty_trait(_, _, _, _, _) => {
let extra = [self.c_slice(ty_to_str(tcx, t).to_managed())];
self.visit("trait", extra);
}

// Miscellaneous extra types
ty::ty_infer(_) => self.leaf("infer"),
ty::ty_err => self.leaf("err"),
ty::ty_param(ref p) => {
Expand Down
19 changes: 11 additions & 8 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 Expand Up @@ -450,9 +453,9 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
true
}

fn visit_trait(&mut self) -> bool {
fn visit_trait(&mut self, name: &str) -> bool {
self.align_to::<@TyVisitor>();
if ! self.inner.visit_trait() { return false; }
if ! self.inner.visit_trait(name) { return false; }
self.bump_past::<@TyVisitor>();
true
}
Expand Down
48 changes: 37 additions & 11 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 @@ -551,21 +560,31 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
}

fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
_n_inputs: uint, _retstyle: uint) -> bool { true }
_n_inputs: uint, _retstyle: uint) -> bool {
self.writer.write("fn(".as_bytes());
true
}

fn visit_fn_input(&mut self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool {
// FIXME: #8917: should print out the parameter types here, separated by commas
true
}

fn visit_fn_output(&mut self, _retstyle: uint, _inner: *TyDesc) -> bool {
self.writer.write(")".as_bytes());
// FIXME: #8917: should print out the output type here, as `-> T`
true
}

fn visit_leave_fn(&mut self, _purity: uint, _proto: uint,
_n_inputs: uint, _retstyle: uint) -> bool { true }


fn visit_trait(&mut self) -> bool { true }
fn visit_trait(&mut self, name: &str) -> bool {
self.writer.write(name.as_bytes());
true
}

fn visit_param(&mut self, _i: uint) -> bool { true }
fn visit_self(&mut self) -> bool { true }
fn visit_type(&mut self) -> bool { true }
Expand Down Expand Up @@ -596,6 +615,7 @@ struct P {a: int, b: float}

#[test]
fn test_repr() {
use prelude::*;
use str;
use str::Str;
use rt::io::Decorator;
Expand Down Expand Up @@ -653,6 +673,12 @@ fn test_repr() {
exact_test(&(10u64, ~"hello"),
"(10u64, ~\"hello\")");

exact_test(&(&println), "&fn()");
exact_test(&(~5 as ~ToStr), "~to_str::ToStr:Send");

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)");
}
8 changes: 4 additions & 4 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 Expand Up @@ -256,7 +256,7 @@ pub trait TyVisitor {
fn visit_leave_fn(&mut self, purity: uint, proto: uint,
n_inputs: uint, retstyle: uint) -> bool;

fn visit_trait(&mut self) -> bool;
fn visit_trait(&mut self, name: &str) -> bool;
fn visit_param(&mut self, i: uint) -> bool;
fn visit_self(&mut self) -> bool;
fn visit_type(&mut self) -> bool;
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ fn mk_fresh_ident_interner() -> @ident_interner {
"blk", // 26
"static", // 27
"__foreign_mod__", // 28
"__field__", // 29
"<unnamed_field>", // 29
"C", // 30
"Self", // 31

Expand Down
3 changes: 2 additions & 1 deletion src/test/debug-info/tuple-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@


// This test case mainly makes sure that no field names are generated for tuple structs (as opposed
// to all fields having the name "__field__"). Otherwise they are handled the same a normal structs.
// to all fields having the name "<unnamed_field>"). Otherwise they are handled the same a normal
// structs.

struct NoPadding16(u16, i16);
struct NoPadding32(i32, f32, u32);
Expand Down
28 changes: 14 additions & 14 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 @@ -428,9 +428,9 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
true
}

fn visit_trait(&mut self) -> bool {
fn visit_trait(&mut self, name: &str) -> bool {
self.align_to::<@TyVisitor>();
if ! self.inner.visit_trait() { return false; }
if ! self.inner.visit_trait(name) { return false; }
self.bump_past::<@TyVisitor>();
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 Expand Up @@ -616,7 +616,7 @@ impl TyVisitor for my_visitor {
_n_inputs: uint, _retstyle: uint) -> bool { true }


fn visit_trait(&mut self) -> bool { true }
fn visit_trait(&mut self, _name: &str) -> bool { true }
fn visit_param(&mut self, _i: uint) -> bool { true }
fn visit_self(&mut self) -> bool { true }
fn visit_type(&mut self) -> bool { true }
Expand Down
8 changes: 4 additions & 4 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 Expand Up @@ -139,7 +139,7 @@ impl TyVisitor for MyVisitor {
_n_inputs: uint, _retstyle: uint) -> bool { true }


fn visit_trait(&mut self) -> bool { true }
fn visit_trait(&mut self, _name: &str) -> bool { true }
fn visit_param(&mut self, _i: uint) -> bool { true }
fn visit_self(&mut self) -> bool { true }
fn visit_type(&mut self) -> bool { true }
Expand Down