1
Fork 0

Move std::{reflect,repr,Poly} to a libdebug crate

This commit moves reflection (as well as the {:?} format modifier) to a new
libdebug crate, all of which is marked experimental.

This is a breaking change because it now requires the debug crate to be
explicitly linked if the :? format qualifier is used. This means that any code
using this feature will have to add `extern crate debug;` to the top of the
crate. Any code relying on reflection will also need to do this.

Closes #12019

[breaking-change]
This commit is contained in:
Alex Crichton 2014-05-22 11:28:01 -07:00
parent 911cc9c352
commit b53454e2e4
156 changed files with 1545 additions and 147 deletions

View file

@ -51,7 +51,7 @@
TARGET_CRATES := libc std green rustuv native flate arena glob term semver \ TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
uuid serialize sync getopts collections num test time rand \ uuid serialize sync getopts collections num test time rand \
workcache url log regex graphviz core rlibc alloc workcache url log regex graphviz core rlibc alloc debug
HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros
CRATES := $(TARGET_CRATES) $(HOST_CRATES) CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc TOOLS := compiletest rustdoc rustc
@ -59,16 +59,17 @@ TOOLS := compiletest rustdoc rustc
DEPS_core := DEPS_core :=
DEPS_rlibc := DEPS_rlibc :=
DEPS_alloc := core libc native:jemalloc DEPS_alloc := core libc native:jemalloc
DEPS_debug := std
DEPS_std := core libc alloc native:rustrt native:backtrace DEPS_std := core libc alloc native:rustrt native:backtrace
DEPS_graphviz := std DEPS_graphviz := std
DEPS_green := std rand native:context_switch DEPS_green := std rand native:context_switch
DEPS_rustuv := std native:uv native:uv_support DEPS_rustuv := std native:uv native:uv_support
DEPS_native := std DEPS_native := std
DEPS_syntax := std term serialize collections log fmt_macros DEPS_syntax := std term serialize collections log fmt_macros debug
DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \ DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
collections time log graphviz collections time log graphviz debug
DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \ DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \
test time test time debug
DEPS_flate := std native:miniz DEPS_flate := std native:miniz
DEPS_arena := std collections DEPS_arena := std collections
DEPS_graphviz := std DEPS_graphviz := std
@ -79,7 +80,7 @@ DEPS_semver := std
DEPS_uuid := std serialize rand DEPS_uuid := std serialize rand
DEPS_sync := std alloc DEPS_sync := std alloc
DEPS_getopts := std DEPS_getopts := std
DEPS_collections := std rand DEPS_collections := std rand debug
DEPS_fourcc := syntax std DEPS_fourcc := syntax std
DEPS_hexfloat := syntax std DEPS_hexfloat := syntax std
DEPS_num := std rand DEPS_num := std rand

View file

