`higher-ranked lifetime error` with a simple example involving a BTreeMap
cpgddln opened this issue · comments
cpgddln commented
The following (playground)
#[async_trait::async_trait]
trait T {
async fn f(&self);
}
#[async_trait::async_trait]
// Compiles when the BTreeMap is replaced by a HashMap
impl T for BTreeMap<u32, Box<dyn Send + Sync + 'static>> {
async fn f(&self) {
for a in self {
test().await;
}
}
}
async fn test() {}
results in
error: higher-ranked lifetime error
--> src/lib.rs:11:23
|
11 | async fn f(&self) {
| _______________________^
12 | | for a in self {
13 | | test().await;
14 | | }
15 | | }
| |_____^
|
= note: could not prove `for<'r, 's, 't0, 't1, 't2> Pin<Box<impl for<'r, 's, 't0, 't1> Future<Output = ()>>>: CoerceUnsized<Pin<Box<(dyn Future<Output = ()> + Send + 't2)>>>`
however, it works fine when the BTreeMap is replaced by a HashMap.
Might that be an issue with async_trait
, or something I misunderstood?
David Tolnay commented
Seems like a standard library bug.
Minimized:
//use std::collections::HashMap as Map;
use std::collections::BTreeMap as Map;
fn assert_send<T: Send>(_: T) {}
fn main() {
assert_send(async {
let map = Map::<u32, Box<dyn Send + Sync>>::new();
let _iter = map.iter();
async {}.await;
});
}
David Tolnay commented
Apparently this is rust-lang/rust#64552.
cpgddln commented
Thanks a lot for identifying the root cause in the standard library and even fixing it there, that's awesome!