From 6ea2db7c2d78182fabf66a8c6ffc856446e1cf81 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Wed, 27 Sep 2023 11:20:17 +0000
Subject: [PATCH] Strip `OpaqueCast` during `RevealAll`.

---
 compiler/rustc_codegen_cranelift/src/base.rs  |  2 +-
 compiler/rustc_codegen_ssa/src/mir/place.rs   |  4 +++-
 .../src/interpret/projection.rs               |  2 +-
 .../rustc_mir_transform/src/reveal_all.rs     | 19 +++++++++++++++
 .../indirect-recursion-issue-112047.stderr    |  2 +-
 tests/ui/polymorphization/generators.rs       |  2 --
 tests/ui/polymorphization/generators.stderr   | 20 +++-------------
 .../cross_inference_pattern_bug.rs            |  2 +-
 .../destructure_tait-layout_of-ice-113594.rs  | 23 +++++++++++++++++++
 .../indirect-recursion-issue-112047.stderr    |  7 ++++--
 10 files changed, 57 insertions(+), 26 deletions(-)
 create mode 100644 tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs

diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 9b5a6b89191..6d55fdc3074 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -875,7 +875,7 @@ pub(crate) fn codegen_place<'tcx>(
             PlaceElem::Deref => {
                 cplace = cplace.place_deref(fx);
             }
-            PlaceElem::OpaqueCast(ty) => cplace = cplace.place_opaque_cast(fx, ty),
+            PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
             PlaceElem::Field(field, _ty) => {
                 cplace = cplace.place_field(fx, field);
             }
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index a9ecbdc5f35..f775711f870 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -463,7 +463,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 mir::ProjectionElem::Field(ref field, _) => {
                     cg_base.project_field(bx, field.index())
                 }
-                mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty),
+                mir::ProjectionElem::OpaqueCast(ty) => {
+                    bug!("encountered OpaqueCast({ty}) in codegen")
+                }
                 mir::ProjectionElem::Index(index) => {
                     let index = &mir::Operand::Copy(mir::Place::from(index));
                     let index = self.codegen_operand(bx, index);
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 6c720ac4a57..ca5e19ac1fa 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -316,7 +316,7 @@ where
     {
         use rustc_middle::mir::ProjectionElem::*;
         Ok(match proj_elem {
-            OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?,
+            OpaqueCast(ty) => bug!("OpaqueCast({ty}) encountered after borrowck"),
             Field(field, _) => self.project_field(base, field.index())?,
             Downcast(_, variant) => self.project_downcast(base, variant)?,
             Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs
index cdd208f5c93..6cc0d383119 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/reveal_all.rs
@@ -25,6 +25,25 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
         self.tcx
     }
 
+    #[inline]
+    fn visit_place(
+        &mut self,
+        place: &mut Place<'tcx>,
+        _context: PlaceContext,
+        _location: Location,
+    ) {
+        // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
+        // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
+        // projections anymore.
+        place.projection = self.tcx.mk_place_elems(
+            &place
+                .projection
+                .into_iter()
+                .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
+                .collect::<Vec<_>>(),
+        );
+    }
+
     #[inline]
     fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
         // We have to use `try_normalize_erasing_regions` here, since it's
diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
index e0c1acfedfc..41e84466a14 100644
--- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
+++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
@@ -2,7 +2,7 @@ error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indir
    |
    = note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`...
    = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`, completing the cycle
-   = note: cycle used when computing layout of `<impl at $DIR/indirect-recursion-issue-112047.rs:31:1: 31:21>::second::{opaque#0}`
+   = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:8:13: 10:6}`
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to previous error
diff --git a/tests/ui/polymorphization/generators.rs b/tests/ui/polymorphization/generators.rs
index 5f157bc3efb..779bac0ace2 100644
--- a/tests/ui/polymorphization/generators.rs
+++ b/tests/ui/polymorphization/generators.rs
@@ -32,7 +32,6 @@ where
 
 #[rustc_polymorphize_error]
 pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
-    //~^ ERROR item has unused generic parameters
     || {
         //~^ ERROR item has unused generic parameters
         yield 1;
@@ -58,7 +57,6 @@ pub fn used_type_in_return<R: Default>() -> impl Generator<(), Yield = u32, Retu
 
 #[rustc_polymorphize_error]
 pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
-    //~^ ERROR item has unused generic parameters
     || {
         //~^ ERROR item has unused generic parameters
         yield 1;
diff --git a/tests/ui/polymorphization/generators.stderr b/tests/ui/polymorphization/generators.stderr
index 7461beb7b19..32d49d25f02 100644
--- a/tests/ui/polymorphization/generators.stderr
+++ b/tests/ui/polymorphization/generators.stderr
@@ -8,34 +8,20 @@ LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error: item has unused generic parameters
-  --> $DIR/generators.rs:36:5
+  --> $DIR/generators.rs:35:5
    |
 LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
    |                    - generic parameter `T` is unused
-LL |
 LL |     || {
    |     ^^
 
 error: item has unused generic parameters
-  --> $DIR/generators.rs:34:8
-   |
-LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
-   |        ^^^^^^^^^^^ - generic parameter `T` is unused
-
-error: item has unused generic parameters
-  --> $DIR/generators.rs:62:5
+  --> $DIR/generators.rs:60:5
    |
 LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
    |                     ------------ generic parameter `T` is unused
-LL |
 LL |     || {
    |     ^^
 
-error: item has unused generic parameters
-  --> $DIR/generators.rs:60:8
-   |
-LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
-   |        ^^^^^^^^^^^^ ------------ generic parameter `T` is unused
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
index 9a50c0f988a..31fea42fa5d 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
@@ -1,5 +1,5 @@
 // compile-flags: --edition=2021
-// check-pass
+// build-pass
 #![feature(type_alias_impl_trait)]
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs
new file mode 100644
index 00000000000..8568b26bea2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs
@@ -0,0 +1,23 @@
+// build-pass
+// edition: 2021
+
+#![feature(type_alias_impl_trait)]
+
+fn foo<T>(x: T) {
+    type Opaque<T> = impl Sized;
+    let foo: Opaque<T> = (x,);
+    let (a,): (T,) = foo;
+}
+
+const fn bar<T: Copy>(x: T) {
+    type Opaque<T: Copy> = impl Copy;
+    let foo: Opaque<T> = (x, 2u32);
+    let (a, b): (T, u32) = foo;
+}
+
+fn main() {
+    foo::<u32>(1);
+    bar::<u32>(1);
+    const CONST: () = bar::<u32>(42u32);
+    CONST
+}
diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr
index 3312230bc81..2063becdb08 100644
--- a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr
+++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr
@@ -1,6 +1,5 @@
 error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}`
    |
-   = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<recur::{opaque#0}>`...
    = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`...
    = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`...
    = note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}`...
@@ -8,7 +7,11 @@ error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirec
    = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`...
    = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`...
    = note: ...which again requires computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}`, completing the cycle
-   = note: cycle used when computing layout of `<impl at $DIR/indirect-recursion-issue-112047.rs:19:1: 19:18>::Recur`
+note: cycle used when elaborating drops for `<impl at $DIR/indirect-recursion-issue-112047.rs:19:1: 19:18>::recur`
+  --> $DIR/indirect-recursion-issue-112047.rs:22:5
+   |
+LL |     fn recur(self) -> Self::Recur {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to previous error