about summary refs log tree commit diff
path: root/src/libcore/fmt
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-13 15:42:53 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-30 09:21:56 -0800
commit62273575139a80c2b208a3a27e0c2392b1425be6 (patch)
treef9381a041e8ad95efe57ee6f85954a8b063b853f /src/libcore/fmt
parent52c74e63dacd49017b19330e0cbecbac0a3fe62e (diff)
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`)

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.

Closes #20661
[breaking-change]
Diffstat (limited to 'src/libcore/fmt')
-rw-r--r--src/libcore/fmt/mod.rs252
-rw-r--r--src/libcore/fmt/rt.rs86
-rw-r--r--src/libcore/fmt/rt/v1.rs94
3 files changed, 239 insertions, 193 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 8b7a4c677ac..2ff67ebd550 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(feature = "rust1", since = "1.0.0")]
 
 use any;
@@ -27,6 +26,7 @@ use result;
 use slice::SliceExt;
 use slice;
 use str::{self, StrExt};
+use self::rt::v1::Alignment;
 
 pub use self::num::radix;
 pub use self::num::Radix;
@@ -34,10 +34,15 @@ pub use self::num::RadixFmt;
 
 mod num;
 mod float;
-pub mod rt;
 
-#[unstable(feature = "core",
-           reason = "core and I/O reconciliation may alter this definition")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(hidden)]
+pub mod rt {
+    #[cfg(stage0)] pub use self::v1::*;
+    pub mod v1;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 /// The type returned by formatter methods.
 pub type Result = result::Result<(), Error>;
 
@@ -46,8 +51,7 @@ 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(feature = "core",
-           reason = "core and I/O reconciliation may alter this definition")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Debug)]
 pub struct Error;
 
@@ -60,8 +64,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(feature = "core",
-           reason = "waiting for core and I/O reconciliation")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Writer {
     /// Writes a slice of bytes into this writer, returning whether the write
     /// succeeded.
@@ -73,12 +76,14 @@ pub trait Writer {
     /// # Errors
     ///
     /// This function will return an instance of `FormatError` on error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     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(feature = "rust1", since = "1.0.0")]
     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
@@ -104,18 +109,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(feature = "core",
-           reason = "name may change and implemented traits are also unstable")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Formatter<'a> {
     flags: uint,
     fill: char,
-    align: rt::Alignment,
+    align: rt::v1::Alignment,
     width: Option<uint>,
     precision: Option<uint>,
 
     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,
@@ -127,35 +131,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(feature = "core",
-           reason = "implementation detail of the `format_args!` macro")]
 #[derive(Copy)]
-pub struct Argument<'a> {
+#[stable(feature = "rust1", since = "1.0.0")]
+#[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 {
         Display::fmt(x, f)
     }
 
-    fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'b> {
+    #[doc(hidden)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    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(feature = "rust1", since = "1.0.0")]
+    pub fn from_uint(x: &uint) -> ArgumentV1 {
+        ArgumentV1::new(x, ArgumentV1::show_uint)
     }
 
     fn as_uint(&self) -> Option<uint> {
-        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
@@ -163,14 +172,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(feature = "core",
-               reason = "implementation detail of the `format_args!` macro")]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    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(feature = "rust1", since = "1.0.0")]
     pub fn new(pieces: &'a [&'a str],
-               args: &'a [Argument<'a>]) -> Arguments<'a> {
+               args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
         Arguments {
             pieces: pieces,
             fmt: None,
@@ -185,11 +212,28 @@ impl<'a> Arguments<'a> {
     /// created with `argumentuint`. However, failing to do so doesn't cause
     /// unsafety, but will ignore invalid .
     #[doc(hidden)] #[inline]
-    #[unstable(feature = "core",
-               reason = "implementation detail of the `format_args!` macro")]
+    #[cfg(stage0)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_placeholders(pieces: &'a [&'a str],
-                             fmt: &'a [rt::Argument],
-                             args: &'a [Argument<'a>]) -> Arguments<'a> {
+                             fmt: &'a [rt::v1::Argument],
+                             args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
+        Arguments {
+            pieces: pieces,
+            fmt: Some(fmt),
+            args: args
+        }
+    }
+    /// This function is used to specify nonstandard formatting parameters.
+    /// The `pieces` array must be at least as long as `fmt` to construct
+    /// a valid Arguments structure. Also, any `Count` within `fmt` that is
+    /// `CountIsParam` or `CountIsNextParam` has to point to an argument
+    /// created with `argumentuint`. However, failing to do so doesn't cause
+    /// unsafety, but will ignore invalid .
+    #[doc(hidden)] #[inline]
+    #[cfg(not(stage0))]
+    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),
@@ -214,11 +258,11 @@ pub struct Arguments<'a> {
     pieces: &'a [&'a str],
 
     // Placeholder specs, or `None` if all specs are default (as in "{}{}").
-    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(feature = "rust1", since = "1.0.0")]
@@ -237,20 +281,20 @@ impl<'a> Display for Arguments<'a> {
 
 /// Format trait for the `:?` format. Useful for debugging, all types
 /// should implement this.
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
 #[deprecated(since = "1.0.0", reason = "renamed to Debug")]
+#[unstable(feature = "old_fmt")]
 pub trait Show {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `:?` format. Useful for debugging, all types
 /// should implement this.
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \
-                            crate, add `#[derive(Debug)]` or manually implement it"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \
+                            defined in your crate, add `#[derive(Debug)]` or \
+                            manually implement it"]
 #[lang = "debug_trait"]
 pub trait Debug {
     /// Formats the value using the given formatter.
@@ -264,19 +308,20 @@ impl<T: Show + ?Sized> Debug for T {
 
 /// When a value can be semantically expressed as a String, this trait may be
 /// used. It corresponds to the default format, `{}`.
-#[unstable(feature = "core")]
 #[deprecated(since = "1.0.0", reason = "renamed to Display")]
+#[unstable(feature = "old_fmt")]
 pub trait String {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     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(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default formatter; try using \
-                            `:?` instead if you are using a format string"]
+#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \
+                            formatter; try using `:?` instead if you are using \
+                            a format string"]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Display {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
@@ -288,58 +333,58 @@ impl<T: String + ?Sized> Display for T {
 }
 
 /// Format trait for the `o` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Octal {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `b` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Binary {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `x` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait LowerHex {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `X` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait UpperHex {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `p` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Pointer {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `e` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait LowerExp {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `E` character
-#[unstable(feature = "core",
-           reason = "I/O and core have yet to be reconciled")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait UpperExp {
     /// Formats the value using the given formatter.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
@@ -351,16 +396,14 @@ pub trait UpperExp {
 ///
 ///   * output - the buffer to write output to
 ///   * args - the precompiled arguments generated by `format_args!`
-#[unstable(feature = "core",
-           reason = "libcore and I/O have yet to be reconciled, and this is an \
-                     implementation detail which should not otherwise be exported")]
+#[stable(feature = "rust1", since = "1.0.0")]
 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(),
@@ -402,7 +445,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;
@@ -412,22 +455,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<uint> {
+    fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<uint> {
         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())
             }
         }
@@ -437,8 +480,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
     ///
@@ -449,27 +492,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(feature = "core",
-               reason = "definition may change slightly over time")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     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();
         }
 
@@ -499,16 +540,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)
                 })
             }
