Skip to content

Strange type inference for recursive RPIT #139406

Open
@theemathas

Description

@theemathas

I tried this code:

#![allow(unconditional_recursion)]

fn what1<T>(x: T) -> impl Sized {
    what1(x)
}

fn what2<T>(x: T) -> impl Sized {
    what2(what2(x))
}

fn print_return_type<T, U>(_: impl Fn(T) -> U) {
    println!("{}", std::any::type_name::<U>())
}

fn main() {
    print_return_type(what1::<i32>);
    print_return_type(what2::<i32>);
}

I compiled the above code in edition 2024, and got the output:

()
i32

Also, the following code gives a compile error:

#![allow(unconditional_recursion)]

fn what3<T>(x: T) -> impl Sized {
    what3(what3(what3(x)))
}
error[E0792]: expected generic type parameter, found `impl Sized`
 --> src/lib.rs:4:5
  |
3 | fn what3<T>(x: T) -> impl Sized {
  |          - this generic parameter must be used with a generic type parameter
4 |     what3(what3(what3(x)))
  |     ^^^^^^^^^^^^^^^^^^^^^^

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

(See also #139350)

I think that both what1 and what2 should not compile, but I'm not sure. And if it does compiles, they should both return !. However, they return () and i32, respectively. (This happens despite the edition 2024 never type fallback change.) The current behavior doesn't make any sense to me.

Discovered while experimenting with #139402.

@rustbot labels +A-impl-trait

Meta

Reproducible on the playground with nightly rust 1.88.0-nightly (2025-04-04 17ffbc81a30c09419383)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.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