Recursive RPIT incorrectly errors: "concrete type differs from previous defining opaque type use"
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
The following code fails to compile, both in the old solver and next-solver. I think it should compile.
#[expect(unconditional_recursion)]
pub fn foo<'a: 'a>() -> impl Sized + use<'a> {
let x: Cov<'static> = foo::<'a>();
x
}
struct Cov<'a>(&'a ());
error: concrete type differs from previous defining opaque type use
--> src/lib.rs:4:5
|
4 | x
| ^ expected `Cov<'static>`, got `Cov<'a>`
|
note: previous use here
--> src/lib.rs:3:27
|
3 | let x: Cov<'static> = foo::<'a>();
| ^^^^^^^^^^^
This code compiles in both solvers if Covis changed to be invariant. But it still doesn't compile if it's contravariant.
This code also compiles if use<'a> is changed to use<>
Meta
Reproducible on the playground with version 1.96.0-nightly (2026-03-08 b41f22de2a13a0babd28)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Rust reproduction in src/lib.rs and compile it with both the old solver and next-solver. Compare the behavior when Cov is invariant or contravariant and when use<'a> becomes use<>; done means the original covariant recursive RPIT example compiles without the concrete-type error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100