Skip to content

Commit

Permalink
Move std::{reflect,repr,Poly} to a libdebug crate
Browse files Browse the repository at this point in the history
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 rust-lang#12019

[breaking-change]
  • Loading branch information
alexcrichton committed May 28, 2014
1 parent 911cc9c commit b53454e
Show file tree
Hide file tree
Showing 156 changed files with 1,545 additions and 147 deletions.
11 changes: 6 additions & 5 deletions mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,25 @@

TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
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
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc

DEPS_core :=
DEPS_rlibc :=
DEPS_alloc := core libc native:jemalloc
DEPS_debug := std
DEPS_std := core libc alloc native:rustrt native:backtrace
DEPS_graphviz := std
DEPS_green := std rand native:context_switch
DEPS_rustuv := std native:uv native:uv_support
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 \
collections time log graphviz
collections time log graphviz debug
DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \
test time
test time debug
DEPS_flate := std native:miniz
DEPS_arena := std collections
DEPS_graphviz := std
Expand All @@ -79,7 +80,7 @@ DEPS_semver := std
DEPS_uuid := std serialize rand
DEPS_sync := std alloc
DEPS_getopts := std
DEPS_collections := std rand
DEPS_collections := std rand debug
DEPS_fourcc := syntax std
DEPS_hexfloat := syntax std
DEPS_num := std rand
Expand Down
24 changes: 12 additions & 12 deletions src/doc/guide-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ for (x, y) in it {
}
// yield and print the last pair from the iterator
println!("last: {:?}", it.next());
println!("last: {}", it.next());
// the iterator is now fully consumed
assert!(it.next().is_none());
Expand Down Expand Up @@ -349,9 +349,9 @@ returning another `DoubleEndedIterator` with `next` and `next_back` exchanged.
~~~
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter();
println!("{:?}", it.next()); // prints `Some(&1)`
println!("{:?}", it.next()); // prints `Some(&2)`
println!("{:?}", it.next_back()); // prints `Some(&6)`
println!("{}", it.next()); // prints `Some(1)`
println!("{}", it.next()); // prints `Some(2)`
println!("{}", it.next_back()); // prints `Some(6)`
// prints `5`, `4` and `3`
for &x in it.rev() {
Expand All @@ -367,7 +367,7 @@ let xs = [1, 2, 3, 4];
let ys = [5, 6, 7, 8];
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`
for x in it.rev() {
Expand Down Expand Up @@ -398,17 +398,17 @@ underlying iterators are.
let xs = [1, 2, 3, 4, 5];
let ys = ~[7, 9, 11];
let mut it = xs.iter().chain(ys.iter());
println!("{:?}", it.idx(0)); // prints `Some(&1)`
println!("{:?}", it.idx(5)); // prints `Some(&7)`
println!("{:?}", it.idx(7)); // prints `Some(&11)`
println!("{:?}", it.idx(8)); // prints `None`
println!("{}", it.idx(0)); // prints `Some(1)`
println!("{}", it.idx(5)); // prints `Some(7)`
println!("{}", it.idx(7)); // prints `Some(11)`
println!("{}", it.idx(8)); // prints `None`
// yield two elements from the beginning, and one from the end
it.next();
it.next();
it.next_back();
println!("{:?}", it.idx(0)); // prints `Some(&3)`
println!("{:?}", it.idx(4)); // prints `Some(&9)`
println!("{:?}", it.idx(6)); // prints `None`
println!("{}", it.idx(0)); // prints `Some(3)`
println!("{}", it.idx(4)); // prints `Some(9)`
println!("{}", it.idx(6)); // prints `None`
~~~
20 changes: 11 additions & 9 deletions src/doc/guide-pointers.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ you were writing this Rust code:

~~~rust
# fn transform(p: Point) -> Point { p }
#[deriving(Show)]
struct Point {
x: int,
y: int,
Expand All @@ -110,7 +111,7 @@ struct Point {
fn main() {
let p0 = Point { x: 5, y: 10};
let p1 = transform(p0);
println!("{:?}", p1);
println!("{}", p1);
}

~~~
Expand All @@ -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:

~~~rust
#[deriving(Show)]
struct Point {
x: int,
y: int,
Expand All @@ -146,7 +148,7 @@ fn transform(p: Point) -> Point {
fn main() {
let p0 = Point { x: 5, y: 10};
let p1 = transform(p0);
println!("{:?}", p1);
println!("{}", p1);
}
~~~

Expand Down Expand Up @@ -182,15 +184,15 @@ 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':

~~~rust

#[deriving(Show)]
enum List<T> {
Nil,
Cons(T, Box<List<T>>),
}

fn main() {
let list: List<int> = Cons(1, box Cons(2, box Cons(3, box Nil)));
println!("{:?}", list);
println!("{}", list);
}
~~~

Expand Down Expand Up @@ -349,7 +351,7 @@ fn main() {
let origin = @Point { x: 0.0, y: 0.0 };
let p1 = box Point { x: 5.0, y: 3.0 };

println!("{:?}", compute_distance(origin, p1));
println!("{}", compute_distance(origin, p1));
}
~~~

Expand Down Expand Up @@ -385,11 +387,11 @@ fn main() {
let mut x = box 5;
if *x < 10 {
let y = &x;
println!("Oh no: {:?}", y);
println!("Oh no: {}", y);
return;
}
*x -= 1;
println!("Oh no: {:?}", x);
println!("Oh no: {}", x);
}
~~~

Expand All @@ -404,11 +406,11 @@ fn main() {
let y = &x;
*x -= 1;
println!("Oh no: {:?}", y);
println!("Oh no: {}", y);
return;
}
*x -= 1;
println!("Oh no: {:?}", x);
println!("Oh no: {}", x);
}
~~~

Expand Down
2 changes: 1 addition & 1 deletion src/doc/guide-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ fn fib(n: u64) -> u64 {
let mut delayed_fib = sync::Future::spawn(proc() fib(50));
make_a_sandwich();
println!("fib(50) = {:?}", delayed_fib.get())
println!("fib(50) = {}", delayed_fib.get())
# }
~~~

Expand Down
30 changes: 20 additions & 10 deletions src/doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
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);
# }
~~~~

[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf
Expand Down Expand Up @@ -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`:

~~~~
# enum Direction { North }
println!( "{:?} => {}", North, North as int );
# #[deriving(Show)] enum Direction { North }
println!( "{} => {}", North, North as int );
~~~~

It is possible to set the discriminator values to chosen constant values:
Expand Down Expand Up @@ -2228,7 +2234,7 @@ method.
~~~~
# trait Printable { fn print(&self); }
impl Printable for int {
fn print(&self) { println!("{:?}", *self) }
fn print(&self) { println!("{}", *self) }
}
impl Printable for String {
Expand All @@ -2253,11 +2259,11 @@ types to be exactly as it is for `int`, above:
~~~~
# trait Printable { fn print(&self); }
impl Printable for f32 {
fn print(&self) { println!("{:?}", *self) }
fn print(&self) { println!("{}", *self) }
}
impl Printable for bool {
fn print(&self) { println!("{:?}", *self) }
fn print(&self) { println!("{}", *self) }
}
# true.print();
Expand All @@ -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:

~~~~
extern crate debug;
# fn main() {
trait Printable {
// Default method implementation
// Default method implementation
fn print(&self) { println!("{:?}", *self) }
}
Expand All @@ -2289,6 +2298,7 @@ impl Printable for f32 {}
# ("foo".to_string()).print();
# true.print();
# 3.14159.print();
# }
~~~~

Here, the impls of `Printable` for `int`, `bool`, and `f32` don't
Expand Down
2 changes: 2 additions & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@
extern crate core;
extern crate libc;


// Allow testing this library

#[cfg(test)] extern crate debug;
#[cfg(test)] extern crate sync;
#[cfg(test)] extern crate native;
#[cfg(test)] #[phase(syntax, link)] extern crate std;
Expand Down
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#![deny(deprecated_owned_vector)]

extern crate rand;
extern crate debug;

#[cfg(test)] extern crate test;
#[cfg(test)] #[phase(syntax, link)] extern crate log;
Expand Down
5 changes: 3 additions & 2 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* demonstrates adding and subtracting two `Point`s.
*
* ```rust
* #[deriving(Show)]
* struct Point {
* x: int,
* y: int
Expand All @@ -44,8 +45,8 @@
* }
* }
* 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});
* }
* ```
*
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ pub trait ImmutableVector<'a, T> {
* ```rust
* let v = &[1,2,3,4];
* for win in v.windows(2) {
* println!("{:?}", win);
* println!("{}", win);
* }
* ```
*
Expand All @@ -444,7 +444,7 @@ pub trait ImmutableVector<'a, T> {
* ```rust
* let v = &[1,2,3,4,5];
* for win in v.chunks(2) {
* println!("{:?}", win);
* println!("{}", win);
* }
* ```
*
Expand Down
53 changes: 53 additions & 0 deletions src/libdebug/fmt.rs
Original file line number Diff line number Diff line change
@@ -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())
}
}
}
}
Loading

0 comments on commit b53454e

Please sign in to comment.