Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

std: Stabilize the std::fmt module #21713

Merged
merged 1 commit into from
Jan 31, 2015

Conversation

alexcrichton
Copy link
Member

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, 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.

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]

@rust-highfive
Copy link
Collaborator

r? @aturon

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member Author

This is a continuation of #21457

cc @eddyb, @cmr, I remember you guys saying that you were thinking of some form of hygiene with macro expansion that would not require stabilizing the runtime, but I'm not sure what came of this.

cc @seanmonstar, this has implications on how rust-lang/rfcs#583 can be implemented in a pre-1.0 world, but I believe it is still possible to do backwards compatibly

@seanmonstar
Copy link
Contributor

I know 583 hasn't been accepted yet, but I have an almost-complete
implementation in a branch.

On Tue, Jan 27, 2015, 7:23 PM Alex Crichton notifications@github.com
wrote:

This is a continuation of #21457
#21457

cc @eddyb https://github.com/eddyb, @cmr https://github.com/cmr, I
remember you guys saying that you were thinking of some form of hygiene
with macro expansion that would not require stabilizing the runtime, but
I'm not sure what came of this.

cc @seanmonstar https://github.com/seanmonstar, this has implications
on how rust-lang/rfcs#583 rust-lang/rfcs#583
can be implemented in a pre-1.0 world, but I believe it is still possible
to do backwards compatibly


Reply to this email directly or view it on GitHub
#21713 (comment).

@alexcrichton
Copy link
Member Author

Cool! I think we'll want to stabilize the APIs in this PR regardless because otherwise you'll get dozens of warnings for using format_args!-related macros (e.g. println, format, log, etc). I'd be totally fine, however, modifying these "stable" APIs before 1.0 as I highly doubt that anyone is actually calling them in practice!

@seanmonstar
Copy link
Contributor

It seems like the size hint stuff fits in a way that it can be unstable for
a bit. The only thing it touched in this PR is Argument::new...

On Tue, Jan 27, 2015, 7:36 PM Alex Crichton notifications@github.com
wrote:

Cool! I think we'll want to stabilize the APIs in this PR regardless
because otherwise you'll get dozens of warnings for using format_args!-related
macros (e.g. println, format, log, etc). I'd be totally fine, however,
modifying these "stable" APIs before 1.0 as I highly doubt that anyone
is actually calling them in practice!


Reply to this email directly or view it on GitHub
#21713 (comment).

@eddyb
Copy link
Member

eddyb commented Jan 28, 2015

@cmr claimed it was already implemented, but I never ended up investigating it, sorry. Will try to experiment today to get a feel for the current rules. Hopefully I'll have some results before this PR is merged.

@alexcrichton
Copy link
Member Author

@seanmonstar unfortunately Argument::new is called in the expansion of format_args!, necessitating its stability for now. I think we'd be fine modifying it, however, before 1.0 is release and avoid creating ArgumentV2 so quickly :)

@eddyb ok thanks! It would sure be nice if we didn't have to stabilize all these details!

@alexcrichton
Copy link
Member Author

@eddyb I should also add that destabilizing these internals is totally OK with me, I really highly doubt that anyone is using them today or anyone will use them before 1.0.

@alexcrichton alexcrichton force-pushed the second-pass-fmt branch 5 times, most recently from 1c34519 to 2869863 Compare January 30, 2015 16:57
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 rust-lang#20661
[breaking-change]
@alexcrichton
Copy link
Member Author

@bors: r=aturon 6227357

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Jan 30, 2015
@aturon aturon mentioned this pull request Jan 30, 2015
38 tasks
@alexcrichton alexcrichton merged commit 6227357 into rust-lang:master Jan 31, 2015
@alexcrichton alexcrichton deleted the second-pass-fmt branch January 31, 2015 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix detection of feature gate use inside of println!
5 participants