Repository navigation
Open
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.Diagnostics: Confusing error or lint; hard to understand for new users.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
The following code does not compile:
// Crate versions:
// futures-preview v0.3.0-alpha.18
// runtime v0.3.0-alpha.7
use futures::{prelude::*, stream::FuturesUnordered};
#[runtime::main]
async fn main() {
let entries: Vec<_> = vec![()]
.into_iter()
.map(|x| async { vec![()].into_iter().map(|_| x) })
.collect::<FuturesUnordered<_>>()
.map(stream::iter)
.flatten()
.collect()
.await;
}It produces this error message:
error[E0308]: mismatched types
--> src\main.rs:3:1
|
3 | #[runtime::main]
| ^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected type `std::ops::FnOnce<(std::iter::Map<std::vec::IntoIter<()>, [closure@src\main.rs:7:51: 7:56 x:&()]>,)>`
found type `std::ops::FnOnce<(std::iter::Map<std::vec::IntoIter<()>, [closure@src\main.rs:7:51: 7:56 x:&()]>,)>`
In this case, the code can be made to compile by adding move in two places on this line:
// ...
.map(|x| async move { vec![()].into_iter().map(move |_| x) })
// ...Some possibly related issues: #57362, #60658
rustc version: 1.39.0-nightly (97e58c0d3 2019-09-20)
Reacted by Andrew Plaza, R+, Ximo Guanter, alopatindev, Erlend Langseth, Kornel, 0x5459, Juan Campa, Jacob LeGrone, Scott Olson and 22 more
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.Diagnostics: Confusing error or lint; hard to understand for new users.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
Seeker14491 commentedon Oct 1, 2019
Here's an updated reproduction that doesn't use the
runtimecrate:Error:
ructc version:
rustc 1.40.0-nightly (22bc9e1d9 2019-09-30)djc commentedon Mar 8, 2020
Someone was just asking about this in hyper's gitter channel. The diagnostics here are surprisingly bad. Ping?
Aaron1011 commentedon Mar 18, 2020
The output is better on nightly:
but still contains the spurious "mismatched types" error.
Aaron1011 commentedon Mar 24, 2020
I think the 'one type is more general than the other' error is another instance of #64552
kornelski commentedon Jul 12, 2020
Another case: https://users.rust-lang.org/t/tokio-spawn-error-one-type-is-more-general-than-the-other/45733
Nashenas88 commentedon Oct 13, 2020
This doesn't include async, but the conditions are similar enough, and I found it equally confusing (especially once I realized what the fix was): https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f2cf25b58f393f4a4377b0086e0032a2
inline:
Error:
jerel commentedon Jan 12, 2021
I ran into this same issue this week using tokio. Here's my conclusion, in case it's helpful for narrowing in on the bug.
Reduced down to as few lines as possible it looks like this:
and fails with:
--> src/lib.rs:185:14 | 185 | runtime.spawn(async { | ^^^^^ one type is more general than the other | = note: expected type `std::ops::FnOnce<(warp::generic::Either<(warp::generic::Either<(warp::http::Response<std::vec::Vec<u8>>,), (warp::http::Response<std::vec::Vec<u8>>,)>,), (impl warp::Reply,)>,)>` found type `std::ops::FnOnce<(warp::generic::Either<(warp::generic::Either<(warp::http::Response<std::vec::Vec<u8>>,), (warp::http::Response<std::vec::Vec<u8>>,)>,), (impl warp::Reply,)>,)>`Those types are identical aren't they? I managed to work around it like this:
The first version has been working fine in another part of the codebase, something about how it's called here triggers it maybe? The other way I'm using it is in a
#[tokio::main]function instead ofruntime.spawnbut the implementation is identical.Shizcow commentedon Jan 25, 2021
I have found a fairly minimal way to reproduce without external dependencies, and several useful observations. It's not using async, so maybe this is more fitted for #64552?
Tested with
rustc 1.51.0-nightly (d98d2f57d 2021-01-18)This is the reproduction code:
The above yields the following error:
Replacing the generic
Retwith&strdoes let the code compile, but I have some more observations that more naturally lead to this conclusion. Besides, non-generic fn return parameters aren't fun!From the error it looks like a lifetime is either forgotten or elided. Removing the type annotations on
foogives a little more data:And the new error:
Well that's not right.
ais supposed to befor<'r> fn(&'r str) -> &'static str, notfor<'r> fn(&'r str) -> &'r str. The'staticseems to be replaced by'r.What explicitly declaring the lifetime of
a's return:New error:
Now the lifetimes are correct but it's not picking up the
impl, even thoughimpl<Ret>is about as general as you can get. What about explicitly declaring theimplwith the compiler-supplied type, but still with generic return:New error:
Even though the
impl Typeis the exact same type as in the error, it's not recognized. The error is the same if the additional lifetime parameters are left out (IEimpl BoxHolder<Box<fn(&str) -> &str>>). The only thing I've gotten to work is the following:The above code compiles correctly. It seems that
BoxHolder { data: Box::new(a) }is notBoxHolder<Box<fn(&str) -> &str>>but can be imlpicitly converted into it.FWIW, doing
type F = fn(&str) -> &str;and usingFeverywhere doesn't change the errors. An implicit cast toBoxHolder<Box<F>>is still required. If someone knows how to directly check the type of two variables (during compilation?) I think the next step would be seeing what the types of the following two variables are, because the type system doesn't seem to think they're equal according to the testing above:This is all the useful information I'm able to gleam from this. I'm unsure if the later results are directly related to the initial
one type is more general than the otherissue, if they're another bug entirely, or if they're a thing because I just plain don't know enough rust. Hope it helps in diagnosing the root cause.estebank commentedon Oct 8, 2026
Current output:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=461f44a5a1143577d4e600e46a3c4bfd
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=8bdb0d3d21de458ae4299fd66af80241
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=d4e19bf0b1c9956015ac072fb55cf0ff
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=b5f2856f669ecb39bcb735517ba418e3
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=0ff1324314dd4b22028f5ad3e6d09b89