Skip to content

Replace secret formatting functions with UFCS versions #18537

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 3, 2014
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