Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 132 additions & 4 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ pub trait UpperExp for Sized? {
fn fmt(&self, &mut Formatter) -> Result;
}

// FIXME #11938 - UFCS would make us able call the above methods
// directly Show::show(x, fmt).
// NOTE(stage0): Remove macro after next snapshot
#[cfg(stage0)]
macro_rules! uniform_fn_call_workaround {
($( $name: ident, $trait_: ident; )*) => {
$(
Expand All @@ -262,6 +262,8 @@ macro_rules! uniform_fn_call_workaround {
)*
}
}
// NOTE(stage0): Remove macro after next snapshot
#[cfg(stage0)]
uniform_fn_call_workaround! {
secret_show, Show;
secret_bool, Bool;
Expand Down Expand Up @@ -568,36 +570,65 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,

/// When the compiler determines that the type of an argument *must* be a string
/// (such as for select), then it invokes this method.
// NOTE(stage0): remove function after a snapshot
#[cfg(stage0)]
#[doc(hidden)] #[inline]
pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
argument(secret_string, s)
}

/// When the compiler determines that the type of an argument *must* be a string
/// (such as for select), then it invokes this method.
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[doc(hidden)] #[inline]
pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
argument(String::fmt, s)
}

/// When the compiler determines that the type of an argument *must* be a uint
/// (such as for plural), then it invokes this method.
// NOTE(stage0): remove function after a snapshot
#[cfg(stage0)]
#[doc(hidden)] #[inline]
pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
argument(secret_unsigned, s)
}

/// When the compiler determines that the type of an argument *must* be a uint
/// (such as for plural), then it invokes this method.
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[doc(hidden)] #[inline]
pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
argument(Unsigned::fmt, s)
}

// Implementations of the core formatting traits

impl<'a, Sized? T: Show> Show for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
}
impl<'a, Sized? T: Show> Show for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
}
impl<'a> Show for &'a Show+'a {
fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl Bool for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_string(&(if *self {"true"} else {"false"}), f)
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl Bool for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
String::fmt(if *self { "true" } else { "false" }, f)
}
}

impl<T: str::Str> String for T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.pad(self.as_slice())
Expand All @@ -610,6 +641,8 @@ impl String for str {
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl Char for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::Char;
Expand All @@ -621,28 +654,80 @@ impl Char for char {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl Char for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::Char;

let mut utf8 = [0u8, ..4];
let amt = self.encode_utf8(utf8).unwrap_or(0);
let s: &str = unsafe { mem::transmute(utf8[..amt]) };
String::fmt(s, f)
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (rt::FlagAlternate as uint);
secret_lower_hex::<uint>(&(*self as uint), f)
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (rt::FlagAlternate as uint);
LowerHex::fmt(&(*self as uint), f)
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Pointer for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*const T>(&(*self as *const T), f)
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Pointer for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(*self as *const T), f)
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<'a, T> Pointer for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*const T>(&(&**self as *const T), f)
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<'a, T> Pointer for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(*self as *const T), f)
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<'a, T> Pointer for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*const T>(&(&**self as *const T), f)
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<'a, T> Pointer for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(&**self as *const T), f)
}
}

macro_rules! floating(($ty:ident) => {
impl Float for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
Expand Down Expand Up @@ -712,26 +797,69 @@ floating!(f64)

// Implementation of Show for various core types

// NOTE(stage0): remove macro after a snapshot
#[cfg(stage0)]
macro_rules! delegate(($ty:ty to $other:ident) => {
impl Show for $ty {
fn fmt(&self, f: &mut Formatter) -> Result {
(concat_idents!(secret_, $other)(self, f))
}
}
})

// NOTE(stage0): remove these macros after a snapshot
#[cfg(stage0)]
delegate!(str to string)
#[cfg(stage0)]
delegate!(bool to bool)
#[cfg(stage0)]
delegate!(char to char)
#[cfg(stage0)]
delegate!(f32 to float)
#[cfg(stage0)]
delegate!(f64 to float)

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
macro_rules! delegate(($ty:ty to $other:ident) => {
impl Show for $ty {
fn fmt(&self, f: &mut Formatter) -> Result {
$other::fmt(self, f)
}
}
})
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(str to String)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(bool to Bool)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(char to Char)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(f32 to Float)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(f64 to Float)

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Show for *const T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Show for *const T {
fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Show for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Show for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
}

macro_rules! peel(($name:ident, $($other:ident,)*) => (tuple!($($other,)*)))

macro_rules! tuple (
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,14 +424,20 @@ pub use core::fmt::{Argument, Arguments, write, radix, Radix, RadixFmt};

#[doc(hidden)]
pub use core::fmt::{argument, argumentstr, argumentuint};
// NOTE(stage0): remove these imports after a snapshot
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_show, secret_string, secret_unsigned};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_signed, secret_lower_hex, secret_upper_hex};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_bool, secret_char, secret_octal, secret_binary};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_float, secret_upper_exp, secret_lower_exp};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_pointer};

Expand Down
37 changes: 19 additions & 18 deletions src/libsyntax/ext/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,28 +663,28 @@ impl<'a, 'b> Context<'a, 'b> {
fn format_arg(ecx: &ExtCtxt, sp: Span,
ty: &ArgumentType, arg: P<ast::Expr>)
-> P<ast::Expr> {
let (krate, fmt_fn) = match *ty {
let trait_ = match *ty {
Known(ref tyname) => {
match tyname.as_slice() {
"" => ("std", "secret_show"),
"b" => ("std", "secret_bool"),
"c" => ("std", "secret_char"),
"d" | "i" => ("std", "secret_signed"),
"e" => ("std", "secret_lower_exp"),
"E" => ("std", "secret_upper_exp"),
"f" => ("std", "secret_float"),
"o" => ("std", "secret_octal"),
"p" => ("std", "secret_pointer"),
"s" => ("std", "secret_string"),
"t" => ("std", "secret_binary"),
"u" => ("std", "secret_unsigned"),
"x" => ("std", "secret_lower_hex"),
"X" => ("std", "secret_upper_hex"),
"" => "Show",
"b" => "Bool",
"c" => "Char",
"d" | "i" => "Signed",
"e" => "LowerExp",
"E" => "UpperExp",
"f" => "Float",
"o" => "Octal",
"p" => "Pointer",
"s" => "String",
"t" => "Binary",
"u" => "Unsigned",
"x" => "LowerHex",
"X" => "UpperHex",
_ => {
ecx.span_err(sp,
format!("unknown format trait `{}`",
*tyname).as_slice());
("std", "dummy")
"Dummy"
}
}
}
Expand All @@ -697,9 +697,10 @@ impl<'a, 'b> Context<'a, 'b> {
};

let format_fn = ecx.path_global(sp, vec![
ecx.ident_of(krate),
ecx.ident_of("std"),
ecx.ident_of("fmt"),
ecx.ident_of(fmt_fn)]);
ecx.ident_of(trait_),
ecx.ident_of("fmt")]);
ecx.expr_call_global(sp, vec![
ecx.ident_of("std"),
ecx.ident_of("fmt"),
Expand Down