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

Document that Debug output of structures is unstable #62794

Closed
rivy opened this issue Jul 19, 2019 · 21 comments
Closed

Document that Debug output of structures is unstable #62794

rivy opened this issue Jul 19, 2019 · 21 comments
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@rivy
Copy link

rivy commented Jul 19, 2019

Pretty printed structures for cfg!(windows) have trailing commas, which is inconsistent with the debug output format documentation and output on non-windows platforms.

use std::fmt;
struct Foo { bar: u32, baz: Option<u32> }
impl fmt::Debug for Foo {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Foo")
           .field("bar", &self.bar)
           .field("baz", &self.baz)
           .finish()
    }
}
fn main() {
    let cfg_windows = if cfg!(windows) { "true" } else { "false" };
    let foo = Foo { bar: 1, baz: Some(1) };
    println!("[cfg!(windows) == {}]\n{:?}\n{:#?}", cfg_windows, foo, foo);
}
C:> rustc --version
rustc 1.36.0 (a53f9df32 2019-07-03)
C:> cargo run
   Compiling t-debug_struct v0.1.0 (C:\Users\Roy\OneDrive\Projects\rust\t-debug_struct)
    Finished dev [unoptimized + debuginfo] target(s) in 0.53s
     Running `target\debug\t-debug_struct.exe`
