Skip to content

Recursive RPIT causes E0792 (an error about TAIT): "this generic parameter must be used with a generic type parameter" #139350

Open
@theemathas

Description

@theemathas

Code

I tried this code:

fn conjure<T>() -> T { panic!() }

fn what<T, F: FnOnce() -> T>(_: F) -> impl Sized {
    if false {
        let _: T = what::<T, _>(move || conjure::<T>());
    }
    conjure::<T>()
}

I expect the code to compile (although maybe the function might be impossible to call). Instead, on the latest nightly rust (1.88.0-nightly (2025-04-02 d5b4c2e4f19b6d703737)), I got this error:

error[E0792]: expected generic type parameter, found `{closure@src/lib.rs:5:33: 5:40}`
 --> src/lib.rs:5:16
  |
3 | fn what<T, F: FnOnce() -> T>(_: F) -> impl Sized {
  |            - this generic parameter must be used with a generic type parameter
4 |     if false {
5 |         let _: T = what::<T, _>(move || conjure::<T>());
  |                ^

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

Version it worked on

The code compiles fine on rust 1.72.0 on godbolt.

Version with regression

The code gives the above error on rust 1.73.0 on godbolt.

Additional context

I was playing around trying to break rust, and I ran into this.

Removing the : T type annotation causes the code to compile fine.

The E0792 error emitted by the compiler is an error about TAIT, which is weird, given that the code uses RPIT, not TAIT.

Another variant of the code is:

#[allow(unconditional_recursion)]
fn what<T, F: FnOnce() -> T>(f: F) -> impl Sized {
    what(move || what::<T, _>(move || f()))
}

This variant gives:

  • the confusing E0792 error since version 1.73.0
  • a "concrete type differs from previous defining opaque type use" error in versions 1.65.0 to 1.72.0
  • a "broken MIR" internal compiler error in versions 1.61 to 1.64.0
  • the arguably correct "cannot resolve opaque type" error in version 1.60.0. (I haven't checked earlier versions than this).

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged +A-impl-trait

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions