mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Don't ICE when generating Fn shim for async closure with borrowck error
This commit is contained in:
parent
13b5a4e43b
commit
57a7e514a4
@ -1070,19 +1070,26 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
|
||||
let locals = local_decls_for_sig(&sig, span);
|
||||
|
||||
let mut fields = vec![];
|
||||
|
||||
// Move all of the closure args.
|
||||
for idx in 1..sig.inputs().len() {
|
||||
fields.push(Operand::Move(Local::from_usize(idx + 1).into()));
|
||||
}
|
||||
|
||||
for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() {
|
||||
if receiver_by_ref {
|
||||
// The only situation where it's possible is when we capture immuatable references,
|
||||
// since those don't need to be reborrowed with the closure's env lifetime. Since
|
||||
// references are always `Copy`, just emit a copy.
|
||||
assert_matches!(
|
||||
ty.kind(),
|
||||
ty::Ref(_, _, hir::Mutability::Not),
|
||||
"field should be captured by immutable ref if we have an `Fn` instance"
|
||||
);
|
||||
if !matches!(ty.kind(), ty::Ref(_, _, hir::Mutability::Not)) {
|
||||
// This copy is only sound if it's a `&T`. This may be
|
||||
// reachable e.g. when eagerly computing the `Fn` instance
|
||||
// of an async closure that doesn't borrowck.
|
||||
tcx.dcx().delayed_bug(format!(
|
||||
"field should be captured by immutable ref if we have \
|
||||
an `Fn` instance, but it was: {ty}"
|
||||
));
|
||||
}
|
||||
fields.push(Operand::Copy(tcx.mk_place_field(
|
||||
self_local,
|
||||
FieldIdx::from_usize(idx),
|
||||
|
@ -1,4 +1,3 @@
|
||||
//@ known-bug: rust-lang/rust#129262
|
||||
//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
|
||||
|
||||
#![feature(async_closure)]
|
||||
@ -11,6 +10,7 @@ fn needs_fn_mut<T>(mut x: impl FnMut() -> T) {
|
||||
|
||||
fn hello(x: Ty) {
|
||||
needs_fn_mut(async || {
|
||||
//~^ ERROR cannot move out of `x`
|
||||
x.hello();
|
||||
});
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
error[E0507]: cannot move out of `x` which is behind a mutable reference
|
||||
--> $DIR/closure-shim-borrowck-error.rs:12:18
|
||||
|
|
||||
LL | needs_fn_mut(async || {
|
||||
| ^^^^^^^^ `x` is moved here
|
||||
LL |
|
||||
LL | x.hello();
|
||||
| -
|
||||
| |
|
||||
| variable moved due to use in coroutine
|
||||
| move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
|
||||
|
|
||||
note: if `Ty` implemented `Clone`, you could clone the value
|
||||
--> $DIR/closure-shim-borrowck-error.rs:18:1
|
||||
|
|
||||
LL | x.hello();
|
||||
| - you could clone this value
|
||||
...
|
||||
LL | struct Ty;
|
||||
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
Loading…
Reference in New Issue
Block a user