Skip to content

Middle/pretty: Butchered output for opaque types with associated type bounds #127329

Open
@kmicklas

Description

@kmicklas

Code

trait Trait {
    type Associated;
}

impl Trait for () {
    type Associated = ();
}

fn capture<T: Trait>(_: T, _: &T::Associated) {}

fn with<A, F>(_: F)
where
    F: FnOnce(&A),
{
}

// fn borrow(_: &()) -> impl '_ + Trait<Associated = impl Sized> {}
fn borrow(_: &()) -> impl '_ + Trait<Associated: 'static> {}

fn fail() -> impl Trait {
    with(move |a| {
        let data = ();
        capture(borrow(&data), a)
    })
}

fn main() {
    fail();
}

Current output

error[E0597]: `data` does not live long enough
  --> src/main.rs:23:24
   |
21 |     with(move |a| {
   |                - has type `&<impl Trait + '1 + 'static as Trait>::Associated`
22 |         let data = ();
   |             ---- binding `data` declared here
23 |         capture(borrow(&data), a)
   |                 -------^^^^^-
   |                 |      |
   |                 |      borrowed value does not live long enough
   |                 argument requires that `data` is borrowed for `'1`
24 |     })
   |     - `data` dropped here while still borrowed

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

Desired output

error[E0597]: `data` does not live long enough
  --> src/main.rs:23:24
   |
21 |     with(move |a| {
   |                - has type `&<impl Trait + '1 as Trait>::Associated`
22 |         let data = ();
   |             ---- binding `data` declared here
23 |         capture(borrow(&data), a)
   |                 -------^^^^^-
   |                 |      |
   |                 |      borrowed value does not live long enough
   |                 argument requires that `data` is borrowed for `'1`
24 |     })
   |     - `data` dropped here while still borrowed

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

Rationale and extra context

This is closely related to #106684 and in particular my observation in #106684 (comment). As in there, uncommenting the commented line to replace the return type of borrow with impl '_ + Trait<Associated = impl Sized> caused the code to compile, as expected. This is a further reduced example, and in this case I'm not even sure that there should be any error at all since with and capture both return ().

However, the most salient problem to me as a user here, is not that the code doesn't compile, but that the error doesn't seem to make sense, specifically the inferred type on the a parameter to the closure, which is &<impl Trait + '1 + 'static as Trait>::Associated. The Associated: 'static bound has somehow floated upward to become impl Trait + 'static, which was never specified.

I thought this might be worth reporting as a separate diagnostic bug, but if this is just a consequence of an underlying issue in the type checking, maybe covered under #106684, then feel free to close it.

Other cases

No response

Rust Version

rustc 1.81.0-nightly (aa1d4f682 2024-07-03)
binary: rustc
commit-hash: aa1d4f6826de006b02fed31a718ce4f674203721
commit-date: 2024-07-03
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-prettyArea: Pretty printing (including `-Z unpretty`)C-bugCategory: This is a bug.S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-compilerRelevant to the compiler 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