mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-28 11:38:01 +00:00
Fix overconstrained Send impls in btree internals Fixes https://github.com/dtolnay/async-trait/issues/215. Minimal repro: ```rust use std::collections::btree_map::Iter; fn require_send<T: Send>(_: T) {} fn main() { require_send(async { let _iter = None::<Iter<(), &()>>; async {}.await; }); } ``` ```console error: higher-ranked lifetime error --> src/main.rs:6:5 | 6 | / require_send(async { 7 | | let _iter = None::<Iter<(), &()>>; 8 | | async {}.await; 9 | | }); | |______^ | = note: could not prove `impl Future<Output = ()>: Send` ``` Not-quite-so-minimal repro: ```rust use std::collections::BTreeMap; use std::future::Future; fn spawn<T: Future + Send>(_: T) {} async fn f() { let map = BTreeMap::<u32, Box<dyn Send + Sync>>::new(); for _ in &map { async {}.await; } } fn main() { spawn(f()); } ``` ```console error: higher-ranked lifetime error --> src/main.rs:14:5 | 14 | spawn(f()); | ^^^^^^^^^^ | = note: could not prove `impl Future<Output = ()>: Send` ``` I am not familiar with the btree internals, but it seems clear to me that the `async fn f` above should return a Send future. Using HashMap instead of BTreeMap in that code makes it already return a Send future. The _"higher-ranked lifetime error"_ message may be a regression in Rust 1.63. Using older compilers the error message was more detailed: ```console error: implementation of `Send` is not general enough --> src/main.rs:14:5 | 14 | spawn(f()); | ^^^^^ implementation of `Send` is not general enough | = note: `Send` would have to be implemented for the type `alloc::collections::btree::node::NodeRef<alloc::collections::btree::node::marker::Immut<'0>, u32, Box<(dyn Send + Sync + '1)>, alloc::collections::btree::node::marker::LeafOrInternal>`, for any two lifetimes `'0` and `'1`... = note: ...but `Send` is actually implemented for the type `alloc::collections::btree::node::NodeRef<alloc::collections::btree::node::marker::Immut<'2>, u32, Box<dyn Send + Sync>, alloc::collections::btree::node::marker::LeafOrInternal>`, for some specific lifetime `'2` error: implementation of `Send` is not general enough --> src/main.rs:14:5 | 14 | spawn(f()); | ^^^^^ implementation of `Send` is not general enough | = note: `Send` would have to be implemented for the type `alloc::collections::btree::node::NodeRef<alloc::collections::btree::node::marker::Immut<'0>, u32, Box<(dyn Send + Sync + '1)>, alloc::collections::btree::node::marker::Leaf>`, for any two lifetimes `'0` and `'1`... = note: ...but `Send` is actually implemented for the type `alloc::collections::btree::node::NodeRef<alloc::collections::btree::node::marker::Immut<'2>, u32, Box<dyn Send + Sync>, alloc::collections::btree::node::marker::Leaf>`, for some specific lifetime `'2` ```