@ -254,7 +254,7 @@ for (x, y) in it {
} }
// yield and print the last pair from the iterator // yield and print the last pair from the iterator
println!("last: {:?}", it.next()); println!("last: {}", it.next());
// the iterator is now fully consumed // the iterator is now fully consumed
assert!(it.next().is_none()); assert!(it.next().is_none());
@ -349,9 +349,9 @@ returning another `DoubleEndedIterator` with `next` and `next_back` exchanged.
~~~ ~~~
let xs = [1, 2, 3, 4, 5, 6]; let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter(); let mut it = xs.iter();
println!("{:?}", it.next()); // prints `Some(&1)` println!("{}", it.next()); // prints `Some(1)`
println!("{:?}", it.next()); // prints `Some(&2)` println!("{}", it.next()); // prints `Some(2)`
println!("{:?}", it.next_back()); // prints `Some(&6)` println!("{}", it.next_back()); // prints `Some(6)`
// prints `5`, `4` and `3` // prints `5`, `4` and `3`
for &x in it.rev() { for &x in it.rev() {
@ -367,7 +367,7 @@ let xs = [1, 2, 3, 4];
let ys = [5, 6, 7, 8]; let ys = [5, 6, 7, 8];
let mut it = xs.iter().chain(ys.iter()).map(|&x| x * 2); let mut it = xs.iter().chain(ys.iter()).map(|&x| x * 2);
println!("{:?}", it.next()); // prints `Some(2)` println!("{}", it.next()); // prints `Some(2)`
// prints `16`, `14`, `12`, `10`, `8`, `6`, `4` // prints `16`, `14`, `12`, `10`, `8`, `6`, `4`
for x in it.rev() { for x in it.rev() {
@ -398,17 +398,17 @@ underlying iterators are.
let xs = [1, 2, 3, 4, 5]; let xs = [1, 2, 3, 4, 5];
let ys = ~[7, 9, 11]; let ys = ~[7, 9, 11];
let mut it = xs.iter().chain(ys.iter()); let mut it = xs.iter().chain(ys.iter());
println!("{:?}", it.idx(0)); // prints `Some(&1)` println!("{}", it.idx(0)); // prints `Some(1)`
println!("{:?}", it.idx(5)); // prints `Some(&7)` println!("{}", it.idx(5)); // prints `Some(7)`
println!("{:?}", it.idx(7)); // prints `Some(&11)` println!("{}", it.idx(7)); // prints `Some(11)`
println!("{:?}", it.idx(8)); // prints `None` println!("{}", it.idx(8)); // prints `None`
// yield two elements from the beginning, and one from the end // yield two elements from the beginning, and one from the end
it.next(); it.next();
it.next(); it.next();
it.next_back(); it.next_back();
println!("{:?}", it.idx(0)); // prints `Some(&3)` println!("{}", it.idx(0)); // prints `Some(3)`
println!("{:?}", it.idx(4)); // prints `Some(&9)` println!("{}", it.idx(4)); // prints `Some(9)`
println!("{:?}", it.idx(6)); // prints `None` println!("{}", it.idx(6)); // prints `None`
~~~ ~~~

View file

@ -102,6 +102,7 @@ you were writing this Rust code:
~~~rust ~~~rust
# fn transform(p: Point) -> Point { p } # fn transform(p: Point) -> Point { p }
#[deriving(Show)]
struct Point { struct Point {
x: int, x: int,
y: int, y: int,
@ -110,7 +111,7 @@ struct Point {
fn main() { fn main() {
let p0 = Point { x: 5, y: 10}; let p0 = Point { x: 5, y: 10};
let p1 = transform(p0); let p1 = transform(p0);
println!("{:?}", p1); println!("{}", p1);
} }
~~~ ~~~
@ -134,6 +135,7 @@ let p1 = transform(&p0);
This does work, but you don't need to create those references! The better way to write this is simply: This does work, but you don't need to create those references! The better way to write this is simply:
~~~rust ~~~rust
#[deriving(Show)]
struct Point { struct Point {
x: int, x: int,
y: int, y: int,
@ -146,7 +148,7 @@ fn transform(p: Point) -> Point {
fn main() { fn main() {
let p0 = Point { x: 5, y: 10}; let p0 = Point { x: 5, y: 10};
let p1 = transform(p0); let p1 = transform(p0);
println!("{:?}", p1); println!("{}", p1);
} }
~~~ ~~~
@ -182,7 +184,7 @@ trait. Therefore, unboxed traits don't make any sense, and aren't allowed.
Sometimes, you need a recursive data structure. The simplest is known as a 'cons list': Sometimes, you need a recursive data structure. The simplest is known as a 'cons list':
~~~rust ~~~rust
#[deriving(Show)]
enum List<T> { enum List<T> {
Nil, Nil,
Cons(T, Box<List<T>>), Cons(T, Box<List<T>>),
@ -190,7 +192,7 @@ enum List<T> {
fn main() { fn main() {
let list: List<int> = Cons(1, box Cons(2, box Cons(3, box Nil))); let list: List<int> = Cons(1, box Cons(2, box Cons(3, box Nil)));
println!("{:?}", list); println!("{}", list);
} }
~~~ ~~~
@ -349,7 +351,7 @@ fn main() {
let origin = @Point { x: 0.0, y: 0.0 }; let origin = @Point { x: 0.0, y: 0.0 };
let p1 = box Point { x: 5.0, y: 3.0 }; let p1 = box Point { x: 5.0, y: 3.0 };
println!("{:?}", compute_distance(origin, p1)); println!("{}", compute_distance(origin, p1));
} }
~~~ ~~~
@ -385,11 +387,11 @@ fn main() {
let mut x = box 5; let mut x = box 5;
if *x < 10 { if *x < 10 {
let y = &x; let y = &x;
println!("Oh no: {:?}", y); println!("Oh no: {}", y);
return; return;
} }
*x -= 1; *x -= 1;
println!("Oh no: {:?}", x); println!("Oh no: {}", x);
} }
~~~ ~~~
@ -404,11 +406,11 @@ fn main() {
let y = &x; let y = &x;
*x -= 1; *x -= 1;
println!("Oh no: {:?}", y); println!("Oh no: {}", y);
return; return;
} }
*x -= 1; *x -= 1;
println!("Oh no: {:?}", x); println!("Oh no: {}", x);
} }
~~~ ~~~

View file

@ -280,7 +280,7 @@ fn fib(n: u64) -> u64 {
let mut delayed_fib = sync::Future::spawn(proc() fib(50)); let mut delayed_fib = sync::Future::spawn(proc() fib(50));
make_a_sandwich(); make_a_sandwich();
println!("fib(50) = {:?}", delayed_fib.get()) println!("fib(50) = {}", delayed_fib.get())
# } # }
~~~ ~~~

View file

@ -405,14 +405,20 @@ will often see in examples, and its related family of macros: `print!`,
that [printf][pf] has. Unlike printf, `format!` will give you a compile-time that [printf][pf] has. Unlike printf, `format!` will give you a compile-time
error when the types of the directives don't match the types of the arguments. error when the types of the directives don't match the types of the arguments.
~~~~ ~~~
# let mystery_object = ();
// `{}` will print the "default format" of a type // `{}` will print the "default format" of a type
println!("{} is {}", "the answer", 43); println!("{} is {}", "the answer", 43);
~~~
// `{:?}` will conveniently print any type ~~~~
extern crate debug;
# fn main() {
# let mystery_object = ();
// `{:?}` will conveniently print any type,
// but requires the `debug` crate to be linked in
println!("what is this thing: {:?}", mystery_object); println!("what is this thing: {:?}", mystery_object);
# }
~~~~ ~~~~
[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf [pf]: http://en.cppreference.com/w/cpp/io/c/fprintf
@ -698,8 +704,8 @@ When an enum has simple integer discriminators, you can apply the `as` cast
operator to convert a variant to its discriminator value as an `int`: operator to convert a variant to its discriminator value as an `int`:
~~~~ ~~~~
# enum Direction { North } # #[deriving(Show)] enum Direction { North }
println!( "{:?} => {}", North, North as int ); println!( "{} => {}", North, North as int );
~~~~ ~~~~
It is possible to set the discriminator values to chosen constant values: It is possible to set the discriminator values to chosen constant values:
@ -2228,7 +2234,7 @@ method.
~~~~ ~~~~
# trait Printable { fn print(&self); } # trait Printable { fn print(&self); }
impl Printable for int { impl Printable for int {
fn print(&self) { println!("{:?}", *self) } fn print(&self) { println!("{}", *self) }
} }
impl Printable for String { impl Printable for String {
@ -2253,11 +2259,11 @@ types to be exactly as it is for `int`, above:
~~~~ ~~~~
# trait Printable { fn print(&self); } # trait Printable { fn print(&self); }
impl Printable for f32 { impl Printable for f32 {
fn print(&self) { println!("{:?}", *self) } fn print(&self) { println!("{}", *self) }
} }
impl Printable for bool { impl Printable for bool {
fn print(&self) { println!("{:?}", *self) } fn print(&self) { println!("{}", *self) }
} }
# true.print(); # true.print();
@ -2270,8 +2276,11 @@ definition of `print` right in the trait definition, instead of just
giving its signature. That is, we can write the following: giving its signature. That is, we can write the following:
~~~~ ~~~~
extern crate debug;
# fn main() {
trait Printable { trait Printable {
// Default method implementation // Default method implementation
fn print(&self) { println!("{:?}", *self) } fn print(&self) { println!("{:?}", *self) }
} }
@ -2289,6 +2298,7 @@ impl Printable for f32 {}
# ("foo".to_string()).print(); # ("foo".to_string()).print();
# true.print(); # true.print();
# 3.14159.print(); # 3.14159.print();
# }
~~~~ ~~~~
Here, the impls of `Printable` for `int`, `bool`, and `f32` don't Here, the impls of `Printable` for `int`, `bool`, and `f32` don't

View file

@ -74,8 +74,10 @@
extern crate core; extern crate core;
extern crate libc; extern crate libc;
// Allow testing this library // Allow testing this library
#[cfg(test)] extern crate debug;
#[cfg(test)] extern crate sync; #[cfg(test)] extern crate sync;
#[cfg(test)] extern crate native; #[cfg(test)] extern crate native;
#[cfg(test)] #[phase(syntax, link)] extern crate std; #[cfg(test)] #[phase(syntax, link)] extern crate std;

View file

@ -25,6 +25,7 @@
#![deny(deprecated_owned_vector)] #![deny(deprecated_owned_vector)]
extern crate rand; extern crate rand;
extern crate debug;
#[cfg(test)] extern crate test; #[cfg(test)] extern crate test;
#[cfg(test)] #[phase(syntax, link)] extern crate log; #[cfg(test)] #[phase(syntax, link)] extern crate log;

View file

@ -27,6 +27,7 @@
* demonstrates adding and subtracting two `Point`s. * demonstrates adding and subtracting two `Point`s.
* *
* ```rust * ```rust
* #[deriving(Show)]
* struct Point { * struct Point {
* x: int, * x: int,
* y: int * y: int
@ -44,8 +45,8 @@
* } * }
* } * }
* fn main() { * fn main() {
* println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}); * println!("{}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
* println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3}); * println!("{}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
* } * }
* ``` * ```
* *

View file

@ -419,7 +419,7 @@ pub trait ImmutableVector<'a, T> {
* ```rust * ```rust
* let v = &[1,2,3,4]; * let v = &[1,2,3,4];
* for win in v.windows(2) { * for win in v.windows(2) {
* println!("{:?}", win); * println!("{}", win);
* } * }
* ``` * ```
* *
@ -444,7 +444,7 @@ pub trait ImmutableVector<'a, T> {
* ```rust * ```rust
* let v = &[1,2,3,4,5]; * let v = &[1,2,3,4,5];
* for win in v.chunks(2) { * for win in v.chunks(2) {
* println!("{:?}", win); * println!("{}", win);
* } * }
* ``` * ```
* *

53
src/libdebug/fmt.rs Normal file
View file

@ -0,0 +1,53 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Implementation of the `{:?}` format qualifier
//!
//! This module contains the `Poly` trait which is used to implement the `{:?}`
//! format expression in formatting macros. This trait is defined for all types
//! automatically, so it is likely not necessary to use this module manually
use std::fmt;
use repr;
/// Format trait for the `?` character
pub trait Poly {
/// Formats the value using the given formatter.
#[experimental]
fn fmt(&self, &mut fmt::Formatter) -> fmt::Result;
}
#[doc(hidden)]
pub fn secret_poly<T: Poly>(x: &T, fmt: &mut fmt::Formatter) -> fmt::Result {
// FIXME #11938 - UFCS would make us able call the this method
// directly Poly::fmt(x, fmt).
x.fmt(fmt)
}
impl<T> Poly for T {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match (f.width, f.precision) {
(None, None) => {
match repr::write_repr(f, self) {
Ok(()) => Ok(()),
Err(..) => Err(fmt::WriteError),
}
}
// If we have a specified width for formatting, then we have to make
// this allocation of a new string
_ => {
let s = repr::repr_to_str(self);
f.pad(s.as_slice())
}
}
}
}

32
src/libdebug/lib.rs Normal file
View file

@ -0,0 +1,32 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Debugging utilities for Rust programs
//!
//! This crate is intended to provide useful functionality when debugging
//! programs, such as reflection for printing values. This crate is currently
//! entirely experimental as its makeup will likely change over time.
//! Additionally, it is not guaranteed that functionality such as reflection
//! will persist into the future.
#![crate_id = "debug#0.11.0-pre"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/")]
#![experimental]
#![feature(managed_boxes, macro_rules, quad_precision_float)]
#![allow(experimental)]
pub mod fmt;
pub mod reflect;
pub mod repr;

438
src/libdebug/reflect.rs Normal file
View file

@ -0,0 +1,438 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
Runtime type reflection
*/
#![allow(missing_doc)]
use std::intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
use std::mem;
/**
* Trait for visitor that wishes to reflect on data.
*
* To use this, create a struct that encapsulates the set of pointers you wish
* to walk through a data structure, and implement both `MovePtr` for it as well
* as `TyVisitor`; then build a MovePtrAdaptor wrapped around your struct.
*/
pub trait MovePtr {
fn move_ptr(&mut self, adjustment: |*u8| -> *u8);
fn push_ptr(&mut self);
fn pop_ptr(&mut self);
}
/// Helper function for alignment calculation.
#[inline]
pub fn align(size: uint, align: uint) -> uint {
((size + align) - 1u) & !(align - 1u)
}
/// Adaptor to wrap around visitors implementing MovePtr.
pub struct MovePtrAdaptor<V> {
inner: V
}
pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
MovePtrAdaptor { inner: v }
}
impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
#[inline]
pub fn bump(&mut self, sz: uint) {
self.inner.move_ptr(|p| ((p as uint) + sz) as *u8)
}
#[inline]
pub fn align(&mut self, a: uint) {
self.inner.move_ptr(|p| align(p as uint, a) as *u8)
}
#[inline]
pub fn align_to<T>(&mut self) {
self.align(mem::min_align_of::<T>());
}
#[inline]
pub fn bump_past<T>(&mut self) {
self.bump(mem::size_of::<T>());
}
pub fn unwrap(self) -> V { self.inner }
}
/// Abstract type-directed pointer-movement using the MovePtr trait
impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
fn visit_bot(&mut self) -> bool {
self.align_to::<()>();
if ! self.inner.visit_bot() { return false; }
self.bump_past::<()>();
true
}
fn visit_nil(&mut self) -> bool {
self.align_to::<()>();
if ! self.inner.visit_nil() { return false; }
self.bump_past::<()>();
true
}
fn visit_bool(&mut self) -> bool {
self.align_to::<bool>();
if ! self.inner.visit_bool() { return false; }
self.bump_past::<bool>();
true
}
fn visit_int(&mut self) -> bool {
self.align_to::<int>();
if ! self.inner.visit_int() { return false; }
self.bump_past::<int>();
true
}
fn visit_i8(&mut self) -> bool {
self.align_to::<i8>();
if ! self.inner.visit_i8() { return false; }
self.bump_past::<i8>();
true
}
fn visit_i16(&mut self) -> bool {
self.align_to::<i16>();
if ! self.inner.visit_i16() { return false; }
self.bump_past::<i16>();
true
}
fn visit_i32(&mut self) -> bool {
self.align_to::<i32>();
if ! self.inner.visit_i32() { return false; }
self.bump_past::<i32>();
true
}
fn visit_i64(&mut self) -> bool {
self.align_to::<i64>();
if ! self.inner.visit_i64() { return false; }
self.bump_past::<i64>();
true
}
fn visit_uint(&mut self) -> bool {
self.align_to::<uint>();
if ! self.inner.visit_uint() { return false; }
self.bump_past::<uint>();
true
}
fn visit_u8(&mut self) -> bool {
self.align_to::<u8>();
if ! self.inner.visit_u8() { return false; }
self.bump_past::<u8>();
true
}
fn visit_u16(&mut self) -> bool {
self.align_to::<u16>();
if ! self.inner.visit_u16() { return false; }
self.bump_past::<u16>();
true
}
fn visit_u32(&mut self) -> bool {
self.align_to::<u32>();
if ! self.inner.visit_u32() { return false; }
self.bump_past::<u32>();
true
}
fn visit_u64(&mut self) -> bool {
self.align_to::<u64>();
if ! self.inner.visit_u64() { return false; }
self.bump_past::<u64>();
true
}
fn visit_f32(&mut self) -> bool {
self.align_to::<f32>();
if ! self.inner.visit_f32() { return false; }
self.bump_past::<f32>();
true
}
fn visit_f64(&mut self) -> bool {
self.align_to::<f64>();
if ! self.inner.visit_f64() { return false; }
self.bump_past::<f64>();
true
}
fn visit_f128(&mut self) -> bool {
self.align_to::<f128>();
if ! self.inner.visit_f128() { return false; }
self.bump_past::<f128>();
true
}
fn visit_char(&mut self) -> bool {
self.align_to::<char>();
if ! self.inner.visit_char() { return false; }
self.bump_past::<char>();
true
}
fn visit_estr_box(&mut self) -> bool {
true
}
fn visit_estr_uniq(&mut self) -> bool {
self.align_to::<~str>();
if ! self.inner.visit_estr_uniq() { return false; }
self.bump_past::<~str>();
true
}
fn visit_estr_slice(&mut self) -> bool {
self.align_to::<&'static str>();
if ! self.inner.visit_estr_slice() { return false; }
self.bump_past::<&'static str>();
true
}
fn visit_estr_fixed(&mut self, n: uint,
sz: uint,
align: uint) -> bool {
self.align(align);
if ! self.inner.visit_estr_fixed(n, sz, align) { return false; }
self.bump(sz);
true
}
fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<@u8>();
if ! self.inner.visit_box(mtbl, inner) { return false; }
self.bump_past::<@u8>();
true
}
fn visit_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<Box<u8>>();
if ! self.inner.visit_uniq(mtbl, inner) { return false; }
self.bump_past::<Box<u8>>();
true
}
fn visit_ptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<*u8>();
if ! self.inner.visit_ptr(mtbl, inner) { return false; }
self.bump_past::<*u8>();
true
}
fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<&'static u8>();
if ! self.inner.visit_rptr(mtbl, inner) { return false; }
self.bump_past::<&'static u8>();
true
}
fn visit_evec_box(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool {
true
}
fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<~[u8]>();
if ! self.inner.visit_evec_uniq(mtbl, inner) { return false; }
self.bump_past::<~[u8]>();
true
}
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<&'static [u8]>();
if ! self.inner.visit_evec_slice(mtbl, inner) { return false; }
self.bump_past::<&'static [u8]>();
true
}
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
mtbl: uint, inner: *TyDesc) -> bool {
self.align(align);
if ! self.inner.visit_evec_fixed(n, sz, align, mtbl, inner) {
return false;
}
self.bump(sz);
true
}
fn visit_enter_rec(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
self.align(align);
if ! self.inner.visit_enter_rec(n_fields, sz, align) { return false; }
true
}
fn visit_rec_field(&mut self, i: uint, name: &str,
mtbl: uint, inner: *TyDesc) -> bool {
unsafe { self.align((*inner).align); }
if ! self.inner.visit_rec_field(i, name, mtbl, inner) {
return false;
}
unsafe { self.bump((*inner).size); }
true
}
fn visit_leave_rec(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
if ! self.inner.visit_leave_rec(n_fields, sz, align) { return false; }
true
}
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, named_fields, n_fields, sz, align) {
return false;
}
true
}
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, named, mtbl, inner) {
return false;
}
unsafe { self.bump((*inner).size); }
true
}
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
}
fn visit_enter_tup(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
self.align(align);
if ! self.inner.visit_enter_tup(n_fields, sz, align) { return false; }
true
}
fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
unsafe { self.align((*inner).align); }
if ! self.inner.visit_tup_field(i, inner) { return false; }
unsafe { self.bump((*inner).size); }
true
}
fn visit_leave_tup(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
if ! self.inner.visit_leave_tup(n_fields, sz, align) { return false; }
true
}
fn visit_enter_fn(&mut self, purity: uint, proto: uint,
n_inputs: uint, retstyle: uint) -> bool {
if ! self.inner.visit_enter_fn(purity, proto, n_inputs, retstyle) {
return false
}
true
}
fn visit_fn_input(&mut self, i: uint, mode: uint, inner: *TyDesc) -> bool {
if ! self.inner.visit_fn_input(i, mode, inner) { return false; }
true
}
fn visit_fn_output(&mut self, retstyle: uint, variadic: bool, inner: *TyDesc) -> bool {
if ! self.inner.visit_fn_output(retstyle, variadic, inner) { return false; }
true
}
fn visit_leave_fn(&mut self, purity: uint, proto: uint,
n_inputs: uint, retstyle: uint) -> bool {
if ! self.inner.visit_leave_fn(purity, proto, n_inputs, retstyle) {
return false;
}
true
}
fn visit_enter_enum(&mut self, n_variants: uint,
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint)
-> bool {
self.align(align);
if ! self.inner.visit_enter_enum(n_variants, get_disr, sz, align) {
return false;
}
true
}
fn visit_enter_enum_variant(&mut self, variant: uint,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
n_fields, name) {
return false;
}
true
}
fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool {
self.inner.push_ptr();
self.bump(offset);
if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
self.inner.pop_ptr();
true
}
fn visit_leave_enum_variant(&mut self, variant: uint,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
n_fields, name) {
return false;
}
true
}
fn visit_leave_enum(&mut self, n_variants: uint,
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint) -> bool {
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
return false;
}
self.bump(sz);
true
}
fn visit_trait(&mut self, name: &str) -> bool {
self.align_to::<Box<TyVisitor>>();
if ! self.inner.visit_trait(name) { return false; }
self.bump_past::<Box<TyVisitor>>();
true
}
fn visit_param(&mut self, i: uint) -> bool {
if ! self.inner.visit_param(i) { return false; }
true
}
fn visit_self(&mut self) -> bool {
self.align_to::<&'static u8>();
if ! self.inner.visit_self() { return false; }
self.align_to::<&'static u8>();
true
}
}