@@ -526,8 +567,7 @@ impl<'a> Formatter<'a> {
     ///               is longer than this length
     ///
     /// Notably this function ignored the `flag` parameters
-    #[unstable(feature = "core",
-               reason = "definition may change slightly over time")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     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() {
@@ -561,7 +601,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)
                 })
             }
@@ -570,19 +610,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<F>(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where
-        F: FnOnce(&mut Formatter) -> Result,
+    fn with_padding<F>(&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 => (0, padding),
-            rt::AlignRight | rt::AlignUnknown => (padding, 0),
-            rt::AlignCenter => (padding / 2, (padding + 1) / 2),
+            Alignment::Left => (0, padding),
+            Alignment::Right | Alignment::Unknown => (padding, 0),
+            Alignment::Center => (padding / 2, (padding + 1) / 2),
         };
 
         let mut fill = [0u8; 4];
@@ -604,23 +645,20 @@ impl<'a> Formatter<'a> {
 
     /// Writes some data to the underlying buffer contained within this
     /// formatter.
-    #[unstable(feature = "core",
-               reason = "reconciling core and I/O may alter this definition")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn write_str(&mut self, data: &str) -> Result {
         self.buf.write_str(data)
     }
 
     /// Writes some formatted information into this instance
-    #[unstable(feature = "core",
-               reason = "reconciling core and I/O may alter this definition")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn write_fmt(&mut self, fmt: Arguments) -> Result {
         write(self.buf, fmt)
     }
 
     /// Flags for formatting (packed version of rt::Flag)
