Skip to content

Duplicate error messages when RPIT comes from function whose generics don't satisfy bounds #128756

Open

Description

@Baptistemontan

Code

I tried this code:

use std::fmt::Display;

fn foo<T: Display>(x: T) -> impl Display {
    x
}

struct Bar; // does'nt impl `Display`

fn main() {
    let x = foo(Bar);
    println!("{}", x);
}

I expected to see this happen:

The error to be reported on the call to foo() only:

error[E0277]: `Bar` doesn't implement `std::fmt::Display`
  --> src\lib.rs:10:17
   |
10 |     let x = foo(Bar);
   |             --- ^^^ `Bar` cannot be formatted with the default formatter
   |             |
   |             required by a bound introduced by this call
   |
   = help: the trait `std::fmt::Display` is not implemented for `Bar`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `foo`
  --> src\lib.rs:3:11
   |
3  | fn foo<T: Display>(x: T) -> impl Display {
   |           ^^^^^^^ required by this bound in `foo`

For more information about this error, try `rustc --explain E0277`.

Instead, this happened:

The error is propagated to the use of the println! macro call, without supposing x to implement Display:

error[E0277]: `Bar` doesn't implement `std::fmt::Display`
  --> src\lib.rs:10:17
   |
10 |     let x = foo(Bar);
   |             --- ^^^ `Bar` cannot be formatted with the default formatter
   |             |
   |             required by a bound introduced by this call
   |
   = help: the trait `std::fmt::Display` is not implemented for `Bar`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `foo`
  --> src\lib.rs:3:11
   |
3  | fn foo<T: Display>(x: T) -> impl Display {
   |           ^^^^^^^ required by this bound in `foo`

error[E0277]: `Bar` doesn't implement `std::fmt::Display`
  --> src\lib.rs:10:13
   |
10 |     let x = foo(Bar);
   |             ^^^^^^^^ `Bar` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `Bar`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `foo`
  --> src\lib.rs:3:11
   |
3  | fn foo<T: Display>(x: T) -> impl Display {
   |           ^^^^^^^ required by this bound in `foo`

error[E0277]: `Bar` doesn't implement `std::fmt::Display`
  --> src\lib.rs:11:15
   |
11 |     println!("{}", x);
   |               ^^ `Bar` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `Bar`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

Version it worked on

It most recently worked on: Rust 1.77

Version with regression

rustc --version --verbose:

rustc 1.80.0 (051478957 2024-07-21)
binary: rustc
commit-hash: 051478957371ee0084a7c0913941d2a8c4757bb9
commit-date: 2024-07-21
host: x86_64-pc-windows-msvc
release: 1.80.0
LLVM version: 18.1.7

Backtrace

Backtrace

<backtrace>

Activity

  1. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.
    and removed
    regression-untriagedUntriaged performance or correctness regression.
    on Aug 6, 2024
  2. Baptistemontan commented on Aug 6, 2024

    @Baptistemontan
    Author

    This problem is quite annoying with macros, as it propagate the error through the whole macro generated code and stop pin-pointing the source of the problem.

  3. Baptistemontan commented on Aug 6, 2024

    @Baptistemontan
    Author

    The behavior change came with 1.78, I tried 1.78, 1.79, 1.80, 1.81-nightly and 1.82-nightly.

  4. compiler-errors commented on Aug 6, 2024

    @compiler-errors
    Contributor

    This isn't leaking RPITs. This code has the same error:

    use std::fmt::Display;
    
    fn foo<T: Display>(_x: T) -> impl Display {
        ""
    }
    
    struct Bar; // doesn't impl `Display`
    
    fn main() {
        let x = foo(Bar);
        println!("{}", x);
    }
    

    This just has to do with bad error spans and a lack of error deduplications. The root cause of all 3 of these errors is still the T: Display bound.

  5. Baptistemontan commented on Aug 6, 2024

    @Baptistemontan
    Author

    @compiler-errors True, this was a supposition on my part, and I did'nt really know how to name the issue, any suggestion how to rename it ?

  6. changed the title [-]RPIT leak concrete type[/-] [+]Duplicate error messages when RPIT comes from function whose generics don't satisfy bounds[/+] on Aug 6, 2024
  7. compiler-errors commented on Aug 6, 2024

    @compiler-errors
    Contributor

    This is purely a diagnostics regression so this doesn't need triaging.

    I caused this in #122341. I may spend some time looking into how to deduplicate these error messages.

  8. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    D-confusingDiagnostics: Confusing error or lint that should be reworked.
    D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    and removed
    regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.D-confusingDiagnostics: Confusing error or lint that should be reworked.D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions