about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src/shim.rs
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-15 16:07:08 -0400
committerMichael Goulet <michael@errs.io>2024-09-16 10:57:58 -0400
commit57a7e514a4fee2d76bae4b6f2ee72a760518f892 (patch)
tree67c8d49ffc936318c8a925eaf116f5082d45f87b /compiler/rustc_mir_transform/src/shim.rs
parent13b5a4e43b92cf738acad403ea56900947f9d37b (diff)
downloadrust-57a7e514a4fee2d76bae4b6f2ee72a760518f892.tar.gz
rust-57a7e514a4fee2d76bae4b6f2ee72a760518f892.zip
Don't ICE when generating Fn shim for async closure with borrowck error
Diffstat (limited to 'compiler/rustc_mir_transform/src/shim.rs')
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs17
1 files changed, 12 insertions, 5 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),