`Send` bound not inferred on RPIT due to nonsensical unsatisfied higher ranked bound
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Extracted from #159575
trait SomeTrait {} // doesnt matter which trait we use for this
trait Trait {
type Assoc;
}
// error goes away when implementing for `dyn SomeTrait + '_`
impl Trait for dyn SomeTrait {
type Assoc = ();
}
// The future returned here is obviously `Send`.
// Adding an explicit `+ Send` bound demonstrates this and makes the error go away.
fn future<T: Trait + ?Sized>() -> impl Future<Output = T::Assoc> {
async { todo!() }
}
fn use_send(_: impl Send) {} // to assert the `Send` bound
fn main() {
use_send(async { future::<dyn SomeTrait>().await }); // error
}
Compiler output
error: implementation of `Trait` is not general enough
--> src/main.rs:21:5
|
21 | use_send(async { future::<dyn SomeTrait>().await }); // error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: `(dyn SomeTrait + '0)` must implement `Trait`, for any lifetime `'0`...
= note: ...but `Trait` is actually implemented for the type `(dyn SomeTrait + 'static)`
With -Znext-solver:
error: higher-ranked subtype error
--> src/main.rs:21:5
|
21 | use_send(async { future::<dyn SomeTrait>().await }); // error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There should not be any higher ranked logic involved here, since dyn SomeTrait in both cases is just the fixed type dyn SomeTrait + 'static (error still happens if written as such). Replacing both occurrences with a type like () makes the error go away. The error also happens if dyn SomeTrait is wrapped in Box or similar.
Adding an explicit + Send bound to the RPIT makes the error go away but can "cause" (unknown if this is the cause) an ICE on the old solver later on (see #159575).
Removing the seemingly redundant async { (...).await } also causes the error to go away.
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 by compiling the reduced example in src/main.rs and compare the default solver with -Znext-solver, focusing on the RPIT, dyn SomeTrait, and async-await interactions described here. Done means the example no longer reports an erroneous higher-ranked bound for dyn SomeTrait without requiring an explicit + Send; also check the related behavior noted in #159575.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100