-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Closed
Copy link
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-inferenceArea: Type inferenceArea: Type inferenceC-bugCategory: This is a bug.Category: This is a bug.P-highHigh priorityHigh priorityT-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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Description
My code does not compile any more after updating to 1.70.0. The project can be found here
Code
I tried to create a minimal reproducer. It has something to do with glib's clone macro, which I use. Here is the reproducer that compiles fine on 1.69 but not on 1.70.0. I left some comments in the code describing what I observed so far. It needs glib
and futures
dependency):
use futures::Future;
use glib::clone;
fn main() {
let obj = String::new();
do_async(
// just using `compound()` without `async` block works
async { compound().await },
clone!(@strong obj => move |info| if let Ok(info) = info {
// removing this line makes the code compile
println!("{:?}", info.t);
}),
);
}
struct Compound {
t: i32
}
// Just returning a simple type like i32 makes the code compile
async fn compound() -> Result<Compound, ()> {
Err(())
}
async fn do_async<R, Fut, F>(tokio_fut: Fut, glib_closure: F)
where
R: Send + 'static,
Fut: Future<Output = R> + Send + 'static,
F: FnOnce(R) + 'static,
{
glib_closure(tokio_fut.await);
}
Output
error[E0282]: type annotations needed for `Result<_, E>`
--> src/main.rs:9:37
|
9 | clone!(@strong obj => move |info| if let Ok(info) = info {
| ^^^^
10 | // removing this line makes the code compile
11 | println!("{:?}", info.t);
| ---- type must be known at this point
|
help: consider giving this closure parameter an explicit type, where the placeholders `_` are specified
|
9 | clone!(@strong obj => move |info: Result<_, E>| if let Ok(info) = info {
| ++++++++++++++
For more information about this error, try `rustc --explain E0282`.
I expected to see this happen: The type info
is correctly inferred
Instead, this happened: The compiler tells me that it doesn't know the type, although the type can be inferred
Version it worked on
It most recently worked on: 1.69.0
Version with regression
rustc --version --verbose
:
rustc 1.70.0 (90c541806 2023-05-31)
binary: rustc
commit-hash: 90c541806f23a127002de5b4038be731ba1458ca
commit-date: 2023-05-31
host: x86_64-unknown-linux-gnu
release: 1.70.0
LLVM version: 16.0.2
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-inferenceArea: Type inferenceArea: Type inferenceC-bugCategory: This is a bug.Category: This is a bug.P-highHigh priorityHigh priorityT-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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
lukas-code commentedon Jun 2, 2023
regressed in #104833 cc @Swatinem
slightly minimized and removed dependencies: playground
Putting the identity function back (or wrapping the async block in a block) seems to "fix" the error:
bisector output
searched nightlies: from nightly-2023-03-01 to nightly-2023-06-01
regressed nightly: nightly-2023-03-15
searched commit range: 22f247c...1716932
regressed commit: 669e751
bisected with cargo-bisect-rustc v0.6.6
Host triple: x86_64-unknown-linux-gnu
Reproduce with:
@rustbot label -regression-untriaged +regression-from-stable-to-stable +A-inference +A-async-await
Swatinem commentedon Jun 3, 2023
It is not only an identity function that makes this suddenly work, but putting the async block in a block works as well.
Permuting what to wrap in a block, only a single case out of the four fails:
Out of curiousity I tried the patch in #109338 thats supposed to fix #106527 to make async blocks "provide inference guidance", but that doesn’t work either.
lukas-code commentedon Jun 3, 2023
This happens due to a hack in typeck, where function arguments that aren't closures, including block expressions that return closures, are typechecked before function parameters that are closures. Note that async blocks are desugared to closures.
rust/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Lines 333 to 378 in 2f5e6bb
This basically means that closures and async blocks in function arguments behave as if they were ordered after all non-closure non-async-block arguments and you now get the same inference error that you would get on older compilers if you manually swapped the function arguments.
(Also, looks like this hack has existed forever.)
Swatinem commentedon Jun 3, 2023
Wow, that is a very good catch! And also good news, as it means "fixing" the regression should be a oneliner, which I will try tomorrow.
However that does smell like a very gross hack, and I wonder if there will eventually be a better way altogether. But that is for a different day.
lukas-code commentedon Jun 3, 2023
Note that just excluding desugared async block closures from this hack breaks inference for different programs that are now accepted on stable, for example:
Swatinem commentedon Jun 3, 2023
you mean which are only accepted as of 1.70?
lukas-code commentedon Jun 3, 2023
Yeah, I mean stable 1.70. But I guess it's better to break a constructed program that compiled for one stable version instead of breaking a real codebase that compiled for several stable versions.
compiler-errors commentedon Jun 3, 2023
@Swatinem @lukas-code: I'd be fine landing a PR that excludes future-desugared async blocks from this hack.
3 remaining items
Fix type-inference regression in rust-lang#112225
marhkb commentedon Jun 4, 2023
My code is GPLv3 and can be found here on GitHub. I've never heard of
crater
and I don't think it is scraped. But it would really cool if it could scrape my project, too. To actually build it, you also need some system libraries installed like glib2, gtk4, libadwaita, etc. No idea whethercrater
can handle this special case.Swatinem commentedon Jun 4, 2023
Crater should automatically pick up any public Rust project on github. But I’m not an expert on it by any means. Its quite possible that it ignores certain crates that depend on specific system libraries.
lukas-code commentedon Jun 4, 2023
Your repo is on crater under the name "symphony", but it's failing to build due to outdated system libraries.
crater log
Auto merge of rust-lang#112266 - Swatinem:fix-async-block-inference, …
apiraino commentedon Jun 5, 2023
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-high
Note: unsure if we wanted to keep issues open when the fix is nominated for a backport
Fix type-inference regression in rust-lang#112225
Auto merge of rust-lang#113000 - Mark-Simulacrum:beta-backport, r=Mar…
Fix type-inference regression in rust-lang#112225