659
src/libdebug/repr.rs Normal file
View file

@ -0,0 +1,659 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
More runtime type reflection
*/
use std::char;
use std::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
use std::io;
use std::mem;
use std::raw;
use reflect;
use reflect::{MovePtr, align};
macro_rules! try( ($me:expr, $e:expr) => (
match $e {
Ok(()) => {},
Err(e) => { $me.last_err = Some(e); return false; }
}
) )
/// Representations
trait Repr {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()>;
}
impl Repr for () {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
writer.write("()".as_bytes())
}
}
impl Repr for bool {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
let s = if *self { "true" } else { "false" };
writer.write(s.as_bytes())
}
}
impl Repr for int {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
write!(writer, "{}", *self)
}
}
macro_rules! int_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
write!(writer, "{}{}", *self, $suffix)
}
}))
int_repr!(i8, "i8")
int_repr!(i16, "i16")
int_repr!(i32, "i32")
int_repr!(i64, "i64")
int_repr!(uint, "u")
int_repr!(u8, "u8")
int_repr!(u16, "u16")
int_repr!(u32, "u32")
int_repr!(u64, "u64")
macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
let s = self.to_str();
writer.write(s.as_bytes()).and_then(|()| {
writer.write(bytes!($suffix))
})
}
}))
num_repr!(f32, "f32")
num_repr!(f64, "f64")
// New implementation using reflect::MovePtr
enum VariantState {
SearchingFor(Disr),
Matched,
AlreadyFound
}
pub struct ReprVisitor<'a> {
ptr: *u8,
ptr_stk: Vec<*u8>,
var_stk: Vec<VariantState>,
writer: &'a mut io::Writer,
last_err: Option<io::IoError>,
}
pub fn ReprVisitor<'a>(ptr: *u8,
writer: &'a mut io::Writer) -> ReprVisitor<'a> {
ReprVisitor {
ptr: ptr,
ptr_stk: vec!(),
var_stk: vec!(),
writer: writer,
last_err: None,
}
}
impl<'a> MovePtr for ReprVisitor<'a> {
#[inline]
fn move_ptr(&mut self, adjustment: |*u8| -> *u8) {
self.ptr = adjustment(self.ptr);
}
fn push_ptr(&mut self) {
self.ptr_stk.push(self.ptr);
}
fn pop_ptr(&mut self) {
self.ptr = self.ptr_stk.pop().unwrap();
}
}
impl<'a> ReprVisitor<'a> {
// Various helpers for the TyVisitor impl
#[inline]
pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T| -> bool) -> bool {
unsafe {
f(self, mem::transmute::<*u8,&T>(self.ptr))
}
}
#[inline]
pub fn visit_inner(&mut self, inner: *TyDesc) -> bool {
self.visit_ptr_inner(self.ptr, inner)
}
#[inline]
pub fn visit_ptr_inner(&mut self, ptr: *u8, inner: *TyDesc) -> bool {
unsafe {
// This should call the constructor up above, but due to limiting
// issues we have to recreate it here.
let u = ReprVisitor {
ptr: ptr,
ptr_stk: vec!(),
var_stk: vec!(),
writer: mem::transmute_copy(&self.writer),
last_err: None,
};
let mut v = reflect::MovePtrAdaptor(u);
// Obviously this should not be a thing, but blame #8401 for now
visit_tydesc(inner, &mut v as &mut TyVisitor);
match v.unwrap().last_err {
Some(e) => {
self.last_err = Some(e);
false
}
None => true,
}
}
}
#[inline]
pub fn write<T:Repr>(&mut self) -> bool {
self.get(|this, v:&T| {
try!(this, v.write_repr(this.writer));
true
})
}
pub fn write_escaped_slice(&mut self, slice: &str) -> bool {
try!(self, self.writer.write(['"' as u8]));
for ch in slice.chars() {
if !self.write_escaped_char(ch, true) { return false }
}
try!(self, self.writer.write(['"' as u8]));
true
}
pub fn write_mut_qualifier(&mut self, mtbl: uint) -> bool {
if mtbl == 0 {
try!(self, self.writer.write("mut ".as_bytes()));
} else if mtbl == 1 {
// skip, this is ast::m_imm
} else {
fail!("invalid mutability value");
}
true
}
pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
let mut p = ptr as *u8;
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
try!(self, self.writer.write(['[' as u8]));
let mut first = true;
let mut left = len;
// unit structs have 0 size, and don't loop forever.
let dec = if sz == 0 {1} else {sz};
while left > 0 {
if first {
first = false;
} else {
try!(self, self.writer.write(", ".as_bytes()));
}
self.visit_ptr_inner(p as *u8, inner);
p = align(unsafe { p.offset(sz as int) as uint }, al) as *u8;
left -= dec;
}
try!(self, self.writer.write([']' as u8]));
true
}
pub fn write_unboxed_vec_repr(&mut self, _: uint, v: &raw::Vec<()>, inner: *TyDesc) -> bool {
self.write_vec_range(&v.data, v.fill, inner)
}
fn write_escaped_char(&mut self, ch: char, is_str: bool) -> bool {
try!(self, match ch {
'\t' => self.writer.write("\\t".as_bytes()),
'\r' => self.writer.write("\\r".as_bytes()),
'\n' => self.writer.write("\\n".as_bytes()),
'\\' => self.writer.write("\\\\".as_bytes()),
'\'' => {
if is_str {
self.writer.write("'".as_bytes())
} else {
self.writer.write("\\'".as_bytes())
}
}
'"' => {
if is_str {
self.writer.write("\\\"".as_bytes())
} else {
self.writer.write("\"".as_bytes())
}
}
'\x20'..'\x7e' => self.writer.write([ch as u8]),
_ => {
char::escape_unicode(ch, |c| {
let _ = self.writer.write([c as u8]);
});
Ok(())
}
});
return true;
}
}
impl<'a> TyVisitor for ReprVisitor<'a> {
fn visit_bot(&mut self) -> bool {
try!(self, self.writer.write("!".as_bytes()));
true
}
fn visit_nil(&mut self) -> bool { self.write::<()>() }
fn visit_bool(&mut self) -> bool { self.write::<bool>() }
fn visit_int(&mut self) -> bool { self.write::<int>() }
fn visit_i8(&mut self) -> bool { self.write::<i8>() }
fn visit_i16(&mut self) -> bool { self.write::<i16>() }
fn visit_i32(&mut self) -> bool { self.write::<i32>() }
fn visit_i64(&mut self) -> bool { self.write::<i64>() }
fn visit_uint(&mut self) -> bool { self.write::<uint>() }
fn visit_u8(&mut self) -> bool { self.write::<u8>() }
fn visit_u16(&mut self) -> bool { self.write::<u16>() }
fn visit_u32(&mut self) -> bool { self.write::<u32>() }
fn visit_u64(&mut self) -> bool { self.write::<u64>() }
fn visit_f32(&mut self) -> bool { self.write::<f32>() }
fn visit_f64(&mut self) -> bool { self.write::<f64>() }
fn visit_f128(&mut self) -> bool { fail!("not implemented") }
fn visit_char(&mut self) -> bool {
self.get::<char>(|this, &ch| {
try!(this, this.writer.write(['\'' as u8]));
if !this.write_escaped_char(ch, false) { return false }
try!(this, this.writer.write(['\'' as u8]));
true
})
}
fn visit_estr_box(&mut self) -> bool {
true
}
fn visit_estr_uniq(&mut self) -> bool {
self.get::<~str>(|this, s| {
try!(this, this.writer.write(['~' as u8]));
this.write_escaped_slice(*s)
})
}
fn visit_estr_slice(&mut self) -> bool {
self.get::<&str>(|this, s| this.write_escaped_slice(*s))
}
// Type no longer exists, vestigial function.
fn visit_estr_fixed(&mut self, _n: uint, _sz: uint,
_align: uint) -> bool { fail!(); }
fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
try!(self, self.writer.write(['@' as u8]));
self.write_mut_qualifier(mtbl);
self.get::<&raw::Box<()>>(|this, b| {
let p = &b.data as *() as *u8;
this.visit_ptr_inner(p, inner)
})
}
fn visit_uniq(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
try!(self, self.writer.write("box ".as_bytes()));
self.get::<*u8>(|this, b| {
this.visit_ptr_inner(*b, inner)
})
}
fn visit_ptr(&mut self, mtbl: uint, _inner: *TyDesc) -> bool {
self.get::<*u8>(|this, p| {
try!(this, write!(this.writer, "({} as *", *p));
this.write_mut_qualifier(mtbl);
try!(this, this.writer.write("())".as_bytes()));
true
})
}
fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
try!(self, self.writer.write(['&' as u8]));
self.write_mut_qualifier(mtbl);
self.get::<*u8>(|this, p| {
this.visit_ptr_inner(*p, inner)
})
}
fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.get::<&raw::Box<raw::Vec<()>>>(|this, b| {
try!(this, this.writer.write(['@' as u8]));
this.write_mut_qualifier(mtbl);
this.write_unboxed_vec_repr(mtbl, &b.data, inner)
})
}
fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.get::<&raw::Vec<()>>(|this, b| {
try!(this, this.writer.write("box ".as_bytes()));
this.write_unboxed_vec_repr(mtbl, *b, inner)
})
}
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
self.get::<raw::Slice<()>>(|this, s| {
try!(this, this.writer.write(['&' as u8]));
this.write_mut_qualifier(mtbl);
let size = unsafe {
if (*inner).size == 0 { 1 } else { (*inner).size }
};
this.write_vec_range(s.data, s.len * size, inner)
})
}
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
_: uint, inner: *TyDesc) -> bool {
let assumed_size = if sz == 0 { n } else { sz };
self.get::<()>(|this, b| {
this.write_vec_range(b, assumed_size, inner)
})
}
fn visit_enter_rec(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool {
try!(self, self.writer.write(['{' as u8]));
true
}
fn visit_rec_field(&mut self, i: uint, name: &str,
mtbl: uint, inner: *TyDesc) -> bool {
if i != 0 {
try!(self, self.writer.write(", ".as_bytes()));
}
self.write_mut_qualifier(mtbl);
try!(self, self.writer.write(name.as_bytes()));
try!(self, self.writer.write(": ".as_bytes()));
self.visit_inner(inner);
true
}
fn visit_leave_rec(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool {
try!(self, self.writer.write(['}' as u8]));
true
}
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
_sz: uint, _align: uint) -> bool {
try!(self, self.writer.write(name.as_bytes()));
if n_fields != 0 {
if named_fields {
try!(self, self.writer.write(['{' as u8]));
} else {
try!(self, self.writer.write(['(' as u8]));
}
}
true
}
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
_mtbl: uint, inner: *TyDesc) -> bool {
if i != 0 {
try!(self, self.writer.write(", ".as_bytes()));
}
if named {
try!(self, self.writer.write(name.as_bytes()));
try!(self, self.writer.write(": ".as_bytes()));
}
self.visit_inner(inner);
true
}
fn visit_leave_class(&mut self, _name: &str, named_fields: bool, n_fields: uint,
_sz: uint, _align: uint) -> bool {
if n_fields != 0 {
if named_fields {
try!(self, self.writer.write(['}' as u8]));
} else {
try!(self, self.writer.write([')' as u8]));
}
}
true
}
fn visit_enter_tup(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool {
try!(self, self.writer.write(['(' as u8]));
true
}
fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
if i != 0 {
try!(self, self.writer.write(", ".as_bytes()));
}
self.visit_inner(inner);
true
}
fn visit_leave_tup(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool {
if _n_fields == 1 {
try!(self, self.writer.write([',' as u8]));
}
try!(self, self.writer.write([')' as u8]));
true
}
fn visit_enter_enum(&mut self,
_n_variants: uint,
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
_sz: uint,
_align: uint) -> bool {
let disr = unsafe {
get_disr(mem::transmute(self.ptr))
};
self.var_stk.push(SearchingFor(disr));
true
}
fn visit_enter_enum_variant(&mut self, _variant: uint,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
let mut write = false;
match self.var_stk.pop().unwrap() {
SearchingFor(sought) => {
if disr_val == sought {
self.var_stk.push(Matched);
write = true;
} else {
self.var_stk.push(SearchingFor(sought));
}
}
Matched | AlreadyFound => {
self.var_stk.push(AlreadyFound);
}
}
if write {
try!(self, self.writer.write(name.as_bytes()));
if n_fields > 0 {
try!(self, self.writer.write(['(' as u8]));
}
}
true
}
fn visit_enum_variant_field(&mut self,
i: uint,
_offset: uint,
inner: *TyDesc)
-> bool {
match *self.var_stk.get(self.var_stk.len() - 1) {
Matched => {
if i != 0 {
try!(self, self.writer.write(", ".as_bytes()));
}
if ! self.visit_inner(inner) {
return false;
}
}
_ => ()
}
true
}
fn visit_leave_enum_variant(&mut self, _variant: uint,
_disr_val: Disr,
n_fields: uint,
_name: &str) -> bool {
match *self.var_stk.get(self.var_stk.len() - 1) {
Matched => {
if n_fields > 0 {
try!(self, self.writer.write([')' as u8]));
}
}
_ => ()
}
true
}
fn visit_leave_enum(&mut self,
_n_variants: uint,
_get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
_sz: uint,
_align: uint)
-> bool {
match self.var_stk.pop().unwrap() {
SearchingFor(..) => fail!("enum value matched no variant"),
_ => true
}
}
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
_n_inputs: uint, _retstyle: uint) -> bool {
try!(self, self.writer.write("fn(".as_bytes()));
true
}
fn visit_fn_input(&mut self, i: uint, _mode: uint, inner: *TyDesc) -> bool {
if i != 0 {
try!(self, self.writer.write(", ".as_bytes()));
}
let name = unsafe { (*inner).name };
try!(self, self.writer.write(name.as_bytes()));
true
}
fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool,
inner: *TyDesc) -> bool {
if variadic {
try!(self, self.writer.write(", ...".as_bytes()));
}
try!(self, self.writer.write(")".as_bytes()));
let name = unsafe { (*inner).name };
if name != "()" {
try!(self, self.writer.write(" -> ".as_bytes()));
try!(self, self.writer.write(name.as_bytes()));
}
true
}
fn visit_leave_fn(&mut self, _purity: uint, _proto: uint,
_n_inputs: uint, _retstyle: uint) -> bool { true }
fn visit_trait(&mut self, name: &str) -> bool {
try!(self, self.writer.write(name.as_bytes()));
true
}
fn visit_param(&mut self, _i: uint) -> bool { true }
fn visit_self(&mut self) -> bool { true }
}
pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
unsafe {
let ptr = object as *T as *u8;
let tydesc = get_tydesc::<T>();
let u = ReprVisitor(ptr, writer);
let mut v = reflect::MovePtrAdaptor(u);
visit_tydesc(tydesc, &mut v as &mut TyVisitor);
match v.unwrap().last_err {
Some(e) => Err(e),
None => Ok(()),
}
}
}
pub fn repr_to_str<T>(t: &T) -> String {
let mut result = io::MemWriter::new();
write_repr(&mut result as &mut io::Writer, t).unwrap();
String::from_utf8(result.unwrap()).unwrap()
}
#[cfg(test)]
struct P {a: int, b: f64}
#[test]
fn test_repr() {
use std::str;
use std::io::stdio::println;
use std::char::is_alphabetic;
use std::mem::swap;
fn exact_test<T>(t: &T, e:&str) {
let mut m = io::MemWriter::new();
write_repr(&mut m as &mut io::Writer, t).unwrap();
let s = str::from_utf8(m.unwrap().as_slice()).unwrap().to_owned();
assert_eq!(s.as_slice(), e);
}
exact_test(&10, "10");
exact_test(&true, "true");
exact_test(&false, "false");
exact_test(&1.234, "1.234f64");
exact_test(&("hello"), "\"hello\"");
exact_test(&(@10), "@10");
exact_test(&(box 10), "box 10");
exact_test(&(&10), "&10");
let mut x = 10;
exact_test(&(&mut x), "&mut 10");
exact_test(&(0 as *()), "(0x0 as *())");
exact_test(&(0 as *mut ()), "(0x0 as *mut ())");
exact_test(&(1,), "(1,)");
exact_test(&(&["hi", "there"]),
"&[\"hi\", \"there\"]");
exact_test(&(P{a:10, b:1.234}),
"repr::P{a: 10, b: 1.234f64}");
exact_test(&(@P{a:10, b:1.234}),
"@repr::P{a: 10, b: 1.234f64}");
exact_test(&(box P{a:10, b:1.234}),
"box repr::P{a: 10, b: 1.234f64}");
exact_test(&(&[1, 2]), "&[1, 2]");
exact_test(&(&mut [1, 2]), "&mut [1, 2]");
exact_test(&'\'', "'\\''");
exact_test(&'"', "'\"'");
exact_test(&("'"), "\"'\"");
exact_test(&("\""), "\"\\\"\"");
exact_test(&println, "fn(&str)");
exact_test(&swap::<int>, "fn(&mut int, &mut int)");
exact_test(&is_alphabetic, "fn(char) -> bool");
struct Bar(int, int);
exact_test(&(Bar(2, 2)), "repr::test_repr::Bar(2, 2)");
}

