-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1.70.0: Type inference no longer works in conjunction with Glib's clone macro #112225
Comments
regressed in #104833 cc @Swatinem slightly minimized and removed dependencies: playground use core::future::Future;
fn main() {
do_async(
async { (0,) },
{
// closure must be inside block
|info| println!("{:?}", info.0)
},
);
}
fn do_async<R, Fut, F>(tokio_fut: Fut, glib_closure: F)
where
Fut: Future<Output = R>,
F: FnOnce(R),
{
} Putting the identity function back (or wrapping the async block in a block) seems to "fix" the error: do_async(
- async { (0,) },
+ core::convert::identity(async { (0,) }),
{
// closure must be inside block
|info| println!("{:?}", info.0)
},
); bisector outputsearched nightlies: from nightly-2023-03-01 to nightly-2023-06-01 bisected with cargo-bisect-rustc v0.6.6Host triple: x86_64-unknown-linux-gnu cargo bisect-rustc -- check @rustbot label -regression-untriaged +regression-from-stable-to-stable +A-inference +A-async-await |
It is not only an identity function that makes this suddenly work, but putting the async block in a block works as well.
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. |
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.) |
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. |
Note that just excluding desugared async block closures from this hack breaks inference for different programs that are now accepted on stable, for example: fn main() {
let x = Default::default();
do_async(
async { x.0; },
{ || { let _: &(i32,) = &x; } },
);
}
fn do_async<Fut, T>(fut: Fut, val: T, ) {} |
you mean which are only accepted as of 1.70? |
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. |
@Swatinem @lukas-code: I'd be fine landing a PR that excludes future-desugared async blocks from this hack. |
I opened #112266 with a fix and regression test. Thanks so much @lukas-code for finding the code responsible for this, I sure would have gone crazy with this :-D @marhkb As both the culprit PR and the 1.70 beta went through a crater run, we are wondering why this was never caught earlier? Is it correct to assume your code exhibiting this problem is closed source? Or is it in some public repo that is not yet scraped by crater? |
My code is GPLv3 and can be found here on GitHub. I've never heard of |
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. |
Your repo is on crater under the name "symphony", but it's failing to build due to outdated system libraries. crater log
|
…r=compiler-errors Fix type-inference regression in rust-lang#112225 The type inference of argument-position closures and async blocks regressed in 1.70 as the evaluation order of async blocks changed, as they are not implicitly wrapped in an identity-function anymore. Fixes rust-lang#112225 by making sure the evaluation order stays the same as it used to. r? `@compiler-errors` As this was a stable-to-stable regression, it might be worth to consider backporting. Although the workaround for this is trivial as well: Just wrap the async block in another block.
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 |
The type inference of argument-position closures and async blocks regressed in 1.70 as the evaluation order of async blocks changed, as they are not implicitly wrapped in an identity-function anymore. Fixes rust-lang#112225 by making sure the evaluation order stays the same as it used to.
…k-Simulacrum [beta] backport This PR backports: - rust-lang#112684: Disable alignment checks on i686-pc-windows-msvc - rust-lang#112581: [rustdoc] Fix URL encoding of % sign - rust-lang#112312: Update to LLVM 16.0.5 - rust-lang#112266: Fix type-inference regression in rust-lang#112225 - rust-lang#112062: Make struct layout not depend on unsizeable tail r? `@Mark-Simulacrum`
The type inference of argument-position closures and async blocks regressed in 1.70 as the evaluation order of async blocks changed, as they are not implicitly wrapped in an identity-function anymore. Fixes rust-lang#112225 by making sure the evaluation order stays the same as it used to.
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
andfutures
dependency):Output
I expected to see this happen: The type
info
is correctly inferredInstead, 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
:The text was updated successfully, but these errors were encountered: