From 92a341a11e80bdc9cbc2d4b4755f48d894dbe2e9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 13 Jan 2015 15:42:53 -0800 Subject: [PATCH] std: Stabilize the std::fmt module This commit performs a final stabilization pass over the std::fmt module, marking all necessary APIs as stable. One of the more interesting aspects of this module is that it exposes a good deal of its runtime representation to the outside world in order for `format_args!` to be able to construct the format strings. Instead of hacking the compiler to assume that these items are stable, this commit instead lays out a story for the stabilization and evolution of these APIs. There are three primary details used by the `format_args!` macro: 1. `Arguments` - an opaque package of a "compiled format string". This structure is passed around and the `write` function is the source of truth for transforming a compiled format string into a string at runtime. This must be able to be constructed in stable code. 2. `Argument` - an opaque structure representing an argument to a format string. This is *almost* a trait object as it's just a pointer/function pair, but due to the function originating from one of many traits, it's not actually a trait object. Like `Arguments`, this must be constructed from stable code. 3. `fmt::rt` - this module contains the runtime type definitions primarily for the `rt::Argument` structure. Whenever an argument is formatted with nonstandard flags, a corresponding `rt::Argument` is generated describing how the argument is being formatted. This can be used to construct an `Arguments`. The primary interface to `std::fmt` is the `Arguments` structure, and as such this type name is stabilize as-is today. It is expected for libraries to pass around an `Arguments` structure to represent a pending formatted computation. The remaining portions are largely "cruft" which would rather not be stabilized, but due to the stability checks they must be. As a result, almost all pieces have been renamed to represent that they are "version 1" of the formatting representation. The theory is that at a later date if we change the representation of these types we can add new definitions called "version 2" and corresponding constructors for `Arguments`. One of the other remaining large questions about the fmt module were how the pending I/O reform would affect the signatures of methods in the module. Due to [RFC 526][rfc], however, the writers of fmt are now incompatible with the writers of io, so this question has largely been solved. As a result the interfaces are largely stabilized as-is today. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md Specifically, the following changes were made: * The contents of `fmt::rt` were all moved under `fmt::rt::v1` * `fmt::rt` is stable * `fmt::rt::v1` is stable * `Error` is stable * `Writer` is stable * `Writer::write_str` is stable * `Writer::write_fmt` is stable * `Formatter` is stable * `Argument` has been renamed to `ArgumentV1` and is stable * `ArgumentV1::new` is stable * `ArgumentV1::from_uint` is stable * `Arguments::new_v1` is stable (renamed from `new`) * `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`) * All formatting traits are now stable, as well as the `fmt` method. * `fmt::write` is stable * `fmt::format` is stable * `Formatter::pad_integral` is stable * `Formatter::pad` is stable * `Formatter::write_str` is stable * `Formatter::write_fmt` is stable * Some assorted top level items which were only used by `format_args!` were removed in favor of static functions on `ArgumentV1` as well. * The formatting-flag-accessing methods remain unstable Within the contents of the `fmt::rt::v1` module, the following actions were taken: * Reexports of all enum variants were removed * All prefixes on enum variants were removed * A few miscellaneous enum variants were renamed * Otherwise all structs, fields, and variants were marked stable. In addition to these actions in the `std::fmt` module, many implementations of `Show` and `String` were stabilized as well. In some other modules: * `ToString` is now stable * `ToString::to_string` is now stable * `Vec` no longer implements `fmt::Writer` (this has moved to `String`) While stabilize the formatting traits, the following change was also made to the `result` module: * `Result::unwrap` now requires `String` instead of `Show` * `Result::unwrap_err` now requires `String` instead of `Show` This is a breaking change due to all of the changes to the `fmt::rt` module, but this likely will not have much impact on existing programs. It is also a breaking change due to the usage of `String` for `unwrap()` on `Result` instead of `Show`. Error types should implement `String` for human readable errors and `Show` for inspecting their representation. Closes #20661 [breaking-change] --- src/liballoc/arc.rs | 30 ++- src/liballoc/boxed.rs | 1 + src/liballoc/rc.rs | 2 +- src/libcollections/bit.rs | 1 + src/libcollections/enum_set.rs | 1 + src/libcollections/string.rs | 8 +- src/libcollections/vec.rs | 9 +- src/libcore/array.rs | 2 +- src/libcore/fmt/mod.rs | 229 +++++++++++------- src/libcore/fmt/num.rs | 8 +- src/libcore/fmt/{rt.rs => rt/v1.rs} | 82 ++++--- src/libcore/ops.rs | 8 +- src/libcore/result.rs | 10 +- src/librbml/lib.rs | 7 + src/libregex/parse.rs | 3 +- src/librustc/middle/cfg/graphviz.rs | 4 +- .../middle/infer/region_inference/graphviz.rs | 4 +- src/librustc/middle/traits/error_reporting.rs | 4 +- src/librustc_back/archive.rs | 4 +- .../borrowck/gather_loans/mod.rs | 2 +- src/librustc_trans/back/link.rs | 6 +- src/librustc_trans/back/write.rs | 8 +- src/librustdoc/lib.rs | 2 +- src/libserialize/json.rs | 22 +- src/libstd/ffi/c_str.rs | 2 +- src/libstd/fmt.rs | 6 +- src/libstd/io/buffered.rs | 4 + src/libstd/io/mod.rs | 3 + src/libstd/io/net/ip.rs | 2 + src/libstd/io/process.rs | 10 +- src/libstd/os.rs | 1 + src/libstd/path/mod.rs | 2 + src/libstd/path/posix.rs | 1 + src/libstd/path/windows.rs | 1 + src/libstd/sync/mpsc/mod.rs | 20 +- src/libstd/sync/poison.rs | 8 +- src/libstd/time/duration.rs | 1 + src/libsyntax/ext/format.rs | 136 +++++------ src/libterm/terminfo/mod.rs | 2 +- 39 files changed, 385 insertions(+), 271 deletions(-) rename src/libcore/fmt/{rt.rs => rt/v1.rs} (57%) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index c0cd034abfa4a..19e30830835ff 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -12,20 +12,22 @@ //! Threadsafe reference-counted boxes (the `Arc` type). //! -//! The `Arc` type provides shared ownership of an immutable value. Destruction is -//! deterministic, and will occur as soon as the last owner is gone. It is marked as `Send` because -//! it uses atomic reference counting. +//! The `Arc` type provides shared ownership of an immutable value. +//! Destruction is deterministic, and will occur as soon as the last owner is +//! gone. It is marked as `Send` because it uses atomic reference counting. //! -//! If you do not need thread-safety, and just need shared ownership, consider the [`Rc` -//! type](../rc/struct.Rc.html). It is the same as `Arc`, but does not use atomics, making it -//! both thread-unsafe as well as significantly faster when updating the reference count. +//! If you do not need thread-safety, and just need shared ownership, consider +//! the [`Rc` type](../rc/struct.Rc.html). It is the same as `Arc`, but +//! does not use atomics, making it both thread-unsafe as well as significantly +//! faster when updating the reference count. //! -//! The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A -//! `Weak` pointer can be upgraded to an `Arc` pointer, but will return `None` if the value -//! has already been dropped. +//! The `downgrade` method can be used to create a non-owning `Weak` pointer +//! to the box. A `Weak` pointer can be upgraded to an `Arc` pointer, but +//! will return `None` if the value has already been dropped. //! -//! For example, a tree with parent pointers can be represented by putting the nodes behind strong -//! `Arc` pointers, and then storing the parent pointers as `Weak` pointers. +//! For example, a tree with parent pointers can be represented by putting the +//! nodes behind strong `Arc` pointers, and then storing the parent pointers +//! as `Weak` pointers. //! //! # Examples //! @@ -87,8 +89,9 @@ use heap::deallocate; /// /// # Example /// -/// In this example, a large vector of floats is shared between several tasks. With simple pipes, -/// without `Arc`, a copy would have to be made for each task. +/// In this example, a large vector of floats is shared between several tasks. +/// With simple pipes, without `Arc`, a copy would have to be made for each +/// task. /// /// ```rust /// use std::sync::Arc; @@ -578,6 +581,7 @@ impl Ord for Arc { #[stable] impl Eq for Arc {} +#[stable] impl fmt::Show for Arc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Arc({:?})", (**self)) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 458eb3dce57a8..135a105e912c5 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -162,6 +162,7 @@ impl BoxAny for Box { } } +#[stable] impl fmt::Show for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Box({:?})", &**self) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f42c6dbdc15a5..703c4c47fd3a7 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -615,7 +615,7 @@ impl> Hash for Rc { } } -#[unstable = "Show is experimental."] +#[stable] impl fmt::Show for Rc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Rc({:?})", **self) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index c1b34c52fcc15..5704ba81707d7 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -1727,6 +1727,7 @@ impl BitvSet { } } +#[stable] impl fmt::Show for BitvSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "BitvSet {{")); diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 1b852d0ba680d..f6eb8b6a7be8e 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -31,6 +31,7 @@ pub struct EnumSet { impl Copy for EnumSet {} +#[stable] impl fmt::Show for EnumSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "EnumSet {{")); diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index e30e7e8600dcb..88047ef30da09 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -680,6 +680,7 @@ impl FromUtf8Error { pub fn utf8_error(&self) -> Utf8Error { self.error } } +#[stable] impl fmt::Show for FromUtf8Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::String::fmt(self, f) @@ -693,6 +694,7 @@ impl fmt::String for FromUtf8Error { } } +#[stable] impl fmt::Show for FromUtf16Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::String::fmt(self, f) @@ -821,7 +823,7 @@ impl fmt::String for String { } } -#[unstable = "waiting on fmt stabilization"] +#[stable] impl fmt::Show for String { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -938,11 +940,14 @@ impl FromStr for String { } /// A generic trait for converting a value to a string +#[stable] pub trait ToString { /// Converts the value of `self` to an owned string + #[stable] fn to_string(&self) -> String; } +#[stable] impl ToString for T { #[inline] fn to_string(&self) -> String { @@ -979,6 +984,7 @@ impl<'a> Str for CowString<'a> { } } +#[stable] impl fmt::Writer for String { #[inline] fn write_str(&mut self, s: &str) -> fmt::Result { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e5f9b2513e277..93471e2ad6e8d 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1457,20 +1457,13 @@ impl Default for Vec { } } -#[unstable = "waiting on Show stability"] +#[stable] impl fmt::Show for Vec { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt(self.as_slice(), f) } } -impl<'a> fmt::Writer for Vec { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.push_all(s.as_bytes()); - Ok(()) - } -} - //////////////////////////////////////////////////////////////////////////////// // Clone-on-write //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/array.rs b/src/libcore/array.rs index c07fac108d6f3..cc3db2e3771af 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -32,7 +32,7 @@ macro_rules! array_impls { } } - #[unstable = "waiting for Show to stabilize"] + #[stable] impl fmt::Show for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt(&&self[], f) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index a0ec9e5f151c2..200f38157ca00 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -10,7 +10,6 @@ //! Utilities for formatting and printing strings -#![allow(unused_variables)] #![stable] use any; @@ -27,6 +26,7 @@ use result; use slice::SliceExt; use slice; use str::{self, StrExt, Utf8Error}; +use self::rt::v1::Alignment; pub use self::num::radix; pub use self::num::Radix; @@ -34,9 +34,17 @@ pub use self::num::RadixFmt; mod num; mod float; -pub mod rt; -#[unstable = "core and I/O reconciliation may alter this definition"] +#[stable] +#[doc(hidden)] +pub mod rt { + #[cfg(stage0)] pub use self::v1::*; + + #[stable] + pub mod v1; +} + +#[stable] /// The type returned by formatter methods. pub type Result = result::Result<(), Error>; @@ -45,8 +53,8 @@ pub type Result = result::Result<(), Error>; /// This type does not support transmission of an error other than that an error /// occurred. Any extra information must be arranged to be transmitted through /// some other means. -#[unstable = "core and I/O reconciliation may alter this definition"] -#[derive(Copy)] +#[stable] +#[derive(Copy, Show)] pub struct Error; /// A collection of methods that are required to format a message into a stream. @@ -58,7 +66,7 @@ pub struct Error; /// This trait should generally not be implemented by consumers of the standard /// library. The `write!` macro accepts an instance of `io::Writer`, and the /// `io::Writer` trait is favored over implementing this trait. -#[unstable = "waiting for core and I/O reconciliation"] +#[stable] pub trait Writer { /// Writes a slice of bytes into this writer, returning whether the write /// succeeded. @@ -70,12 +78,14 @@ pub trait Writer { /// # Errors /// /// This function will return an instance of `FormatError` on error. + #[stable] fn write_str(&mut self, s: &str) -> Result; /// Glue for usage of the `write!` macro with implementers of this trait. /// /// This method should generally not be invoked manually, but rather through /// the `write!` macro itself. + #[stable] fn write_fmt(&mut self, args: Arguments) -> Result { // This Adapter is needed to allow `self` (of type `&mut // Self`) to be cast to a FormatWriter (below) without @@ -101,17 +111,17 @@ pub trait Writer { /// A struct to represent both where to emit formatting strings to and how they /// should be formatted. A mutable version of this is passed to all formatting /// traits. -#[unstable = "name may change and implemented traits are also unstable"] +#[stable] pub struct Formatter<'a> { flags: uint, fill: char, - align: rt::Alignment, + align: rt::v1::Alignment, width: Option, precision: Option, buf: &'a mut (Writer+'a), - curarg: slice::Iter<'a, Argument<'a>>, - args: &'a [Argument<'a>], + curarg: slice::Iter<'a, ArgumentV1<'a>>, + args: &'a [ArgumentV1<'a>], } // NB. Argument is essentially an optimized partially applied formatting function, @@ -123,34 +133,40 @@ enum Void {} /// family of functions. It contains a function to format the given value. At /// compile time it is ensured that the function and the value have the correct /// types, and then this struct is used to canonicalize arguments to one type. -#[unstable = "implementation detail of the `format_args!` macro"] #[derive(Copy)] -pub struct Argument<'a> { +#[stable] +#[doc(hidden)] +pub struct ArgumentV1<'a> { value: &'a Void, formatter: fn(&Void, &mut Formatter) -> Result, } -impl<'a> Argument<'a> { +impl<'a> ArgumentV1<'a> { #[inline(never)] fn show_uint(x: &uint, f: &mut Formatter) -> Result { Show::fmt(x, f) } - fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'b> { + #[doc(hidden)] + #[stable] + pub fn new<'b, T>(x: &'b T, + f: fn(&T, &mut Formatter) -> Result) -> ArgumentV1<'b> { unsafe { - Argument { + ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } } } - fn from_uint(x: &uint) -> Argument { - Argument::new(x, Argument::show_uint) + #[doc(hidden)] + #[stable] + pub fn from_uint(x: &uint) -> ArgumentV1 { + ArgumentV1::new(x, ArgumentV1::show_uint) } fn as_uint(&self) -> Option { - if self.formatter as uint == Argument::show_uint as uint { + if self.formatter as uint == ArgumentV1::show_uint as uint { Some(unsafe { *(self.value as *const _ as *const uint) }) } else { None @@ -158,13 +174,32 @@ impl<'a> Argument<'a> { } } +// flags available in the v1 format of format_args +#[derive(Copy)] +#[allow(dead_code)] // SignMinus isn't currently used +enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, } + impl<'a> Arguments<'a> { /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. #[doc(hidden)] #[inline] - #[unstable = "implementation detail of the `format_args!` macro"] + #[stable] + pub fn new_v1(pieces: &'a [&'a str], + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { + Arguments { + pieces: pieces, + fmt: None, + args: args + } + } + + /// When using the format_args!() macro, this function is used to generate the + /// Arguments structure. + #[doc(hidden)] #[inline] + #[cfg(stage0)] + #[stable] pub fn new(pieces: &'a [&'a str], - args: &'a [Argument<'a>]) -> Arguments<'a> { + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { Arguments { pieces: pieces, fmt: None, @@ -182,8 +217,8 @@ impl<'a> Arguments<'a> { #[unstable = "implementation detail of the `format_args!` macro"] #[cfg(stage0)] // SNAP 9e4e524 pub fn with_placeholders(pieces: &'a [&'a str], - fmt: &'a [rt::Argument<'a>], - args: &'a [Argument<'a>]) -> Arguments<'a> { + fmt: &'a [rt::v1::Argument<'a>], + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { Arguments { pieces: pieces, fmt: Some(fmt), @@ -197,11 +232,10 @@ impl<'a> Arguments<'a> { /// created with `argumentuint`. However, failing to do so doesn't cause /// unsafety, but will ignore invalid . #[doc(hidden)] #[inline] - #[unstable = "implementation detail of the `format_args!` macro"] #[cfg(not(stage0))] - pub fn with_placeholders(pieces: &'a [&'a str], - fmt: &'a [rt::Argument], - args: &'a [Argument<'a>]) -> Arguments<'a> { + pub fn new_v1_formatted(pieces: &'a [&'a str], + args: &'a [ArgumentV1<'a>], + fmt: &'a [rt::v1::Argument]) -> Arguments<'a> { Arguments { pieces: pieces, fmt: Some(fmt), @@ -228,15 +262,16 @@ pub struct Arguments<'a> { // Placeholder specs, or `None` if all specs are default (as in "{}{}"). // SNAP 9e4e524 #[cfg(stage0)] - fmt: Option<&'a [rt::Argument<'a>]>, + fmt: Option<&'a [rt::v1::Argument<'a>]>, #[cfg(not(stage0))] - fmt: Option<&'a [rt::Argument]>, + fmt: Option<&'a [rt::v1::Argument]>, // Dynamic arguments for interpolation, to be interleaved with string // pieces. (Every argument is preceded by a string piece.) - args: &'a [Argument<'a>], + args: &'a [ArgumentV1<'a>], } +#[stable] impl<'a> Show for Arguments<'a> { fn fmt(&self, fmt: &mut Formatter) -> Result { String::fmt(self, fmt) @@ -252,67 +287,76 @@ impl<'a> String for Arguments<'a> { /// Format trait for the `:?` format. Useful for debugging, most all types /// should implement this. -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait Show { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// When a value can be semantically expressed as a String, this trait may be /// used. It corresponds to the default format, `{}`. -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait String { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `o` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait Octal { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `b` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait Binary { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `x` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait LowerHex { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `X` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait UpperHex { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `p` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait Pointer { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `e` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait LowerExp { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `E` character -#[unstable = "I/O and core have yet to be reconciled"] +#[stable] pub trait UpperExp { /// Formats the value using the given formatter. + #[stable] fn fmt(&self, &mut Formatter) -> Result; } @@ -324,15 +368,14 @@ pub trait UpperExp { /// /// * output - the buffer to write output to /// * args - the precompiled arguments generated by `format_args!` -#[unstable = "libcore and I/O have yet to be reconciled, and this is an \ - implementation detail which should not otherwise be exported"] +#[stable] pub fn write(output: &mut Writer, args: Arguments) -> Result { let mut formatter = Formatter { flags: 0, width: None, precision: None, buf: output, - align: rt::AlignUnknown, + align: Alignment::Unknown, fill: ' ', args: args.args, curarg: args.args.iter(), @@ -374,7 +417,7 @@ impl<'a> Formatter<'a> { // First up is the collection of functions used to execute a format string // at runtime. This consumes all of the compile-time statics generated by // the format! syntax extension. - fn run(&mut self, arg: &rt::Argument) -> Result { + fn run(&mut self, arg: &rt::v1::Argument) -> Result { // Fill in the format parameters into the formatter self.fill = arg.format.fill; self.align = arg.format.align; @@ -384,22 +427,22 @@ impl<'a> Formatter<'a> { // Extract the correct argument let value = match arg.position { - rt::ArgumentNext => { *self.curarg.next().unwrap() } - rt::ArgumentIs(i) => self.args[i], + rt::v1::Position::Next => { *self.curarg.next().unwrap() } + rt::v1::Position::At(i) => self.args[i], }; // Then actually do some printing (value.formatter)(value.value, self) } - fn getcount(&mut self, cnt: &rt::Count) -> Option { + fn getcount(&mut self, cnt: &rt::v1::Count) -> Option { match *cnt { - rt::CountIs(n) => Some(n), - rt::CountImplied => None, - rt::CountIsParam(i) => { + rt::v1::Count::Is(n) => Some(n), + rt::v1::Count::Implied => None, + rt::v1::Count::Param(i) => { self.args[i].as_uint() } - rt::CountIsNextParam => { + rt::v1::Count::NextParam => { self.curarg.next().and_then(|arg| arg.as_uint()) } } @@ -409,8 +452,8 @@ impl<'a> Formatter<'a> { // all formatting traits can use. /// Performs the correct padding for an integer which has already been - /// emitted into a byte-array. The byte-array should *not* contain the sign - /// for the integer, that will be added by this method. + /// emitted into a str. The str should *not* contain the sign for the + /// integer, that will be added by this method. /// /// # Arguments /// @@ -421,26 +464,25 @@ impl<'a> Formatter<'a> { /// /// This function will correctly account for the flags provided as well as /// the minimum width. It will not take precision into account. - #[unstable = "definition may change slightly over time"] + #[stable] pub fn pad_integral(&mut self, is_positive: bool, prefix: &str, buf: &str) -> Result { use char::CharExt; - use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad}; let mut width = buf.len(); let mut sign = None; if !is_positive { sign = Some('-'); width += 1; - } else if self.flags & (1 << (FlagSignPlus as uint)) != 0 { + } else if self.flags & (1 << (FlagV1::SignPlus as uint)) != 0 { sign = Some('+'); width += 1; } let mut prefixed = false; - if self.flags & (1 << (FlagAlternate as uint)) != 0 { + if self.flags & (1 << (FlagV1::Alternate as uint)) != 0 { prefixed = true; width += prefix.char_len(); } @@ -470,16 +512,16 @@ impl<'a> Formatter<'a> { } // The sign and prefix goes before the padding if the fill character // is zero - Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => { + Some(min) if self.flags & (1 << (FlagV1::SignAwareZeroPad as uint)) != 0 => { self.fill = '0'; try!(write_prefix(self)); - self.with_padding(min - width, rt::AlignRight, |f| { + self.with_padding(min - width, Alignment::Right, |f| { f.buf.write_str(buf) }) } // Otherwise, the sign and prefix goes after the padding Some(min) => { - self.with_padding(min - width, rt::AlignRight, |f| { + self.with_padding(min - width, Alignment::Right, |f| { try!(write_prefix(f)); f.buf.write_str(buf) }) } @@ -497,7 +539,7 @@ impl<'a> Formatter<'a> { /// is longer than this length /// /// Notably this function ignored the `flag` parameters - #[unstable = "definition may change slightly over time"] + #[stable] pub fn pad(&mut self, s: &str) -> Result { // Make sure there's a fast path up front if self.width.is_none() && self.precision.is_none() { @@ -531,7 +573,7 @@ impl<'a> Formatter<'a> { // If we're under both the maximum and the minimum width, then fill // up the minimum width with the specified string + some alignment. Some(width) => { - self.with_padding(width - s.char_len(), rt::AlignLeft, |me| { + self.with_padding(width - s.char_len(), Alignment::Left, |me| { me.buf.write_str(s) }) } @@ -540,19 +582,20 @@ impl<'a> Formatter<'a> { /// Runs a callback, emitting the correct padding either before or /// afterwards depending on whether right or left alignment is requested. - fn with_padding(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where - F: FnOnce(&mut Formatter) -> Result, + fn with_padding(&mut self, padding: uint, default: Alignment, + f: F) -> Result + where F: FnOnce(&mut Formatter) -> Result, { use char::CharExt; let align = match self.align { - rt::AlignUnknown => default, + Alignment::Unknown => default, _ => self.align }; let (pre_pad, post_pad) = match align { - rt::AlignLeft => (0u, padding), - rt::AlignRight | rt::AlignUnknown => (padding, 0u), - rt::AlignCenter => (padding / 2, (padding + 1) / 2), + Alignment::Left => (0u, padding), + Alignment::Right | Alignment::Unknown => (padding, 0u), + Alignment::Center => (padding / 2, (padding + 1) / 2), }; let mut fill = [0u8; 4]; @@ -574,20 +617,20 @@ impl<'a> Formatter<'a> { /// Writes some data to the underlying buffer contained within this /// formatter. - #[unstable = "reconciling core and I/O may alter this definition"] + #[stable] pub fn write_str(&mut self, data: &str) -> Result { self.buf.write_str(data) } /// Writes some formatted information into this instance - #[unstable = "reconciling core and I/O may alter this definition"] + #[stable] pub fn write_fmt(&mut self, fmt: Arguments) -> Result { write(self.buf, fmt) } /// Flags for formatting (packed version of rt::Flag) #[unstable = "return type may change and method was just created"] - pub fn flags(&self) -> uint { self.flags } + pub fn flags(&self) -> usize { self.flags } /// Character used as 'fill' whenever there is alignment #[unstable = "method was just created"] @@ -595,7 +638,7 @@ impl<'a> Formatter<'a> { /// Flag indicating what form of alignment was requested #[unstable = "method was just created"] - pub fn align(&self) -> rt::Alignment { self.align } + pub fn align(&self) -> Alignment { self.align } /// Optionally specified integer width that the output should be #[unstable = "method was just created"] @@ -606,7 +649,8 @@ impl<'a> Formatter<'a> { pub fn precision(&self) -> Option { self.precision } } -impl Show for Error { +#[stable] +impl String for Error { fn fmt(&self, f: &mut Formatter) -> Result { String::fmt("an error occurred when formatting an argument", f) } @@ -616,17 +660,19 @@ impl Show for Error { /// create the Argument structures that are passed into the `format` function. #[doc(hidden)] #[inline] #[unstable = "implementation detail of the `format_args!` macro"] +#[cfg(stage0)] pub fn argument<'a, T>(f: fn(&T, &mut Formatter) -> Result, - t: &'a T) -> Argument<'a> { - Argument::new(t, f) + t: &'a T) -> ArgumentV1<'a> { + ArgumentV1::new(t, f) } /// When the compiler determines that the type of an argument *must* be a uint /// (such as for width and precision), then it invokes this method. #[doc(hidden)] #[inline] #[unstable = "implementation detail of the `format_args!` macro"] -pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { - Argument::from_uint(s) +#[cfg(stage0)] +pub fn argumentuint<'a>(s: &'a uint) -> ArgumentV1<'a> { + ArgumentV1::from_uint(s) } // Implementations of the core formatting traits @@ -634,9 +680,11 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { macro_rules! fmt_refs { ($($tr:ident),*) => { $( + #[stable] impl<'a, T: ?Sized + $tr> $tr for &'a T { fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } + #[stable] impl<'a, T: ?Sized + $tr> $tr for &'a mut T { fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } @@ -646,6 +694,7 @@ macro_rules! fmt_refs { fmt_refs! { Show, String, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } +#[stable] impl Show for bool { fn fmt(&self, f: &mut Formatter) -> Result { String::fmt(self, f) @@ -659,6 +708,7 @@ impl String for bool { } } +#[stable] impl Show for str { fn fmt(&self, f: &mut Formatter) -> Result { try!(write!(f, "\"")); @@ -676,6 +726,7 @@ impl String for str { } } +#[stable] impl Show for char { fn fmt(&self, f: &mut Formatter) -> Result { use char::CharExt; @@ -697,27 +748,31 @@ impl String for char { } } +#[stable] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter) -> Result { - f.flags |= 1 << (rt::FlagAlternate as uint); + f.flags |= 1 << (FlagV1::Alternate as uint); let ret = LowerHex::fmt(&(*self as uint), f); - f.flags &= !(1 << (rt::FlagAlternate as uint)); + f.flags &= !(1 << (FlagV1::Alternate as uint)); ret } } +#[stable] impl Pointer for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(&(*self as *const T), f) } } +#[stable] impl<'a, T> Pointer for &'a T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(&(*self as *const T), f) } } +#[stable] impl<'a, T> Pointer for &'a mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(&(&**self as *const T), f) @@ -726,9 +781,10 @@ impl<'a, T> Pointer for &'a mut T { macro_rules! floating { ($ty:ident) => { + #[stable] impl Show for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { - try!(String::fmt(self, fmt)); + try!(write!(fmt, "{}", *self)); fmt.write_str(stringify!($ty)) } } @@ -755,6 +811,7 @@ macro_rules! floating { ($ty:ident) => { } } + #[stable] impl LowerExp for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; @@ -776,6 +833,7 @@ macro_rules! floating { ($ty:ident) => { } } + #[stable] impl UpperExp for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; @@ -802,9 +860,11 @@ floating! { f64 } // Implementation of Show for various core types +#[stable] impl Show for *const T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } +#[stable] impl Show for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } @@ -816,6 +876,7 @@ macro_rules! peel { macro_rules! tuple { () => (); ( $($name:ident,)+ ) => ( + #[stable] impl<$($name:Show),*> Show for ($($name,)*) { #[allow(non_snake_case, unused_assignments)] fn fmt(&self, f: &mut Formatter) -> Result { @@ -841,13 +902,15 @@ macro_rules! tuple { tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } +#[stable] impl<'a> Show for &'a (any::Any+'a) { fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") } } +#[stable] impl Show for [T] { fn fmt(&self, f: &mut Formatter) -> Result { - if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + if f.flags & (1 << (FlagV1::Alternate as uint)) == 0 { try!(write!(f, "[")); } let mut is_first = true; @@ -859,26 +922,28 @@ impl Show for [T] { } try!(write!(f, "{:?}", *x)) } - if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + if f.flags & (1 << (FlagV1::Alternate as uint)) == 0 { try!(write!(f, "]")); } Ok(()) } } +#[stable] impl Show for () { fn fmt(&self, f: &mut Formatter) -> Result { f.pad("()") } } +#[stable] impl Show for Cell { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "Cell {{ value: {:?} }}", self.get()) } } -#[unstable] +#[stable] impl Show for RefCell { fn fmt(&self, f: &mut Formatter) -> Result { match self.try_borrow() { @@ -888,12 +953,14 @@ impl Show for RefCell { } } +#[stable] impl<'b, T: Show> Show for Ref<'b, T> { fn fmt(&self, f: &mut Formatter) -> Result { Show::fmt(&**self, f) } } +#[stable] impl<'b, T: Show> Show for RefMut<'b, T> { fn fmt(&self, f: &mut Formatter) -> Result { Show::fmt(&*(self.deref()), f) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 1df6f8452258b..7f17b8cce1d7e 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -154,12 +154,14 @@ pub fn radix(x: T, base: u8) -> RadixFmt { macro_rules! radix_fmt { ($T:ty as $U:ty, $fmt:ident, $S:expr) => { + #[stable] impl fmt::Show for RadixFmt<$T, Radix> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(fmt::String::fmt(self, f)); + try!(write!(f, "{}", *self)); f.write_str($S) } } + #[stable] impl fmt::String for RadixFmt<$T, Radix> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) } @@ -169,6 +171,7 @@ macro_rules! radix_fmt { } macro_rules! int_base { ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { + #[stable] impl fmt::$Trait for $T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { $Radix.fmt_int(*self as $U, f) @@ -179,9 +182,10 @@ macro_rules! int_base { macro_rules! show { ($T:ident with $S:expr) => { + #[stable] impl fmt::Show for $T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(fmt::String::fmt(self, f)); + try!(write!(f, "{}", self)); f.write_str($S) } } diff --git a/src/libcore/fmt/rt.rs b/src/libcore/fmt/rt/v1.rs similarity index 57% rename from src/libcore/fmt/rt.rs rename to src/libcore/fmt/rt/v1.rs index 2abf921eaf2c1..346dfaf408d05 100644 --- a/src/libcore/fmt/rt.rs +++ b/src/libcore/fmt/rt/v1.rs @@ -14,22 +14,31 @@ //! These definitions are similar to their `ct` equivalents, but differ in that //! these can be statically allocated and are slightly optimized for the runtime -#![unstable = "implementation detail of the `format_args!` macro"] +#![stable] -pub use self::Alignment::*; -pub use self::Count::*; -pub use self::Position::*; -pub use self::Flag::*; +#[cfg(stage0)] pub use self::Position::*; + +#[cfg(stage0)] pub use self::Alignment::Left as AlignLeft; +#[cfg(stage0)] pub use self::Alignment::Right as AlignRight; +#[cfg(stage0)] pub use self::Alignment::Center as AlignCenter; +#[cfg(stage0)] pub use self::Alignment::Unknown as AlignUnknown; +#[cfg(stage0)] pub use self::Count::Is as CountIs; +#[cfg(stage0)] pub use self::Count::Implied as CountImplied; +#[cfg(stage0)] pub use self::Count::Param as CountIsParam; +#[cfg(stage0)] pub use self::Count::NextParam as CountIsNextParam; +#[cfg(stage0)] pub use self::Position::Next as ArgumentNext; +#[cfg(stage0)] pub use self::Position::At as ArgumentIs; // SNAP 9e4e524 -#[doc(hidden)] #[derive(Copy)] #[cfg(not(stage0))] +#[stable] pub struct Argument { + #[stable] pub position: Position, + #[stable] pub format: FormatSpec, } -#[doc(hidden)] #[derive(Copy)] #[cfg(stage0)] pub struct Argument<'a> { @@ -37,58 +46,57 @@ pub struct Argument<'a> { pub format: FormatSpec, } -#[doc(hidden)] #[derive(Copy)] +#[stable] pub struct FormatSpec { + #[stable] pub fill: char, + #[stable] pub align: Alignment, + #[stable] pub flags: uint, + #[stable] pub precision: Count, + #[stable] pub width: Count, } /// Possible alignments that can be requested as part of a formatting directive. #[derive(Copy, PartialEq)] +#[stable] pub enum Alignment { /// Indication that contents should be left-aligned. - AlignLeft, + #[stable] + Left, /// Indication that contents should be right-aligned. - AlignRight, + #[stable] + Right, /// Indication that contents should be center-aligned. - AlignCenter, + #[stable] + Center, /// No alignment was requested. - AlignUnknown, + #[stable] + Unknown, } -#[doc(hidden)] #[derive(Copy)] +#[stable] pub enum Count { - CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied, + #[stable] + Is(usize), + #[stable] + Param(usize), + #[stable] + NextParam, + #[stable] + Implied, } -#[doc(hidden)] #[derive(Copy)] +#[stable] pub enum Position { - ArgumentNext, ArgumentIs(uint) -} - -/// Flags which can be passed to formatting via a directive. -/// -/// These flags are discovered through the `flags` field of the `Formatter` -/// structure. The flag in that structure is a union of these flags into a -/// `uint` where each flag's discriminant is the corresponding bit. -#[derive(Copy)] -pub enum Flag { - /// A flag which enables number formatting to always print the sign of a - /// number. - FlagSignPlus, - /// Currently not a used flag - FlagSignMinus, - /// Indicates that the "alternate formatting" for a type should be used. - /// - /// The meaning of this flag is type-specific. - FlagAlternate, - /// Indicates that padding should be done with a `0` character as well as - /// being aware of the sign to be printed. - FlagSignAwareZeroPad, + #[stable] + Next, + #[stable] + At(usize) } diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index e7eb307689fbe..4201f61f71e4b 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -905,7 +905,7 @@ pub trait IndexMut { #[unstable = "API still in development"] pub struct FullRange; -#[unstable = "API still in development"] +#[stable] impl fmt::Show for FullRange { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt("..", fmt) @@ -964,7 +964,7 @@ impl DoubleEndedIterator for Range { #[unstable = "API still in development"] impl ExactSizeIterator for Range {} -#[unstable = "API still in development"] +#[stable] impl fmt::Show for Range { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..{:?}", self.start, self.end) @@ -993,7 +993,7 @@ impl Iterator for RangeFrom { } } -#[unstable = "API still in development"] +#[stable] impl fmt::Show for RangeFrom { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..", self.start) @@ -1009,7 +1009,7 @@ pub struct RangeTo { pub end: Idx, } -#[unstable = "API still in development"] +#[stable] impl fmt::Show for RangeTo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "..{:?}", self.end) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index f7421203336c3..082737ab4c1ab 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -233,7 +233,7 @@ use self::Result::{Ok, Err}; use clone::Clone; -use fmt::Show; +use fmt; use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; @@ -718,7 +718,7 @@ impl Result { } #[stable] -impl Result { +impl Result { /// Unwraps a result, yielding the content of an `Ok`. /// /// # Panics @@ -743,13 +743,13 @@ impl Result { match self { Ok(t) => t, Err(e) => - panic!("called `Result::unwrap()` on an `Err` value: {:?}", e) + panic!("called `Result::unwrap()` on an `Err` value: {}", e) } } } #[stable] -impl Result { +impl Result { /// Unwraps a result, yielding the content of an `Err`. /// /// # Panics @@ -773,7 +773,7 @@ impl Result { pub fn unwrap_err(self) -> E { match self { Ok(t) => - panic!("called `Result::unwrap_err()` on an `Ok` value: {:?}", t), + panic!("called `Result::unwrap_err()` on an `Ok` value: {}", t), Err(e) => e } } diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 6a7062a419e59..bc667ffe65f33 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -37,6 +37,7 @@ pub use self::EbmlEncoderTag::*; pub use self::Error::*; use std::str; +use std::fmt; pub mod io; @@ -114,6 +115,12 @@ pub enum Error { } // -------------------------------------- +impl fmt::String for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Show::fmt(self, f) + } +} + pub mod reader { use std::char; diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 1cc2b271e9ccd..fe899c907df9a 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -30,6 +30,7 @@ static MAX_REPEAT: uint = 1000; /// /// (Once an expression is compiled, it is not possible to produce an error /// via searching, splitting or replacing.) +#[derive(Show)] pub struct Error { /// The *approximate* character index of where the error occurred. pub pos: uint, @@ -37,7 +38,7 @@ pub struct Error { pub msg: String, } -impl fmt::Show for Error { +impl fmt::String for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Regex syntax error near position {}: {:?}", self.pos, self.msg) diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs index f4db2b6e61db2..ee163d2f8b4a2 100644 --- a/src/librustc/middle/cfg/graphviz.rs +++ b/src/librustc/middle/cfg/graphviz.rs @@ -52,10 +52,10 @@ fn replace_newline_with_backslash_l(s: String) -> String { } impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> { - fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[]).unwrap() } + fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[]).ok().unwrap() } fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> { - dot::Id::new(format!("N{}", i.node_id())).unwrap() + dot::Id::new(format!("N{}", i.node_id())).ok().unwrap() } fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> { diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs index 0d6ab9c273b75..62783c577ebca 100644 --- a/src/librustc/middle/infer/region_inference/graphviz.rs +++ b/src/librustc/middle/infer/region_inference/graphviz.rs @@ -157,10 +157,10 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> { impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> { fn graph_id(&self) -> dot::Id { - dot::Id::new(self.graph_name.as_slice()).unwrap() + dot::Id::new(self.graph_name.as_slice()).ok().unwrap() } fn node_id(&self, n: &Node) -> dot::Id { - dot::Id::new(format!("node_{}", self.node_ids.get(n).unwrap())).unwrap() + dot::Id::new(format!("node_{}", self.node_ids.get(n).unwrap())).ok().unwrap() } fn node_label(&self, n: &Node) -> dot::LabelText { match *n { diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index e9ef214543d6e..273cb925e4aab 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -188,7 +188,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, ty::Predicate::Equate(ref predicate) => { let predicate = infcx.resolve_type_vars_if_possible(predicate); let err = infcx.equality_predicate(obligation.cause.span, - &predicate).unwrap_err(); + &predicate).err().unwrap(); infcx.tcx.sess.span_err( obligation.cause.span, format!( @@ -200,7 +200,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, ty::Predicate::RegionOutlives(ref predicate) => { let predicate = infcx.resolve_type_vars_if_possible(predicate); let err = infcx.region_outlives_predicate(obligation.cause.span, - &predicate).unwrap_err(); + &predicate).err().unwrap(); infcx.tcx.sess.span_err( obligation.cause.span, format!( diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 7ea192b8d6bc8..ede9ae94d2850 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -59,7 +59,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, let mut cmd = Command::new(ar); cmd.arg(args).args(paths); - debug!("{}", cmd); + debug!("{:?}", cmd); match cwd { Some(p) => { @@ -73,7 +73,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, Ok(prog) => { let o = prog.wait_with_output().unwrap(); if !o.status.success() { - handler.err(&format!("{} failed with: {}", + handler.err(&format!("{:?} failed with: {}", cmd, o.status)[]); handler.note(&format!("stdout ---\n{}", diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 889a359b019cd..b1cc3a651200c 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -491,7 +491,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { if let ast::ExprAddrOf(mutbl, ref base) = ex.node { let param_env = ty::empty_parameter_environment(self.bccx.tcx); let mc = mc::MemCategorizationContext::new(¶m_env); - let base_cmt = mc.cat_expr(&**base).unwrap(); + let base_cmt = mc.cat_expr(&**base).ok().unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); // Check that we don't allow borrows of unsafe static items. if check_aliasability(self.bccx, ex.span, euv::AddrOf, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 351be70cf5261..f742b67077c3a 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -779,14 +779,14 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, } if sess.opts.debugging_opts.print_link_args { - println!("{}", &cmd); + println!("{:?}", &cmd); } // May have not found libraries in the right formats. sess.abort_if_errors(); // Invoke the system linker - debug!("{}", &cmd); + debug!("{:?}", &cmd); let prog = time(sess.time_passes(), "running linker", (), |()| cmd.output()); match prog { Ok(prog) => { @@ -794,7 +794,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, sess.err(&format!("linking with `{}` failed: {}", pname, prog.status)[]); - sess.note(&format!("{}", &cmd)[]); + sess.note(&format!("{:?}", &cmd)[]); let mut output = prog.error.clone(); output.push_all(&prog.output[]); sess.note(str::from_utf8(&output[]).unwrap()); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index c818dda7581bd..17ec6223824b7 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -716,7 +716,7 @@ pub fn run_passes(sess: &Session, cmd.args(&sess.target.target.options.post_link_args[]); if sess.opts.debugging_opts.print_link_args { - println!("{}", &cmd); + println!("{:?}", &cmd); } cmd.stdin(::std::io::process::Ignored) @@ -725,7 +725,7 @@ pub fn run_passes(sess: &Session, match cmd.status() { Ok(status) => { if !status.success() { - sess.err(&format!("linking of {} with `{}` failed", + sess.err(&format!("linking of {} with `{:?}` failed", output_path.display(), cmd)[]); sess.abort_if_errors(); } @@ -953,7 +953,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject)) .arg(outputs.temp_path(config::OutputTypeAssembly)); - debug!("{}", &cmd); + debug!("{:?}", &cmd); match cmd.output() { Ok(prog) => { @@ -961,7 +961,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { sess.err(&format!("linking with `{}` failed: {}", pname, prog.status)[]); - sess.note(&format!("{}", &cmd)[]); + sess.note(&format!("{:?}", &cmd)[]); let mut note = prog.error.clone(); note.push_all(&prog.output[]); sess.note(str::from_utf8(¬e[]).unwrap()); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e6eed4806338b..c2fa9fa6a5e1f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -110,7 +110,7 @@ pub fn main() { let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || { main_args(std::os::args().as_slice()) }).join(); - std::os::set_exit_status(res.map_err(|_| ()).unwrap()); + std::os::set_exit_status(res.ok().unwrap()); } pub fn opts() -> Vec { diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 62acef2ca1cc7..4400ad33b2b8e 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -617,13 +617,12 @@ impl<'a> ::Encoder for Encoder<'a> { if idx != 0 { try!(write!(self.writer, ",")) } // ref #12967, make sure to wrap a key in double quotes, // in the event that its of a type that omits them (eg numbers) - let mut buf = Vec::new(); + let mut out = String::new(); // FIXME(14302) remove the transmute and unsafe block. unsafe { - let mut check_encoder = Encoder::new(&mut buf); + let mut check_encoder = Encoder::new(&mut out); try!(f(transmute(&mut check_encoder))); } - let out = str::from_utf8(&buf[]).unwrap(); let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; if needs_wrapping { try!(write!(self.writer, "\"")); } try!(f(self)); @@ -888,13 +887,12 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { try!(spaces(self.writer, self.curr_indent)); // ref #12967, make sure to wrap a key in double quotes, // in the event that its of a type that omits them (eg numbers) - let mut buf = Vec::new(); + let mut out = String::new(); // FIXME(14302) remove the transmute and unsafe block. unsafe { - let mut check_encoder = PrettyEncoder::new(&mut buf); + let mut check_encoder = PrettyEncoder::new(&mut out); try!(f(transmute(&mut check_encoder))); } - let out = str::from_utf8(&buf[]).unwrap(); let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; if needs_wrapping { try!(write!(self.writer, "\"")); } try!(f(self)); @@ -2494,6 +2492,18 @@ impl FromStr for Json { } } +impl fmt::String for DecoderError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Show::fmt(self, f) + } +} + +impl fmt::String for ParserError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Show::fmt(self, f) + } +} + #[cfg(test)] mod tests { extern crate test; diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index d7f8eb2e4158b..7c0b174103cae 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -121,7 +121,7 @@ impl Deref for CString { impl fmt::Show for CString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - String::from_utf8_lossy(self.as_bytes()).fmt(f) + fmt::String::fmt(&String::from_utf8_lossy(self.as_bytes()), f) } } diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs index 907925e93d399..940760894fbd8 100644 --- a/src/libstd/fmt.rs +++ b/src/libstd/fmt.rs @@ -419,9 +419,10 @@ pub use core::fmt::{Show, String, Octal, Binary}; pub use core::fmt::{LowerHex, UpperHex, Pointer}; pub use core::fmt::{LowerExp, UpperExp}; pub use core::fmt::Error; -pub use core::fmt::{Argument, Arguments, write, radix, Radix, RadixFmt}; +pub use core::fmt::{ArgumentV1, Arguments, write, radix, Radix, RadixFmt}; #[doc(hidden)] +#[cfg(stage0)] pub use core::fmt::{argument, argumentuint}; /// The format function takes a precompiled format string and a list of @@ -439,8 +440,7 @@ pub use core::fmt::{argument, argumentuint}; /// let s = fmt::format(format_args!("Hello, {}!", "world")); /// assert_eq!(s, "Hello, world!".to_string()); /// ``` -#[unstable = "this is an implementation detail of format! and should not \ - be called directly"] +#[stable] pub fn format(args: Arguments) -> string::String { let mut output = string::String::new(); let _ = write!(&mut output, "{}", args); diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 36def48b88b32..06472942d2376 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -52,6 +52,7 @@ pub struct BufferedReader { cap: uint, } +#[stable] impl fmt::Show for BufferedReader where R: fmt::Show { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "BufferedReader {{ reader: {:?}, buffer: {}/{} }}", @@ -156,6 +157,7 @@ pub struct BufferedWriter { pos: uint } +#[stable] impl fmt::Show for BufferedWriter where W: fmt::Show { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}", @@ -250,6 +252,7 @@ pub struct LineBufferedWriter { inner: BufferedWriter, } +#[stable] impl fmt::Show for LineBufferedWriter where W: fmt::Show { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}", @@ -340,6 +343,7 @@ pub struct BufferedStream { inner: BufferedReader> } +#[stable] impl fmt::Show for BufferedStream where S: fmt::Show { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let reader = &self.inner; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 3968dda2a8202..3dfb76f51bf6e 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -340,6 +340,7 @@ impl IoError { } } +#[stable] impl fmt::String for IoError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -1827,12 +1828,14 @@ impl Default for FilePermission { fn default() -> FilePermission { FilePermission::empty() } } +#[stable] impl fmt::Show for FilePermission { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::String::fmt(self, f) } } +#[stable] impl fmt::String for FilePermission { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:04o}", self.bits) diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index d09afea94dcc1..231df781e2712 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -38,6 +38,7 @@ pub enum IpAddr { Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16) } +#[stable] impl fmt::String for IpAddr { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -69,6 +70,7 @@ pub struct SocketAddr { pub port: Port, } +#[stable] impl fmt::String for SocketAddr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.ip { diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index a093e748d5736..d3dedc16f2525 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -395,14 +395,15 @@ impl Command { } } -impl fmt::String for Command { +#[stable] +impl fmt::Show for Command { /// Format the program and arguments of a Command for display. Any /// non-utf8 data is lossily converted using the utf8 replacement /// character. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{}", String::from_utf8_lossy(self.program.as_bytes()))); + try!(write!(f, "{:?}", self.program)); for arg in self.args.iter() { - try!(write!(f, " '{}'", String::from_utf8_lossy(arg.as_bytes()))); + try!(write!(f, " '{:?}'", arg)); } Ok(()) } @@ -503,6 +504,7 @@ pub enum ProcessExit { ExitSignal(int), } +#[stable] impl fmt::Show for ProcessExit { /// Format a ProcessExit enum, to nicely present the information. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -510,7 +512,7 @@ impl fmt::Show for ProcessExit { } } - +#[stable] impl fmt::String for ProcessExit { /// Format a ProcessExit enum, to nicely present the information. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 588f729d8005d..c4fca7f47cb87 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -900,6 +900,7 @@ pub enum MapError { ErrMapViewOfFile(uint) } +#[stable] impl fmt::Show for MapError { fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result { let str = match *self { diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 1ec7b6b3edcbb..9ba951394bb72 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -823,12 +823,14 @@ pub struct Display<'a, P:'a> { filename: bool } +#[stable] impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::String::fmt(self, f) } } +#[stable] impl<'a, P: GenericPath> fmt::String for Display<'a, P> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.as_cow().fmt(f) diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 293696d5ccada..396ebba7752cf 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -57,6 +57,7 @@ pub fn is_sep(c: char) -> bool { c == SEP } +#[stable] impl fmt::Show for Path { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt(&self.display(), f) diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 2a1f1794e49e7..cf3396ea31fc6 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -85,6 +85,7 @@ pub struct Path { sepidx: Option // index of the final separator in the non-prefix portion of repr } +#[stable] impl fmt::Show for Path { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt(&self.display(), f) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index eca7d3155b18b..409d735f08871 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -381,7 +381,7 @@ pub struct SyncSender { /// A `send` operation can only fail if the receiving end of a channel is /// disconnected, implying that the data could never be received. The error /// contains the data being sent as a payload so it can be recovered. -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Clone, Copy, Show)] #[stable] pub struct SendError(pub T); @@ -389,13 +389,13 @@ pub struct SendError(pub T); /// /// The `recv` operation can only fail if the sending half of a channel is /// disconnected, implying that no further messages will ever be received. -#[derive(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, Show)] #[stable] pub struct RecvError; /// This enumeration is the list of the possible reasons that try_recv could not /// return data when called. -#[derive(PartialEq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, Show)] #[stable] pub enum TryRecvError { /// This channel is currently empty, but the sender(s) have not yet @@ -411,7 +411,7 @@ pub enum TryRecvError { /// This enumeration is the list of the possible error outcomes for the /// `SyncSender::try_send` method. -#[derive(PartialEq, Clone)] +#[derive(PartialEq, Eq, Clone, Copy, Show)] #[stable] pub enum TrySendError { /// The data could not be sent on the channel because it would require that @@ -980,13 +980,15 @@ unsafe impl Send for RacyCell { } unsafe impl Sync for RacyCell { } // Oh dear -impl fmt::Show for SendError { +#[stable] +impl fmt::String for SendError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "sending on a closed channel".fmt(f) } } -impl fmt::Show for TrySendError { +#[stable] +impl fmt::String for TrySendError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TrySendError::Full(..) => { @@ -999,13 +1001,15 @@ impl fmt::Show for TrySendError { } } -impl fmt::Show for RecvError { +#[stable] +impl fmt::String for RecvError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "receiving on a closed channel".fmt(f) } } -impl fmt::Show for TryRecvError { +#[stable] +impl fmt::String for TryRecvError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TryRecvError::Empty => { diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs index 385df45b400c4..40d5f8e525f77 100644 --- a/src/libstd/sync/poison.rs +++ b/src/libstd/sync/poison.rs @@ -54,6 +54,7 @@ pub struct Guard { /// each lock, but once a lock is poisoned then all future acquisitions will /// return this error. #[stable] +#[derive(Show)] pub struct PoisonError { guard: T, } @@ -61,6 +62,7 @@ pub struct PoisonError { /// An enumeration of possible errors which can occur while calling the /// `try_lock` method. #[stable] +#[derive(Show)] pub enum TryLockError { /// The lock could not be acquired because another task failed while holding /// the lock. @@ -90,7 +92,8 @@ pub type LockResult = Result>; #[stable] pub type TryLockResult = Result>; -impl fmt::Show for PoisonError { +#[stable] +impl fmt::String for PoisonError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "poisoned lock: another task failed inside".fmt(f) } @@ -109,7 +112,8 @@ impl FromError> for TryLockError { } } -impl fmt::Show for TryLockError { +#[stable] +impl fmt::String for TryLockError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TryLockError::Poisoned(ref p) => p.fmt(f), diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 162c3677168f8..ad324d6e89514 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -334,6 +334,7 @@ impl Div for Duration { } } +#[stable] impl fmt::String for Duration { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // technically speaking, negative duration is not valid ISO 8601, diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index f512b33f02440..ae482f8c76200 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -17,7 +17,7 @@ use ext::base::*; use ext::base; use ext::build::AstBuilder; use fmt_macros as parse; -use parse::token::{InternedString, special_idents}; +use parse::token::special_idents; use parse::token; use ptr::P; @@ -300,56 +300,35 @@ impl<'a, 'b> Context<'a, 'b> { } } - /// These attributes are applied to all statics that this syntax extension - /// will generate. - fn static_attrs(ecx: &ExtCtxt, fmtsp: Span) -> Vec { - // Flag statics as `inline` so LLVM can merge duplicate globals as much - // as possible (which we're generating a whole lot of). - let unnamed = ecx.meta_word(fmtsp, InternedString::new("inline")); - let unnamed = ecx.attribute(fmtsp, unnamed); - - // Do not warn format string as dead code - let dead_code = ecx.meta_word(fmtsp, InternedString::new("dead_code")); - let allow_dead_code = ecx.meta_list(fmtsp, - InternedString::new("allow"), - vec![dead_code]); - let allow_dead_code = ecx.attribute(fmtsp, allow_dead_code); - vec![unnamed, allow_dead_code] - } - fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec { - vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"), ecx.ident_of(s)] + vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"), + ecx.ident_of("v1"), ecx.ident_of(s)] } fn trans_count(&self, c: parse::Count) -> P { let sp = self.fmtsp; - match c { - parse::CountIs(i) => { - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIs"), - vec!(self.ecx.expr_uint(sp, i))) + let count = |: c, arg| { + let mut path = Context::rtpath(self.ecx, "Count"); + path.push(self.ecx.ident_of(c)); + match arg { + Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]), + None => self.ecx.expr_path(self.ecx.path_global(sp, path)), } + }; + match c { + parse::CountIs(i) => count("Is", Some(self.ecx.expr_uint(sp, i))), parse::CountIsParam(i) => { - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIsParam"), - vec!(self.ecx.expr_uint(sp, i))) - } - parse::CountImplied => { - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, - "CountImplied")); - self.ecx.expr_path(path) - } - parse::CountIsNextParam => { - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, - "CountIsNextParam")); - self.ecx.expr_path(path) + count("Param", Some(self.ecx.expr_uint(sp, i))) } + parse::CountImplied => count("Implied", None), + parse::CountIsNextParam => count("NextParam", None), parse::CountIsName(n) => { let i = match self.name_positions.get(n) { Some(&i) => i, None => 0, // error already emitted elsewhere }; let i = i + self.args.len(); - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIsParam"), - vec!(self.ecx.expr_uint(sp, i))) + count("Param", Some(self.ecx.expr_uint(sp, i))) } } } @@ -373,27 +352,35 @@ impl<'a, 'b> Context<'a, 'b> { } parse::NextArgument(ref arg) => { // Translate the position - let pos = match arg.position { - // These two have a direct mapping - parse::ArgumentNext => { - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, - "ArgumentNext")); - self.ecx.expr_path(path) - } - parse::ArgumentIs(i) => { - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "ArgumentIs"), - vec!(self.ecx.expr_uint(sp, i))) - } - // Named arguments are converted to positional arguments at - // the end of the list of arguments - parse::ArgumentNamed(n) => { - let i = match self.name_positions.get(n) { - Some(&i) => i, - None => 0, // error already emitted elsewhere - }; - let i = i + self.args.len(); - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "ArgumentIs"), - vec!(self.ecx.expr_uint(sp, i))) + let pos = { + let pos = |: c, arg| { + let mut path = Context::rtpath(self.ecx, "Position"); + path.push(self.ecx.ident_of(c)); + match arg { + Some(i) => { + let arg = self.ecx.expr_uint(sp, i); + self.ecx.expr_call_global(sp, path, vec![arg]) + } + None => { + self.ecx.expr_path(self.ecx.path_global(sp, path)) + } + } + }; + match arg.position { + // These two have a direct mapping + parse::ArgumentNext => pos("Next", None), + parse::ArgumentIs(i) => pos("At", Some(i)), + + // Named arguments are converted to positional arguments + // at the end of the list of arguments + parse::ArgumentNamed(n) => { + let i = match self.name_positions.get(n) { + Some(&i) => i, + None => 0, // error already emitted elsewhere + }; + let i = i + self.args.len(); + pos("At", Some(i)) + } } }; @@ -417,19 +404,16 @@ impl<'a, 'b> Context<'a, 'b> { // Translate the format let fill = self.ecx.expr_lit(sp, ast::LitChar(fill)); + let align = |:name| { + let mut p = Context::rtpath(self.ecx, "Alignment"); + p.push(self.ecx.ident_of(name)); + self.ecx.path_global(sp, p) + }; let align = match arg.format.align { - parse::AlignLeft => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignLeft")) - } - parse::AlignRight => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignRight")) - } - parse::AlignCenter => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignCenter")) - } - parse::AlignUnknown => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignUnknown")) - } + parse::AlignLeft => align("Left"), + parse::AlignRight => align("Right"), + parse::AlignCenter => align("Center"), + parse::AlignUnknown => align("Unknown"), }; let align = self.ecx.expr_path(align); let flags = self.ecx.expr_uint(sp, arg.format.flags); @@ -465,7 +449,7 @@ impl<'a, 'b> Context<'a, 'b> { let st = ast::ItemStatic(ty, ast::MutImmutable, slice); let name = ecx.ident_of(name); - let item = ecx.item(fmtsp, name, Context::static_attrs(ecx, fmtsp), st); + let item = ecx.item(fmtsp, name, vec![], st); let decl = respan(fmtsp, ast::DeclItem(item)); // Wrap the declaration in a block so that it forms a single expression. @@ -575,7 +559,7 @@ impl<'a, 'b> Context<'a, 'b> { // Now create the fmt::Arguments struct with all our locals we created. let (fn_name, fn_args) = if self.all_pieces_simple { - ("new", vec![pieces, args_slice]) + ("new_v1", vec![pieces, args_slice]) } else { // Build up the static array which will store our precompiled // nonstandard placeholders, if there are any. @@ -587,7 +571,7 @@ impl<'a, 'b> Context<'a, 'b> { piece_ty, self.pieces); - ("with_placeholders", vec![pieces, fmt, args_slice]) + ("new_v1_formatted", vec![pieces, args_slice, fmt]) }; self.ecx.expr_call_global(self.fmtsp, vec!( @@ -624,7 +608,8 @@ impl<'a, 'b> Context<'a, 'b> { return ecx.expr_call_global(sp, vec![ ecx.ident_of("std"), ecx.ident_of("fmt"), - ecx.ident_of("argumentuint")], vec![arg]) + ecx.ident_of("ArgumentV1"), + ecx.ident_of("from_uint")], vec![arg]) } }; @@ -636,7 +621,8 @@ impl<'a, 'b> Context<'a, 'b> { ecx.expr_call_global(sp, vec![ ecx.ident_of("std"), ecx.ident_of("fmt"), - ecx.ident_of("argument")], vec![ecx.expr_path(format_fn), arg]) + ecx.ident_of("ArgumentV1"), + ecx.ident_of("new")], vec![arg, ecx.expr_path(format_fn)]) } } diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index 4933938f33836..2ef0bca3785cb 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -197,7 +197,7 @@ impl TerminfoTerminal { let mut file = entry.unwrap(); let ti = parse(&mut file, false); if ti.is_err() { - debug!("error parsing terminfo entry: {:?}", ti.unwrap_err()); + debug!("error parsing terminfo entry: {:?}", ti.err().unwrap()); return None; }