View file

@ -89,6 +89,7 @@
#![deny(missing_doc)] #![deny(missing_doc)]
#![deny(deprecated_owned_vector)] #![deny(deprecated_owned_vector)]
#[cfg(test)] extern crate debug;
#[cfg(test)] #[phase(syntax, link)] extern crate log; #[cfg(test)] #[phase(syntax, link)] extern crate log;
use std::cmp::Eq; use std::cmp::Eq;

View file

@ -51,8 +51,8 @@ impl Stack {
// page. It isn't guaranteed, but that's why FFI is unsafe. buf.data is // page. It isn't guaranteed, but that's why FFI is unsafe. buf.data is
// guaranteed to be aligned properly. // guaranteed to be aligned properly.
if !protect_last_page(&stack) { if !protect_last_page(&stack) {
fail!("Could not memory-protect guard page. stack={:?}, errno={}", fail!("Could not memory-protect guard page. stack={}, errno={}",
stack, errno()); stack.data, errno());
} }
let mut stk = Stack { let mut stk = Stack {

View file

@ -59,6 +59,7 @@
extern crate alloc; extern crate alloc;
extern crate libc; extern crate libc;
#[cfg(test)] extern crate debug;
use std::os; use std::os;
use std::rt; use std::rt;

View file

@ -65,7 +65,7 @@ if rng.gen() { // bool
```rust ```rust
let tuple_ptr = rand::random::<Box<(f64, char)>>(); let tuple_ptr = rand::random::<Box<(f64, char)>>();
println!("{:?}", tuple_ptr) println!("{}", tuple_ptr)
``` ```
*/ */
@ -80,8 +80,8 @@ println!("{:?}", tuple_ptr)
#![feature(macro_rules, managed_boxes, phase)] #![feature(macro_rules, managed_boxes, phase)]
#![deny(deprecated_owned_vector)] #![deny(deprecated_owned_vector)]
#[cfg(test)] #[cfg(test)] extern crate debug;
#[phase(syntax, link)] extern crate log; #[cfg(test)] #[phase(syntax, link)] extern crate log;
use std::io::IoResult; use std::io::IoResult;
use std::kinds::marker; use std::kinds::marker;
@ -152,7 +152,7 @@ pub trait Rng {
/// ///
/// let mut v = [0u8, .. 13579]; /// let mut v = [0u8, .. 13579];
/// task_rng().fill_bytes(v); /// task_rng().fill_bytes(v);
/// println!("{:?}", v); /// println!("{}", v.as_slice());
/// ``` /// ```
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
// this could, in theory, be done by transmuting dest to a // this could, in theory, be done by transmuting dest to a
@ -188,7 +188,7 @@ pub trait Rng {
/// let mut rng = task_rng(); /// let mut rng = task_rng();
/// let x: uint = rng.gen(); /// let x: uint = rng.gen();
/// println!("{}", x); /// println!("{}", x);
/// println!("{:?}", rng.gen::<(f64, bool)>()); /// println!("{}", rng.gen::<(f64, bool)>());
/// ``` /// ```
#[inline(always)] #[inline(always)]
fn gen<T: Rand>(&mut self) -> T { fn gen<T: Rand>(&mut self) -> T {

View file

@ -31,16 +31,17 @@ This API is completely unstable and subject to change.
#![feature(macro_rules, globs, struct_variant, managed_boxes, quote, #![feature(macro_rules, globs, struct_variant, managed_boxes, quote,
default_type_params, phase)] default_type_params, phase)]
extern crate flate;
extern crate arena; extern crate arena;
extern crate collections;
extern crate debug;
extern crate flate;
extern crate getopts;
extern crate graphviz; extern crate graphviz;
extern crate syntax; extern crate libc;
extern crate serialize; extern crate serialize;
extern crate sync; extern crate sync;
extern crate getopts; extern crate syntax;
extern crate collections;
extern crate time; extern crate time;
extern crate libc;
#[phase(syntax, link)] #[phase(syntax, link)]
extern crate log; extern crate log;

View file

@ -16,17 +16,18 @@
#![feature(globs, struct_variant, managed_boxes, macro_rules, phase)] #![feature(globs, struct_variant, managed_boxes, macro_rules, phase)]
extern crate syntax; extern crate collections;
extern crate debug;
extern crate getopts;
extern crate libc;
#[phase(syntax, link)]
extern crate log;
extern crate rustc; extern crate rustc;
extern crate serialize; extern crate serialize;
extern crate sync; extern crate sync;
extern crate getopts; extern crate syntax;
extern crate collections;
extern crate testing = "test"; extern crate testing = "test";
extern crate time; extern crate time;
#[phase(syntax, link)]
extern crate log;
extern crate libc;
use std::io; use std::io;
use std::io::{File, MemWriter}; use std::io::{File, MemWriter};

View file

@ -44,6 +44,7 @@ via `close` and `delete` methods.
#![allow(visible_private_types)] #![allow(visible_private_types)]
#[cfg(test)] extern crate green; #[cfg(test)] extern crate green;
#[cfg(test)] extern crate debug;
#[cfg(test)] extern crate realrustuv = "rustuv"; #[cfg(test)] extern crate realrustuv = "rustuv";
extern crate libc; extern crate libc;
extern crate alloc; extern crate alloc;

View file

@ -44,6 +44,7 @@ pub struct TaggedDoc<'a> {
pub doc: Doc<'a>, pub doc: Doc<'a>,
} }
#[deriving(Show)]
pub enum EbmlEncoderTag { pub enum EbmlEncoderTag {
EsUint, // 0 EsUint, // 0
EsU64, // 1 EsU64, // 1
@ -323,7 +324,7 @@ pub mod reader {
} }
fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> { fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
debug!(". next_doc(exp_tag={:?})", exp_tag); debug!(". next_doc(exp_tag={})", exp_tag);
if self.pos >= self.parent.end { if self.pos >= self.parent.end {
return Err(Expected(format_strbuf!("no more documents in \ return Err(Expected(format_strbuf!("no more documents in \
current node!"))); current node!")));
@ -339,8 +340,8 @@ pub mod reader {
r_doc.end); r_doc.end);
if r_tag != (exp_tag as uint) { if r_tag != (exp_tag as uint) {
return Err(Expected(format_strbuf!("expected EBML doc with \ return Err(Expected(format_strbuf!("expected EBML doc with \
tag {:?} but found tag \ tag {} but found tag \
{:?}", {}",
exp_tag, exp_tag,
r_tag))); r_tag)));
} }
@ -370,7 +371,7 @@ pub mod reader {
fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> { fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
let r = doc_as_u32(try!(self.next_doc(exp_tag))); let r = doc_as_u32(try!(self.next_doc(exp_tag)));
debug!("_next_uint exp_tag={:?} result={}", exp_tag, r); debug!("_next_uint exp_tag={} result={}", exp_tag, r);
Ok(r as uint) Ok(r as uint)
} }
@ -1085,7 +1086,7 @@ mod tests {
#[test] #[test]
fn test_option_int() { fn test_option_int() {
fn test_v(v: Option<int>) { fn test_v(v: Option<int>) {
debug!("v == {:?}", v); debug!("v == {}", v);
let mut wr = MemWriter::new(); let mut wr = MemWriter::new();
{ {
let mut ebml_w = writer::Encoder(&mut wr); let mut ebml_w = writer::Encoder(&mut wr);
@ -1094,7 +1095,7 @@ mod tests {
let ebml_doc = reader::Doc(wr.get_ref()); let ebml_doc = reader::Doc(wr.get_ref());
let mut deser = reader::Decoder(ebml_doc); let mut deser = reader::Decoder(ebml_doc);
let v1 = Decodable::decode(&mut deser).unwrap(); let v1 = Decodable::decode(&mut deser).unwrap();
debug!("v1 == {:?}", v1); debug!("v1 == {}", v1);
assert_eq!(v, v1); assert_eq!(v, v1);
} }

View file

@ -95,7 +95,7 @@ impl<'a> FromHex for &'a str {
* let hello_str = "Hello, World".as_bytes().to_hex(); * let hello_str = "Hello, World".as_bytes().to_hex();
* println!("{}", hello_str); * println!("{}", hello_str);
* let bytes = hello_str.as_slice().from_hex().unwrap(); * let bytes = hello_str.as_slice().from_hex().unwrap();
* println!("{:?}", bytes); * println!("{}", bytes);
* let result_str = String::from_utf8(bytes).unwrap(); * let result_str = String::from_utf8(bytes).unwrap();
* println!("{}", result_str); * println!("{}", result_str);
* } * }

View file

@ -1906,7 +1906,7 @@ impl ::Decoder<DecoderError> for Decoder {
names: &[&str], names: &[&str],
f: |&mut Decoder, uint| -> DecodeResult<T>) f: |&mut Decoder, uint| -> DecodeResult<T>)
-> DecodeResult<T> { -> DecodeResult<T> {
debug!("read_enum_variant(names={:?})", names); debug!("read_enum_variant(names={})", names);
let name = match self.pop() { let name = match self.pop() {
String(s) => s, String(s) => s,
Object(mut o) => { Object(mut o) => {
@ -1961,7 +1961,7 @@ impl ::Decoder<DecoderError> for Decoder {
names: &[&str], names: &[&str],
f: |&mut Decoder, uint| -> DecodeResult<T>) f: |&mut Decoder, uint| -> DecodeResult<T>)
-> DecodeResult<T> { -> DecodeResult<T> {
debug!("read_enum_struct_variant(names={:?})", names); debug!("read_enum_struct_variant(names={})", names);
self.read_enum_variant(names, f) self.read_enum_variant(names, f)
} }
@ -3013,7 +3013,7 @@ mod tests {
let bytes = mem_buf.unwrap(); let bytes = mem_buf.unwrap();
let json_str = from_utf8(bytes.as_slice()).unwrap(); let json_str = from_utf8(bytes.as_slice()).unwrap();
match from_str(json_str) { match from_str(json_str) {
Err(_) => fail!("Unable to parse json_str: {:?}", json_str), Err(_) => fail!("Unable to parse json_str: {}", json_str),
_ => {} // it parsed and we are good to go _ => {} // it parsed and we are good to go
} }
} }
@ -3033,7 +3033,7 @@ mod tests {
let bytes = mem_buf.unwrap(); let bytes = mem_buf.unwrap();
let json_str = from_utf8(bytes.as_slice()).unwrap(); let json_str = from_utf8(bytes.as_slice()).unwrap();
match from_str(json_str) { match from_str(json_str) {
Err(_) => fail!("Unable to parse json_str: {:?}", json_str), Err(_) => fail!("Unable to parse json_str: {}", json_str),
_ => {} // it parsed and we are good to go _ => {} // it parsed and we are good to go
} }
} }
@ -3043,7 +3043,7 @@ mod tests {
use Decodable; use Decodable;
let json_str = "{\"1\":true}"; let json_str = "{\"1\":true}";
let json_obj = match from_str(json_str) { let json_obj = match from_str(json_str) {
Err(_) => fail!("Unable to parse json_str: {:?}", json_str), Err(_) => fail!("Unable to parse json_str: {}", json_str),
Ok(o) => o Ok(o) => o
}; };
let mut decoder = Decoder::new(json_obj); let mut decoder = Decoder::new(json_obj);

View file

@ -34,12 +34,15 @@ format arguments directly while performing minimal allocations.
Some examples of the `format!` extension are: Some examples of the `format!` extension are:
```rust ```rust
format!("Hello"); // => "Hello".to_string() # extern crate debug;
format!("Hello, {:s}!", "world"); // => "Hello, world!".to_string() # fn main() {
format!("The number is {:d}", 1); // => "The number is 1".to_string() format!("Hello"); // => "Hello"
format!("{:?}", ~[3, 4]); // => "~[3, 4]".to_string() format!("Hello, {:s}!", "world"); // => "Hello, world!"
format!("{value}", value=4); // => "4".to_string() format!("The number is {:d}", 1); // => "The number is 1"
format!("{} {}", 1, 2); // => "1 2".to_string() format!("{:?}", (3, 4)); // => "(3, 4)"
format!("{value}", value=4); // => "4"
format!("{} {}", 1, 2); // => "1 2"
# }
``` ```
From these, you can see that the first argument is a format string. It is From these, you can see that the first argument is a format string. It is
@ -62,7 +65,7 @@ iterator over the argument. Each time a "next argument" specifier is seen, the
iterator advances. This leads to behavior like this: iterator advances. This leads to behavior like this:
```rust ```rust
format!("{1} {} {0} {}", 1, 2); // => "2 1 1 2".to_string() format!("{1} {} {0} {}", 1, 2); // => "2 1 1 2"
``` ```
The internal iterator over the argument has not been advanced by the time the The internal iterator over the argument has not been advanced by the time the
@ -89,9 +92,12 @@ identifier '=' expression
For example, the following `format!` expressions all use named argument: For example, the following `format!` expressions all use named argument:
```rust ```rust
format!("{argument}", argument = "test"); // => "test".to_string() # extern crate debug;
format!("{name} {}", 1, name = 2); // => "2 1".to_string() # fn main() {
format!("{a:s} {c:d} {b:?}", a="a", b=(), c=3); // => "a 3 ()".to_string() format!("{argument}", argument = "test"); // => "test"
format!("{name} {}", 1, name = 2); // => "2 1"
format!("{a:s} {c:d} {b:?}", a="a", b=(), c=3); // => "a 3 ()"
# }
``` ```
It is illegal to put positional parameters (those without names) after arguments It is illegal to put positional parameters (those without names) after arguments
@ -101,18 +107,15 @@ parameters that are unused by the format string.
### Argument types ### Argument types
Each argument's type is dictated by the format string. It is a requirement that Each argument's type is dictated by the format string. It is a requirement that
every argument is only ever referred to by one type. When specifying the format every argument is only ever referred to by one type. For example, this is an
of an argument, however, a string like `{}` indicates no type. This is allowed,
and if all references to one argument do not provide a type, then the format `?`
is used (the type's rust-representation is printed). For example, this is an
invalid format string: invalid format string:
```notrust ```notrust
{0:d} {0:s} {0:d} {0:s}
``` ```
Because the first argument is both referred to as an integer as well as a This is invalid because the first argument is both referred to as an integer as
string. well as a string.
Because formatting is done via traits, there is no requirement that the Because formatting is done via traits, there is no requirement that the
`d` format actually takes an `int`, but rather it simply requires a type which `d` format actually takes an `int`, but rather it simply requires a type which
@ -134,7 +137,7 @@ actually requesting that an argument ascribes to a particular trait. This allows
multiple actual types to be formatted via `{:d}` (like `i8` as well as `int`). multiple actual types to be formatted via `{:d}` (like `i8` as well as `int`).
The current mapping of types to traits is: The current mapping of types to traits is:
* `?` `Poly` * *nothing* `Show`
* `d` `Signed` * `d` `Signed`
* `i` `Signed` * `i` `Signed`
* `u` `Unsigned` * `u` `Unsigned`
@ -149,7 +152,11 @@ The current mapping of types to traits is:
* `f` `Float` * `f` `Float`
* `e` `LowerExp` * `e` `LowerExp`
* `E` `UpperExp` * `E` `UpperExp`
* *nothing* `Show` * `?` `Poly`
> **Note**: The `Poly` formatting trait is provided by [libdebug](../../debug/)
> and is an experimental implementation that should not be relied upon. In order
> to use the `?` modifier, the libdebug crate must be linked against.
What this means is that any type of argument which implements the What this means is that any type of argument which implements the
`std::fmt::Binary` trait can then be formatted with `{:t}`. Implementations are `std::fmt::Binary` trait can then be formatted with `{:t}`. Implementations are
@ -330,7 +337,7 @@ to reference the string value of the argument which was selected upon. As an
example: example:
```rust ```rust
format!("{0, select, other{#}}", "hello"); // => "hello".to_string() format!("{0, select, other{#}}", "hello"); // => "hello"
``` ```
This example is the equivalent of `{0:s}` essentially. This example is the equivalent of `{0:s}` essentially.
@ -485,7 +492,9 @@ will look like `"\\{"`.
use io::Writer; use io::Writer;
use io; use io;
#[cfg(stage0)]
use option::None; use option::None;
#[cfg(stage0)]
use repr; use repr;
use result::{Ok, Err}; use result::{Ok, Err};
use str::{Str, StrAllocating}; use str::{Str, StrAllocating};
@ -516,6 +525,7 @@ pub use core::fmt::{secret_float, secret_upper_exp, secret_lower_exp};
pub use core::fmt::{secret_pointer}; pub use core::fmt::{secret_pointer};
#[doc(hidden)] #[doc(hidden)]
#[cfg(stage0)]
pub fn secret_poly<T: Poly>(x: &T, fmt: &mut Formatter) -> Result { pub fn secret_poly<T: Poly>(x: &T, fmt: &mut Formatter) -> Result {
// FIXME #11938 - UFCS would make us able call the this method // FIXME #11938 - UFCS would make us able call the this method
// directly Poly::fmt(x, fmt). // directly Poly::fmt(x, fmt).
@ -523,6 +533,7 @@ pub fn secret_poly<T: Poly>(x: &T, fmt: &mut Formatter) -> Result {
} }
/// Format trait for the `?` character /// Format trait for the `?` character
#[cfg(stage0)]
pub trait Poly { pub trait Poly {
/// Formats the value using the given formatter. /// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result; fn fmt(&self, &mut Formatter) -> Result;
@ -558,6 +569,7 @@ pub fn format_strbuf(args: &Arguments) -> string::String {
str::from_utf8(output.unwrap().as_slice()).unwrap().into_string() str::from_utf8(output.unwrap().as_slice()).unwrap().into_string()
} }
#[cfg(stage0)]
impl<T> Poly for T { impl<T> Poly for T {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
match (f.width, f.precision) { match (f.width, f.precision) {

View file

@ -117,6 +117,7 @@
#[cfg(test)] extern crate rustuv; #[cfg(test)] extern crate rustuv;
#[cfg(test)] extern crate native; #[cfg(test)] extern crate native;
#[cfg(test)] extern crate green; #[cfg(test)] extern crate green;
#[cfg(test)] extern crate debug;
#[cfg(test)] #[phase(syntax, link)] extern crate log; #[cfg(test)] #[phase(syntax, link)] extern crate log;
// Make and rand accessible for benchmarking/testcases // Make and rand accessible for benchmarking/testcases

View file

@ -773,30 +773,30 @@ impl<'a, 'b> Context<'a, 'b> {
Named(ref s) => self.name_types.get(s) Named(ref s) => self.name_types.get(s)
}; };
let fmt_fn = match *ty { let (krate, fmt_fn) = match *ty {
Known(ref tyname) => { Known(ref tyname) => {
match tyname.as_slice() { match tyname.as_slice() {
"" => "secret_show", "" => ("std", "secret_show"),
"?" => "secret_poly", "?" => ("debug", "secret_poly"),
"b" => "secret_bool", "b" => ("std", "secret_bool"),
"c" => "secret_char", "c" => ("std", "secret_char"),
"d" | "i" => "secret_signed", "d" | "i" => ("std", "secret_signed"),
"e" => "secret_lower_exp", "e" => ("std", "secret_lower_exp"),
"E" => "secret_upper_exp", "E" => ("std", "secret_upper_exp"),
"f" => "secret_float", "f" => ("std", "secret_float"),
"o" => "secret_octal", "o" => ("std", "secret_octal"),
"p" => "secret_pointer", "p" => ("std", "secret_pointer"),
"s" => "secret_string", "s" => ("std", "secret_string"),
"t" => "secret_binary", "t" => ("std", "secret_binary"),
"u" => "secret_unsigned", "u" => ("std", "secret_unsigned"),
"x" => "secret_lower_hex", "x" => ("std", "secret_lower_hex"),
"X" => "secret_upper_hex", "X" => ("std", "secret_upper_hex"),
_ => { _ => {
self.ecx self.ecx
.span_err(sp, .span_err(sp,
format!("unknown format trait `{}`", format!("unknown format trait `{}`",
*tyname).as_slice()); *tyname).as_slice());
"dummy" ("std", "dummy")
} }
} }
} }
@ -815,7 +815,7 @@ impl<'a, 'b> Context<'a, 'b> {
}; };
let format_fn = self.ecx.path_global(sp, vec!( let format_fn = self.ecx.path_global(sp, vec!(
self.ecx.ident_of("std"), self.ecx.ident_of(krate),
self.ecx.ident_of("fmt"), self.ecx.ident_of("fmt"),
self.ecx.ident_of(fmt_fn))); self.ecx.ident_of(fmt_fn)));
self.ecx.expr_call_global(sp, vec!( self.ecx.expr_call_global(sp, vec!(

View file

@ -36,6 +36,7 @@ extern crate collections;
#[phase(syntax, link)] #[phase(syntax, link)]
extern crate log; extern crate log;
extern crate fmt_macros; extern crate fmt_macros;
extern crate debug;
pub mod util { pub mod util {
pub mod interner; pub mod interner;

View file

@ -21,7 +21,9 @@
#![feature(phase)] #![feature(phase)]
#![deny(deprecated_owned_vector)] #![deny(deprecated_owned_vector)]
#[cfg(test)] extern crate debug;
#[cfg(test)] #[phase(syntax, link)] extern crate log; #[cfg(test)] #[phase(syntax, link)] extern crate log;
extern crate serialize; extern crate serialize;
extern crate libc; extern crate libc;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]

View file

@ -412,8 +412,7 @@ impl<'a> Prep<'a> {
&'a self, blk: proc(&mut Exec):Send -> T) -> Work<'a, T> { &'a self, blk: proc(&mut Exec):Send -> T) -> Work<'a, T> {
let mut bo = Some(blk); let mut bo = Some(blk);
debug!("exec_work: looking up {} and {:?}", self.fn_name, debug!("exec_work: looking up {}", self.fn_name);
self.declared_inputs);
let cached = { let cached = {
let db = self.ctxt.db.deref().read(); let db = self.ctxt.db.deref().read();
db.deref().prepare(self.fn_name, &self.declared_inputs) db.deref().prepare(self.fn_name, &self.declared_inputs)
@ -425,8 +424,7 @@ impl<'a> Prep<'a> {
self.all_fresh("discovered input", disc_in) && self.all_fresh("discovered input", disc_in) &&
self.all_fresh("discovered output", disc_out) => { self.all_fresh("discovered output", disc_out) => {
debug!("Cache hit!"); debug!("Cache hit!");
debug!("Trying to decode: {:?} / {:?} / {}", debug!("Trying to decode: {}", *res);
disc_in, disc_out, *res);
Work::from_value(json_decode(res.as_slice())) Work::from_value(json_decode(res.as_slice()))
} }

View file

@ -11,6 +11,8 @@
// Make sure Rust generates the correct calling convention for extern // Make sure Rust generates the correct calling convention for extern
// functions. // functions.
extern crate debug;
#[inline(never)] #[inline(never)]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub extern "win64" fn foo(a: int, b: int, c: int, d: int) { pub extern "win64" fn foo(a: int, b: int, c: int, d: int) {

View file

@ -10,6 +10,7 @@
#![feature(phase)] #![feature(phase)]
#[phase(syntax, link)] extern crate log; #[phase(syntax, link)] extern crate log;
extern crate debug;
pub fn foo<T>() { pub fn foo<T>() {
fn death() -> int { fail!() } fn death() -> int { fail!() }

View file

@ -19,6 +19,7 @@
// version. // version.
extern crate time; extern crate time;
extern crate debug;
use std::comm; use std::comm;
use std::os; use std::os;

View file

@ -15,6 +15,7 @@
// I *think* it's the same, more or less. // I *think* it's the same, more or less.
extern crate time; extern crate time;
extern crate debug;
use std::os; use std::os;
use std::task; use std::task;

View file

@ -12,6 +12,7 @@
extern crate collections; extern crate collections;
extern crate time; extern crate time;
extern crate debug;
use collections::SmallIntMap; use collections::SmallIntMap;
use std::os; use std::os;

View file

@ -10,6 +10,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
struct clam { struct clam {
x: @int, x: @int,
y: @int, y: @int,

View file

@ -11,6 +11,8 @@
// Make sure that fn-to-block coercion isn't incorrectly lifted over // Make sure that fn-to-block coercion isn't incorrectly lifted over
// other tycons. // other tycons.
extern crate debug;
fn coerce(b: ||) -> extern fn() { fn coerce(b: ||) -> extern fn() {
fn lol(f: extern fn(v: ||) -> extern fn(), fn lol(f: extern fn(v: ||) -> extern fn(),
g: ||) -> extern fn() { return f(g); } g: ||) -> extern fn() { return f(g); }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct defer<'a> { struct defer<'a> {
x: &'a [&'a str], x: &'a [&'a str],
} }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn foo(x: int) { println!("{:?}", x); } fn foo(x: int) { println!("{:?}", x); }
fn main() { fn main() {

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
let f: || -> int = || { let f: || -> int = || {
let i: int; let i: int;

View file

@ -10,6 +10,8 @@
// Test that we do not permit moves from &[] matched by a vec pattern. // Test that we do not permit moves from &[] matched by a vec pattern.
extern crate debug;
#[deriving(Clone)] #[deriving(Clone)]
struct Foo { struct Foo {
string: String string: String

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
let x: int = 3; let x: int = 3;
let y: &mut int = &mut x; //~ ERROR cannot borrow let y: &mut int = &mut x; //~ ERROR cannot borrow

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct foo { struct foo {
i: int, i: int,
} }

View file

@ -10,6 +10,8 @@
// error-pattern:mismatched types: expected `()` but found `bool` // error-pattern:mismatched types: expected `()` but found `bool`
extern crate debug;
fn main() { fn main() {
let a = if true { true }; let a = if true { true };
println!("{:?}", a); println!("{:?}", a);

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
println!("{:?}", x); //~ ERROR unresolved name `x`. println!("{:?}", x); //~ ERROR unresolved name `x`.
} }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct C { struct C {
x: int, x: int,
} }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
enum f { g(int, int) } enum f { g(int, int) }
enum h { i(j, k) } enum h { i(j, k) }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
let foo = 100; let foo = 100;

View file

@ -8,4 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { format!("{:?}", None); } //~ ERROR unconstrained type fn main() { format!("{:?}", None); } //~ ERROR unconstrained type

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
format!("{:?}", None); //~ ERROR: cannot determine a type for this bounded format!("{:?}", None); //~ ERROR: cannot determine a type for this bounded
} }

View file

@ -8,5 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn force(f: || -> int) -> int { f() } fn force(f: || -> int) -> int { f() }
fn main() { println!("{:?}", force(|| {})); } //~ ERROR mismatched types fn main() { println!("{:?}", force(|| {})); } //~ ERROR mismatched types

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
let y: Box<int> = box 42; let y: Box<int> = box 42;

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
let y: Box<int> = box 42; let y: Box<int> = box 42;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn main() { fn main() {
let x = box 5; let x = box 5;
let y = x; let y = x;

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn send<T:Send>(ch: _chan<T>, data: T) { fn send<T:Send>(ch: _chan<T>, data: T) {
println!("{:?}", ch); println!("{:?}", ch);

View file

@ -11,6 +11,8 @@
// a good test that we merge paths correctly in the presence of a // a good test that we merge paths correctly in the presence of a
// variable that's used before it's declared // variable that's used before it's declared
extern crate debug;
fn my_fail() -> ! { fail!(); } fn my_fail() -> ! { fail!(); }
fn main() { fn main() {

View file

@ -11,6 +11,8 @@
// Tests that if you move from `x.f` or `x[0]`, `x` is inaccessible. // Tests that if you move from `x.f` or `x[0]`, `x` is inaccessible.
// Also tests that we give a more specific error message. // Also tests that we give a more specific error message.
extern crate debug;
struct Foo { f: String, y: int } struct Foo { f: String, y: int }
fn consume(_s: String) {} fn consume(_s: String) {}
fn touch<A>(_a: &A) {} fn touch<A>(_a: &A) {}

View file

@ -12,6 +12,8 @@
// bound must be noncopyable. For details see // bound must be noncopyable. For details see
// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ // http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
extern crate debug;
struct R<'a> { struct R<'a> {
// This struct is needed to create the // This struct is needed to create the
// otherwise infinite type of a fn that // otherwise infinite type of a fn that

View file

@ -10,6 +10,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
use std::task; use std::task;
struct Port<T>(@T); struct Port<T>(@T);

View file

@ -10,6 +10,9 @@
// Test that a class with a non-copyable field can't be // Test that a class with a non-copyable field can't be
// copied // copied
extern crate debug;
struct bar { struct bar {
x: int, x: int,
} }

View file

@ -10,6 +10,8 @@
// error-pattern:non-scalar cast // error-pattern:non-scalar cast
extern crate debug;
struct foo { struct foo {
x:int x:int
} }

View file

@ -15,6 +15,8 @@
// error-pattern: transmute called on types with different size // error-pattern: transmute called on types with different size
extern crate debug;
use std::mem; use std::mem;
#[packed] #[packed]

View file

@ -15,6 +15,8 @@
// error-pattern: transmute called on types with different size // error-pattern: transmute called on types with different size
extern crate debug;
use std::mem; use std::mem;
#[packed] #[packed]

View file

@ -10,6 +10,8 @@
// error-pattern: mismatched types // error-pattern: mismatched types
extern crate debug;
enum bar { t1((), Option<Vec<int> >), t2, } enum bar { t1((), Option<Vec<int> >), t2, }
fn foo(t: bar) { fn foo(t: bar) {

View file

@ -10,6 +10,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
use std::cell::Cell; use std::cell::Cell;
struct r { struct r {

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct r { struct r {
b: bool, b: bool,
} }

View file

@ -10,6 +10,7 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
use std::cell::Cell; use std::cell::Cell;
struct r { struct r {

View file

@ -110,6 +110,6 @@ fn main() {
'\u205F', '\u3000']; '\u205F', '\u3000'];
for c in chars.iter() { for c in chars.iter() {
let ws = c.is_whitespace(); let ws = c.is_whitespace();
println!("{:?} {:?}" , c , ws); println!("{} {}" , c , ws);
} }
} }

View file

@ -104,6 +104,6 @@ fn main() {
'\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; '\u2028', '\u2029', '\u202F', '\u205F', '\u3000'];
for c in chars.iter() { for c in chars.iter() {
let ws = c.is_whitespace(); let ws = c.is_whitespace();
println!("{:?} {:?}", c , ws); println!("{} {}", c , ws);
} }
} }

View file

@ -10,6 +10,8 @@
// error-pattern:called `Result::unwrap()` on an `Err` value // error-pattern:called `Result::unwrap()` on an `Err` value
extern crate debug;
use std::result; use std::result;
fn main() { fn main() {

View file

@ -12,6 +12,8 @@
// error-pattern:fail // error-pattern:fail
extern crate debug;
fn failfn() { fn failfn() {
fail!(); fail!();
} }

View file

@ -12,6 +12,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
use std::mem; use std::mem;
fn failfn() { fn failfn() {

View file

@ -12,6 +12,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
fn failfn() { fn failfn() {
fail!(); fail!();
} }

View file

@ -12,6 +12,7 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
fn failfn() { fn failfn() {
fail!(); fail!();

View file

@ -12,6 +12,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
fn failfn() { fn failfn() {
fail!(); fail!();
} }

View file

@ -12,6 +12,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
fn failfn() { fn failfn() {
fail!(); fail!();
} }

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct pair<A,B> { struct pair<A,B> {
a: A, b: B a: A, b: B

View file

@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct Pair<T, U> { a: T, b: U } struct Pair<T, U> { a: T, b: U }
struct Triple { x: int, y: int, z: int } struct Triple { x: int, y: int, z: int }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn inty(fun: proc(int) -> int) -> int { fn inty(fun: proc(int) -> int) -> int {
fun(100) fun(100)
} }

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn iter_vec<T>(v: Vec<T> , f: |&T|) { for x in v.iter() { f(x); } } fn iter_vec<T>(v: Vec<T> , f: |&T|) { for x in v.iter() { f(x); } }

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn iter_vec<T>(v: Vec<T> , f: |&T|) { for x in v.iter() { f(x); } } fn iter_vec<T>(v: Vec<T> , f: |&T|) { for x in v.iter() { f(x); } }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
use std::mem::swap; use std::mem::swap;
struct Ints {sum: Box<int>, values: Vec<int> } struct Ints {sum: Box<int>, values: Vec<int> }

View file

@ -12,6 +12,7 @@
// storing closure data (as we used to do), the u64 would // storing closure data (as we used to do), the u64 would
// overwrite the u16. // overwrite the u16.
extern crate debug;
struct Pair<A,B> { struct Pair<A,B> {
a: A, b: B a: A, b: B

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
use std::task; use std::task;
pub fn main() { pub fn main() {

View file

@ -14,6 +14,7 @@
#![feature(phase)] #![feature(phase)]
#[phase(syntax, link)] #[phase(syntax, link)]
extern crate log; extern crate log;
extern crate debug;
pub fn main() { pub fn main() {
// only fails if println! evaluates its argument. // only fails if println! evaluates its argument.

View file

@ -10,6 +10,8 @@
// exec-env:RUST_LOG=conditional-debug-macro-on=4 // exec-env:RUST_LOG=conditional-debug-macro-on=4
extern crate debug;
pub fn main() { pub fn main() {
// exits early if println! evaluates its arguments, otherwise it // exits early if println! evaluates its arguments, otherwise it
// will hit the fail. // will hit the fail.

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
static x : [int, ..4] = [1,2,3,4]; static x : [int, ..4] = [1,2,3,4];
static p : int = x[2]; static p : int = x[2];
static y : &'static [int] = &[1,2,3,4]; static y : &'static [int] = &[1,2,3,4];

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
static x : [int, ..4] = [1,2,3,4]; static x : [int, ..4] = [1,2,3,4];
static y : &'static [int] = &[1,2,3,4]; static y : &'static [int] = &[1,2,3,4];

View file

@ -10,6 +10,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
use std::cell::Cell; use std::cell::Cell;
pub fn main() { pub fn main() {

View file

@ -10,6 +10,8 @@
#![feature(macro_rules)] #![feature(macro_rules)]
extern crate debug;
macro_rules! check { macro_rules! check {
($m:ident, $t:ty, $v:expr) => {{ ($m:ident, $t:ty, $v:expr) => {{
mod $m { mod $m {

View file

@ -10,6 +10,8 @@
#![allow(dead_assignment)] #![allow(dead_assignment)]
extern crate debug;
pub fn main() { pub fn main() {
let x : &[int] = &[1,2,3,4,5]; let x : &[int] = &[1,2,3,4,5];
let mut z = &[1,2,3,4,5]; let mut z = &[1,2,3,4,5];

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
pub fn main() { pub fn main() {
let pi = 3.1415927; let pi = 3.1415927;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
use std::cell::RefCell; use std::cell::RefCell;
pub fn main() { pub fn main() {

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
struct Foo { struct Foo {
x: int, x: int,
y: int y: int

View file

@ -10,6 +10,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
fn id<T>(t: T) -> T { return t; } fn id<T>(t: T) -> T { return t; }
pub fn main() { pub fn main() {

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn id<T:Send>(t: T) -> T { return t; } fn id<T:Send>(t: T) -> T { return t; }

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn g<X>(x: X) -> X { return x; } fn g<X>(x: X) -> X { return x; }

View file

@ -10,6 +10,8 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
extern crate debug;
fn f<T>(x: @T) -> @T { return x; } fn f<T>(x: @T) -> @T { return x; }
pub fn main() { let x = f(@3); println!("{:?}", *x); } pub fn main() { let x = f(@3); println!("{:?}", *x); }

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn f<T>(x: Box<T>) -> Box<T> { return x; } fn f<T>(x: Box<T>) -> Box<T> { return x; }

View file

@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
enum noption<T> { some(T), } enum noption<T> { some(T), }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
extern crate debug;
fn get_third<T>(t: (T, T, T)) -> T { let (_, _, x) = t; return x; } fn get_third<T>(t: (T, T, T)) -> T { let (_, _, x) = t; return x; }
pub fn main() { pub fn main() {

Some files were not shown because too many files have changed in this diff Show more