diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-09-16 18:34:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-16 18:34:01 +0200 |
| commit | 9a1004c259dddb2ba70c92db38a02e6518146334 (patch) | |
| tree | 6023de88453fe1268df1188464e64404b4a8b7b4 | |
| parent | eac6f07380350b2b369e2942e8511f4178c642c2 (diff) | |
| parent | 57a7e514a4fee2d76bae4b6f2ee72a760518f892 (diff) | |
| download | rust-9a1004c259dddb2ba70c92db38a02e6518146334.tar.gz rust-9a1004c259dddb2ba70c92db38a02e6518146334.zip | |
Rollup merge of #130410 - compiler-errors:shim-borrowck-err, r=jieyouxu
Don't ICE when generating `Fn` shim for async closure with borrowck error Turn an assumption that I had originally written as an assert into a delayed bug, because this shim code is reachable even if we have borrowck errors via the MIR inliner. Fixes #129262.
| -rw-r--r-- | compiler/rustc_mir_transform/src/shim.rs | 17 | ||||
| -rw-r--r-- | tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs (renamed from tests/crashes/129262.rs) | 2 | ||||
| -rw-r--r-- | tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr | 24 |
3 files changed, 37 insertions, 6 deletions
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index f1bd803d835..47d04d8a00b 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -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), diff --git a/tests/crashes/129262.rs b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs index c430af35988..4cbbefb0f52 100644 --- a/tests/crashes/129262.rs +++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs @@ -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(); }); } diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr new file mode 100644 index 00000000000..bab26c19482 --- /dev/null +++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr @@ -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`. |