-    #[unstable(feature = "core",
-               reason = "return type may change and method was just created")]
-    pub fn flags(&self) -> uint { self.flags }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn flags(&self) -> usize { self.flags }
 
     /// Character used as 'fill' whenever there is alignment
     #[unstable(feature = "core", reason = "method was just created")]
@@ -628,7 +666,7 @@ impl<'a> Formatter<'a> {
 
     /// Flag indicating what form of alignment was requested
     #[unstable(feature = "core", reason = "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(feature = "core", reason = "method was just created")]
@@ -649,20 +687,20 @@ impl Display for Error {
 /// This is a function which calls are emitted to by the compiler itself to
 /// create the Argument structures that are passed into the `format` function.
 #[doc(hidden)] #[inline]
-#[unstable(feature = "core",
-           reason = "implementation detail of the `format_args!` macro")]
+#[cfg(stage0)]
+#[stable(feature = "rust1", since = "1.0.0")]
 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(feature = "core",
-           reason = "implementation detail of the `format_args!` macro")]
-pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
-    Argument::from_uint(s)
+#[cfg(stage0)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn argumentuint<'a>(s: &'a uint) -> ArgumentV1<'a> {
+    ArgumentV1::from_uint(s)
 }
 
 // Implementations of the core formatting traits
@@ -741,9 +779,9 @@ impl Display for char {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> 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
     }
 }
@@ -899,7 +937,7 @@ impl<'a> Debug for &'a (any::Any+'a) {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Debug> Debug 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;
@@ -911,7 +949,7 @@ impl<T: Debug> Debug 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(())
diff --git a/src/libcore/fmt/rt.rs b/src/libcore/fmt/rt.rs
deleted file mode 100644
index 0b2c1efbc5d..00000000000
--- a/src/libcore/fmt/rt.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2013 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.
-
-//! This is an internal module used by the ifmt! runtime. These structures are
-//! emitted to static arrays to precompile format strings ahead of time.
-//!
-//! 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(feature = "core",
-            reason = "implementation detail of the `format_args!` macro")]
-
-pub use self::Alignment::*;
-pub use self::Count::*;
-pub use self::Position::*;
-pub use self::Flag::*;
-
-#[doc(hidden)]
-#[derive(Copy)]
-pub struct Argument {
-    pub position: Position,
-    pub format: FormatSpec,
-}
-
-#[doc(hidden)]
-#[derive(Copy)]
-pub struct FormatSpec {
-    pub fill: char,
-    pub align: Alignment,
-    pub flags: uint,
-    pub precision: Count,
-    pub width: Count,
-}
-
-/// Possible alignments that can be requested as part of a formatting directive.
-#[derive(Copy, PartialEq)]
-pub enum Alignment {
-    /// Indication that contents should be left-aligned.
-    AlignLeft,
-    /// Indication that contents should be right-aligned.
-    AlignRight,
-    /// Indication that contents should be center-aligned.
-    AlignCenter,
-    /// No alignment was requested.
-    AlignUnknown,
-}
-
-#[doc(hidden)]
-#[derive(Copy)]
-pub enum Count {
-    CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
-}
-
-#[doc(hidden)]
-#[derive(Copy)]
-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,
-}
diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs
new file mode 100644
index 00000000000..f0c82759b70
--- /dev/null
+++ b/src/libcore/fmt/rt/v1.rs
@@ -0,0 +1,94 @@
+// Copyright 2013 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.
+
+//! This is an internal module used by the ifmt! runtime. These structures are
+//! emitted to static arrays to precompile format strings ahead of time.
+//!
+//! These definitions are similar to their `ct` equivalents, but differ in that
+//! these can be statically allocated and are slightly optimized for the runtime
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[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;
+
+#[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Argument {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub position: Position,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub format: FormatSpec,
+}
+
+#[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct FormatSpec {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fill: char,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub align: Alignment,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub flags: uint,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub precision: Count,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub width: Count,
+}
+
+/// Possible alignments that can be requested as part of a formatting directive.
+#[derive(Copy, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Alignment {
+    /// Indication that contents should be left-aligned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Left,
+    /// Indication that contents should be right-aligned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Right,
+    /// Indication that contents should be center-aligned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Center,
+    /// No alignment was requested.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Unknown,
+}
+
+#[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Count {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Is(usize),
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Param(usize),
+    #[stable(feature = "rust1", since = "1.0.0")]
+    NextParam,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Implied,
+}
+
+#[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Position {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Next,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    At(usize)
+}