about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-05-27 13:01:40 +0200
committerGitHub <noreply@github.com>2025-05-27 13:01:40 +0200
commit9d46af12e018d35e804aece2a8c97e5d9e595c2a (patch)
tree7df4148bde4bd5d6937ec486ccc0a4526008b536
parentfb4cc991c06079ca062b01e5c16c6e9c400382ea (diff)
parent5e31cd30aae245aaa1374e12521667b8c728402d (diff)
downloadrust-9d46af12e018d35e804aece2a8c97e5d9e595c2a.tar.gz
rust-9d46af12e018d35e804aece2a8c97e5d9e595c2a.zip
Rollup merge of #141584 - compiler-errors:typing-env-synthetic-body, r=lcnr
Support `opaque_types_defined_by` for `SyntheticCoroutineBody`

We create a synthetic MIR body for the `AsyncFnOnce` impl for async closures. That body goes through all passes that a regular body does, including promotion.

Promotion sometimes requires computing that the type of an rvalue is `Freeze`, which requires computing the typing env of a body. This requires calling `opaque_types_defined_by` on the body's def id, which leads to an ICE today since we don't expect that query to be called for synthetic bodies.

While we could fix this by, for example, computing the typeck root of the body before calling a `TypingEnv` constructor, I think it's appropriate to do a more general fix here since I think it's reasonable that other passes might do analysis too.

Fixes rust-lang/rust#141466

r? ```@lcnr``` or ```@oli-obk```
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs8
-rw-r--r--tests/ui/async-await/async-closures/promote-in-body.rs13
2 files changed, 18 insertions, 3 deletions
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 841f602d985..3b4482146d4 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -321,7 +321,10 @@ fn opaque_types_defined_by<'tcx>(
             collector.collect_taits_declared_in_body();
         }
         // Closures and coroutines are type checked with their parent
-        DefKind::Closure | DefKind::InlineConst => {
+        // Note that we also support `SyntheticCoroutineBody` since we create
+        // a MIR body for the def kind, and some MIR passes (like promotion)
+        // may require doing analysis using its typing env.
+        DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody => {
             collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item)));
         }
         DefKind::AssocTy | DefKind::TyAlias | DefKind::GlobalAsm => {}
@@ -343,8 +346,7 @@ fn opaque_types_defined_by<'tcx>(
         | DefKind::ForeignMod
         | DefKind::Field
         | DefKind::LifetimeParam
-        | DefKind::Impl { .. }
-        | DefKind::SyntheticCoroutineBody => {
+        | DefKind::Impl { .. } => {
             span_bug!(
                 tcx.def_span(item),
                 "`opaque_types_defined_by` not defined for {} `{item:?}`",
diff --git a/tests/ui/async-await/async-closures/promote-in-body.rs b/tests/ui/async-await/async-closures/promote-in-body.rs
new file mode 100644
index 00000000000..ea95d680987
--- /dev/null
+++ b/tests/ui/async-await/async-closures/promote-in-body.rs
@@ -0,0 +1,13 @@
+//@ build-pass
+//@ compile-flags: --crate-type=lib
+//@ edition: 2024
+
+union U {
+    f: i32,
+}
+
+fn foo() {
+    async || {
+        &U { f: 1 }
+    };
+}