diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index b6cb47efc7670..45f2830dafee9 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -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.) @@ -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 { @@ -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); } @@ -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); @@ -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) => { diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 7b352e7806e62..91e3719e3d053 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -331,25 +331,28 @@ impl TyVisitor for MovePtrAdaptor { 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 @@ -450,9 +453,9 @@ impl TyVisitor for MovePtrAdaptor { 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 } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index 3e2c5773acced..02a3561a6f41f 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -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 } @@ -551,13 +560,19 @@ 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 } @@ -565,7 +580,11 @@ impl<'self> TyVisitor for ReprVisitor<'self> { _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 } @@ -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; @@ -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)"); } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 8e0f6255e0974..fbd5bdaf587e7 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -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, @@ -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; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 3d47b1141ddd0..c9d61be6b0ebf 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -436,7 +436,7 @@ fn mk_fresh_ident_interner() -> @ident_interner { "blk", // 26 "static", // 27 "__foreign_mod__", // 28 - "__field__", // 29 + "", // 29 "C", // 30 "Self", // 31 diff --git a/src/test/debug-info/tuple-struct.rs b/src/test/debug-info/tuple-struct.rs index 1368053f48cb4..762b8dcb38f45 100644 --- a/src/test/debug-info/tuple-struct.rs +++ b/src/test/debug-info/tuple-struct.rs @@ -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 ""). Otherwise they are handled the same a normal +// structs. struct NoPadding16(u16, i16); struct NoPadding32(i32, f32, u32); diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 317fdb634bc06..2d9f4a2ff6f6d 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -317,26 +317,26 @@ impl TyVisitor for ptr_visit_adaptor { 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 @@ -428,9 +428,9 @@ impl TyVisitor for ptr_visit_adaptor { 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 } @@ -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, @@ -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 } diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 32df437698360..b3d81d9c51102 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -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, @@ -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 }