[cfg!(windows) == true]
Foo { bar: 1, baz: Some(1) }
Foo {
    bar: 1,
    baz: Some(
        1,
    ),
}
$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/t-debug_struct`
[cfg!(windows) == false]
Foo { bar: 1, baz: Some(1) }
Foo {
    bar: 1,
    baz: Some(
        1
    )
}
@rivy rivy changed the title pretty print output of structures differs between platforms (incorrect trailing commas for cfg(windows)) pretty print output of structures differs between platforms (incorrect trailing commas for cfg!(windows)) Jul 19, 2019
rivy added a commit to rivy/rust.ansi-term that referenced this issue Jul 19, 2019
- customize expected pretty-print output for windows platforms
  - work-around for unexpected trailing commas on windows platforms (see <rust-lang/rust#62794>)
@jonas-schievink jonas-schievink added C-bug Category: This is a bug. O-windows Operating system: Windows T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jul 19, 2019
@CryZe
Copy link
Contributor

CryZe commented Jul 19, 2019

Isn't the formatting of Debug implementations (at least the derived ones) considered an implementation detail and you shouldn't be testing against those?

Also you seem to be using an outdated compiler on Linux. The formatting changed to include the commas and it does so for me on Linux as well:

[cfg!(windows) == false]
Foo { bar: 1, baz: Some(1) }
Foo {
    bar: 1,
    baz: Some(
        1,
    ),
}

rivy added a commit to rivy/rust.ansi-term that referenced this issue Jul 19, 2019
- customize expected pretty-print output for windows platforms
  - work-around for unexpected trailing commas on windows platforms (see <rust-lang/rust#62794>)
@RalfJung
Copy link
Member

@rivy could you do rustc --version on both platforms to check that you are using the same compiler version?

@rivy
Copy link
Author

rivy commented Jul 22, 2019

I was using fairly recent version of rustc for both (1.36.0 [2019-07-03] and v1.33.0 [2019-02-28], respectively). I've inserted the version output into the original issue statement.

I ran across this while trying to fix some failing windows tests for "ansi-term".

I've fixed that by converting to a regex comparison with optional trailing commas. So, that issue is essentially solved. And, I'm just fine if it's an "implementation detail" and subject to change, but that's not mentioned anywhere within the usual documentation that I could find.

Pretty-print seems to be a convenient way to compare structures visually, so, I suspect that others are using it for comparisons. A mention in the official documentation about what can be expected to remain stable and what might change would be helpful.

@RalfJung
Copy link
Member

1.36.0 [2019-07-03] and v1.33.0 [2019-02-28]

That would explain the difference then. Could you adjust the issue title? This has nothing to do with Windows vs non-Windows. The output simply changed between two versions.

@jonas-schievink jonas-schievink removed C-bug Category: This is a bug. O-windows Operating system: Windows labels Jul 22, 2019
@rivy rivy changed the title pretty print output of structures differs between platforms (incorrect trailing commas for cfg!(windows)) pretty print output of structures differs between rustc versions Jul 22, 2019
@rivy
Copy link
Author

rivy commented Jul 22, 2019

Yes, you're correct. The pretty-print is differing between versions, not platforms. It's the same, per platform, when using the same rustc version.

Since at least the ansi-term package is using the pretty-print to compare structures, I think it'd be a good idea to make a notation in the official documentation about stability and/or instability of the pretty-print output.

Also, any recommendations for structural comparison during testing?

I'd like to give @ogham a PR for a better way to test his structure (see https://github.com/ogham/rust-ansi-term/blob/master/src/debug.rs#L104-L122). I've already supplied a regex comparison which fixes the specific trailing-comma / no-trailing-comma problem (see ogham/rust-ansi-term#52), but that seems quite fragile if pretty-print has no output guarantees.

@rivy
Copy link
Author

rivy commented Jul 22, 2019

Thanks for the input @CryZe and @RalfJung!

@RalfJung RalfJung changed the title pretty print output of structures differs between rustc versions pretty print Debug output of structures differs between rustc versions Jul 23, 2019
@RalfJung RalfJung changed the title pretty print Debug output of structures differs between rustc versions Debug output of structures differs between rustc versions Jul 23, 2019
@RalfJung
Copy link
Member

I have adjusted the title to include Debug; I hope that's accurate. IMO this is mostly a docs issue about stating more clearly in the docs that Debug output is not stable. But I will leave that to the libs or docs team. ;)

I'd like to give @ogham a PR for a better way to test his structure (see https://github.com/ogham/rust-ansi-term/blob/master/src/debug.rs#L104-L122).

The expected way for people to compare structures is to use PartialEq. Why does that not work here?

@ogham
Copy link
Contributor

ogham commented Jul 23, 2019

Hi,

In this case, I'm literally testing against the auto-generated Debug output! The type in question has a short debug style if you use {:?} and a longer debug style if you use {:#?} (using debug_struct). There's a test to see if the short debug style works, but there's also a test to see if the longer debug style works that has started feeling. This is why I can't just use PartialEq.

@RalfJung
Copy link
Member

What is the point of the test?

If you want to test the debug output itself, you will just have to live with the fact that it can change arbitrarily any time. It's like testing &mut 4 as *mut _ as usize -- some tests just won't produce stable results. I also don't know why you would do that, but whatever. ;)

@rivy
Copy link
Author

rivy commented Jul 24, 2019

@ogham & @RalfJung , I think I've made the current testing a bit more robust in the face changing debug formatting between rustc versions (see ogham/rust-ansi-term#52, specifically ogham/rust-ansi-term@bc76cd1). All tests are passing on all platforms and rustc versions that I'm seeing. But it's obviously a fragile test if the debug output is unstable between versions.

I understand the motivation to check for an expected structure instantiation via testing. But using PartialEq seems like a large amount coding for such a simple (and, I would think, common) test. Maybe, I'm missing something... @RalfJung , would you have a more concrete example of how to do this, or suggest a different method to verify a correctly constructed structure?

I'm happy to flesh it out and add it to a new PR for ansi-term.

And maybe we should direct further discussion to that PR?

@RalfJung
Copy link
Member

RalfJung commented Jul 24, 2019

I am still wondering what it is that you are trying to achieve here. Please explain what the test is testing. :)

But using PartialEq seems like a large amount coding

You do not have to write the PartialEq implementation yourself, you can use #[derive(PartialEq)].

@Mark-Simulacrum
Copy link
Member

I'm going to close this issue -- auto-generated Debug implementations are explicitly not guaranteed to produce the same output over time, and the libs team has discussed this (I believe for both this specific change, and in general) and confirmed as such. Further discussion can happen on internals.rust-lang.org.

@rivy
Copy link
Author

rivy commented Aug 5, 2019

@Mark-Simulacrum , when you say "explicitly not guaranteed to produce the same output", where is that documented? When researching this, I found no such documentation. While I don't have a problem with closing this issue as "works as designed", I don't think the issue should be closed until the behavior is documented in a place that is reasonably easy for users to find/see.

@Mark-Simulacrum Mark-Simulacrum changed the title Debug output of structures differs between rustc versions Document that Debug output of structures is unstable Aug 5, 2019
@Mark-Simulacrum Mark-Simulacrum added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools and removed T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Aug 5, 2019
@Mark-Simulacrum
Copy link
Member

Reopening as such, I was also unable to find such a place. I think a note on stability in std::fmt noting that the impls for all standard library types of Debug and Display are unstable in terms of output (though not existence) should be added. We'll probably want to fcp the wording and such with libs team but that can happen on the PR.

rivy added a commit to rivy/rust.ansi-term that referenced this issue Aug 24, 2019
- customize expected pretty-print output for windows platforms
  - work-around for debug print format changes between versions (see <rust-lang/rust#62794>)
@KamilaBorowska
Copy link
Contributor

KamilaBorowska commented Aug 26, 2019

@Mark-Simulacrum

impls for all standard library types of Debug and Display are unstable in terms of output

Huh, Display implementations for non-error/Escape types are unstable? That I find myself to be really surprising, and frankly something that I don't think Rust developers can realistically change at this point as many programs depend on Display implementations to stay stable.

In particular, Display for integers, floating point numbers, characters, strings, booleans, IP addresses, socket addresses, and std::fmt::Arguments should remain stable. Programs do depend on those.

@Mark-Simulacrum
Copy link
Member

To be clear, I'm not an authority here -- I don't know that the libs team has made the assertion about Display impls before. I do think that it may make sense to say that Display impls are stable in terms of output, though perhaps such a broad claim might be excessive (an audit might be in order for where we implement Display).

@jonas-schievink jonas-schievink added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Mar 6, 2020
tesaguri added a commit to tesaguri/oauth1-request-rs that referenced this issue Mar 12, 2020
Technically, this changes behavior of the library, but it is considered
that `Debug` output is unstable in general (rust-lang/rust#62794) so you
should not be relying on it anyway.
@alilleybrinker
Copy link
Contributor

Doesn't look like anything has happened on this. I'm happy to attempt an explanation in the docs. The question is where to put it. My first thought is at the end of the last paragraph before "Examples" in the API docs for std::fmt::Debug, specifically changing:

Current

/// This trait can be used with `#[derive]` if all fields implement `Debug`. When
/// `derive`d for structs, it will use the name of the `struct`, then `{`, then a
/// comma-separated list of each field's name and `Debug` value, then `}`. For
/// `enum`s, it will use the name of the variant and, if applicable, `(`, then the
/// `Debug` values of the fields, then `)`.

