-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
rustc fails to prove Send
ness for an async
block where a !Send
value is dropped before an .await
point
#128095
Comments
Send
ness for an async
block within a !Send
value dropped before an .await
pointSend
ness for an async
block within a !Send
value dropped before an .await
point
I dag into |
Send
ness for an async
block within a !Send
value dropped before an .await
pointSend
ness for an async
block where a !Send
value is dropped before an .await
point
This isn't anything to do with trait selection. I believe this has to do with the temporary that we create on the autoderef when calling the async fn yield_point() {}
struct Lock;
impl Lock {
fn borrow(&self) -> LockGuard<'_> { todo!() }
}
struct LockGuard<'a>(*mut (), &'a ());
impl std::ops::Deref for LockGuard<'_> {
type Target = Inner;
fn deref(&self) -> &Self::Target { todo!() }
}
struct Inner;
impl Inner {
fn foo(&self) -> i32 { 0 }
}
fn main() {
let lock = Lock;
fn is_send(_: impl Send) {}
is_send(async {
let guard = lock.borrow();
let _len = guard.foo(); // Comment this out and it works.
drop(guard);
yield_point().await;
});
} |
Actually, here's a more minimal example: #![feature(coroutines)]
struct S(*mut ());
impl S {
fn do_something(&self) {}
}
fn main() {
fn is_send(_: impl Send) {}
is_send(#[coroutine] static || {
// Make a new `S`.
let s = S::new();
// Borrow it by calling a method on it.
s.do_something();
// Drop `s` by moving it.
drop(s);
// Closure analysis keeps thinking that it's live since it has been
// borrowed and there's no `StorageDrop` on `s`'s local.
yield;
});
} It seems to do with the fact that we don't consider the variable |
cc #112279 which fixes this |
@rustbot labels +AsyncAwait-Triaged We discussed this in our meeting today. Looks like it's being fixed. |
Stop considering moved-out locals when computing auto traits for generators (rebased) This PR revives rust-lang#112279. I wanted to reopen this to gauge `@cjgillot's` thoughts about this, since it's been a while since `-Zdrop-tracking-mir` has landed. If this PR looks OK, I can flesh it out and write up an FCP report -- I think this is a T-types FCP, since this has to do with the types that are considered live for auto traits, and doesn't otherwise affect the layout of coroutines. Open questions: * **"Why do we require storage to be live if the locals is not initialized?"** (rust-lang#112279 (comment)) * I agree that we should eventually fix the storage analysis for coroutines, but this seems like a problem that can be fixed after we fix witnesses for *the purposes of traits* here. * As far as I could tell, fixing the problem of moved locals for *storage* would require insertion of additional `StorageDead` statements, or would require further entangling the type system with the operational semantics in ways that T-opsem seemed uncomfortable with [when I asked](https://rust-lang.zulipchat.com/#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Inserting.20.60StorageDrop.60.20after.20unconditional.20moves). cc `@RalfJung` * Relevant: rust-lang/unsafe-code-guidelines#188 Fixes rust-lang#128095 Fixes rust-lang#94067 r? `@cjgillot`
I tried this code: (playground)
I expected to see this happen: the code passes compilation.
Instead, this happened:
However, this code works fine: (playground)
Meta: nightly rust (1.81.0-nightly 2024-07-12) and stable rust (1.79.0) behave similarly.
I have constructed a minimum reproducible version:
The text was updated successfully, but these errors were encountered: