Skip to content

Commit f3b74b9

Browse files
authored
Unrolled build for rust-lang#130410
Rollup merge of rust-lang#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 rust-lang#129262.
2 parents 3a22be3 + 57a7e51 commit f3b74b9

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

compiler/rustc_mir_transform/src/shim.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1070,19 +1070,26 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
10701070
let locals = local_decls_for_sig(&sig, span);
10711071

10721072
let mut fields = vec![];
1073+
1074+
// Move all of the closure args.
10731075
for idx in 1..sig.inputs().len() {
10741076
fields.push(Operand::Move(Local::from_usize(idx + 1).into()));
10751077
}
1078+
10761079
for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() {
10771080
if receiver_by_ref {
10781081
// The only situation where it's possible is when we capture immuatable references,
10791082
// since those don't need to be reborrowed with the closure's env lifetime. Since
10801083
// references are always `Copy`, just emit a copy.
1081-
assert_matches!(
1082-
ty.kind(),
1083-
ty::Ref(_, _, hir::Mutability::Not),
1084-
"field should be captured by immutable ref if we have an `Fn` instance"
1085-
);
1084+
if !matches!(ty.kind(), ty::Ref(_, _, hir::Mutability::Not)) {
1085+
// This copy is only sound if it's a `&T`. This may be
1086+
// reachable e.g. when eagerly computing the `Fn` instance
1087+
// of an async closure that doesn't borrowck.
1088+
tcx.dcx().delayed_bug(format!(
1089+
"field should be captured by immutable ref if we have \
1090+
an `Fn` instance, but it was: {ty}"
1091+
));
1092+
}
10861093
fields.push(Operand::Copy(tcx.mk_place_field(
10871094
self_local,
10881095
FieldIdx::from_usize(idx),

tests/crashes/129262.rs renamed to tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@ known-bug: rust-lang/rust#129262
21
//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
32

43
#![feature(async_closure)]
@@ -11,6 +10,7 @@ fn needs_fn_mut<T>(mut x: impl FnMut() -> T) {
1110

1211
fn hello(x: Ty) {
1312
needs_fn_mut(async || {
13+
//~^ ERROR cannot move out of `x`
1414
x.hello();
1515
});
1616
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0507]: cannot move out of `x` which is behind a mutable reference
2+
--> $DIR/closure-shim-borrowck-error.rs:12:18
3+
|
4+
LL | needs_fn_mut(async || {
5+
| ^^^^^^^^ `x` is moved here
6+
LL |
7+
LL | x.hello();
8+
| -
9+
| |
10+
| variable moved due to use in coroutine
11+
| move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
12+
|
13+
note: if `Ty` implemented `Clone`, you could clone the value
14+
--> $DIR/closure-shim-borrowck-error.rs:18:1
15+
|
16+
LL | x.hello();
17+
| - you could clone this value
18+
...
19+
LL | struct Ty;
20+
| ^^^^^^^^^ consider implementing `Clone` for this type
21+
22+
error: aborting due to 1 previous error
23+
24+
For more information about this error, try `rustc --explain E0507`.

0 commit comments

Comments
 (0)