Possible Change

/// This trait can be used with `#[derive]` if all fields implement `Debug`. When
/// `derive`d for structs, it will use the name of the `struct`, then `{`, then a
/// comma-separated list of each field's name and `Debug` value, then `}`. For
/// `enum`s, it will use the name of the variant and, if applicable, `(`, then the
/// `Debug` values of the fields, then `)`. __Derived `Debug` formats are not
/// stable, and so may change with future Rust versions.__

Is this notice enough? Should there be an additional notice in std::fmt? Was a conclusion ever reached on the stability of Display impls for types in std?

@RalfJung
Copy link
Member

@alilleybrinker that seems like a good start!

Orthogonally to this, though, Debug for types in std may also change, whether they are derived or not. So maybe it is worth having a subsection, like ## Stability or so, discussing the various aspects of stability around Debug.

Was a conclusion ever reached on the stability of Display impls for types in std?

Not that I know of. And as @Mark-Simulacrum said, an audit of the existing impls should probably be done before we promise anything like that.

@alilleybrinker
Copy link
Contributor

Hm. Alright, I think you're right that a new Stability section is probably best. Thanks!

RalfJung added a commit to RalfJung/rust that referenced this issue May 25, 2020
…lity, r=KodrAus

First draft documenting Debug stability.

Debug implementations of std types aren't stable, and neither are derived Debug implementations for any types, including user-defined types. This commit adds a section to the Debug documentation noting this stability status.

This issue is tracked by rust-lang#62794.
@alilleybrinker
Copy link
Contributor

With #72551 addressing the Debug docs, perhaps a new issue should be opened for the question of auditing the stability guarantees of stdlib Display impls.

@RalfJung
Copy link
Member

@alilleybrinker sure. In either case I am closing this issue now. Thanks for the PR!

sholderbach pushed a commit to nushell/nu-ansi-term that referenced this issue Mar 14, 2022
- customize expected pretty-print output for windows platforms
  - work-around for debug print format changes between versions (see <rust-lang/rust#62794>)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants