about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-20 04:57:51 +0000
committerbors <bors@rust-lang.org>2024-01-20 04:57:51 +0000
commit5378c1cf0713ab224eb6431327c28522182feb69 (patch)
tree9c5a3060be46fcff08e195903ac9fd52b0cd3566
parent128148d4cf742c3056e9bfc65e7cc9531cb0f815 (diff)
parent867831a1703c0ea7c062a5139538ea20f5921b62 (diff)
downloadrust-5378c1cf0713ab224eb6431327c28522182feb69.tar.gz
rust-5378c1cf0713ab224eb6431327c28522182feb69.zip
Auto merge of #119821 - oli-obk:reveal_all_const_evals, r=lcnr
Always use RevealAll for const eval queries

implements what is described in https://github.com/rust-lang/rust/pull/116803#discussion_r1364089471

Using `UserFacing` for const eval does not make sense anymore, unless we significantly change things like avoiding revealing opaque types.

New tests are copied from https://github.com/rust-lang/rust/pull/101478
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs38
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr5
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr5
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr5
-rw-r--r--tests/ui/consts/const-eval/const-eval-query-stack.stderr5
-rw-r--r--tests/ui/consts/const-size_of-cycle.stderr5
-rw-r--r--tests/ui/consts/issue-36163.stderr14
-rw-r--r--tests/ui/consts/issue-44415.stderr5
-rw-r--r--tests/ui/consts/recursive-zst-static.default.stderr9
-rw-r--r--tests/ui/consts/recursive-zst-static.unleash.stderr9
-rw-r--r--tests/ui/consts/write-to-static-mut-in-static.stderr9
-rw-r--r--tests/ui/impl-trait/in-ctfe/array-len-size-of.rs16
-rw-r--r--tests/ui/impl-trait/in-ctfe/array-len.rs22
-rw-r--r--tests/ui/impl-trait/in-ctfe/enum-discr.rs26
-rw-r--r--tests/ui/impl-trait/in-ctfe/fully_monomorphic_const_eval.rs29
-rw-r--r--tests/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs24
-rw-r--r--tests/ui/impl-trait/transmute/in-defining-scope.rs14
-rw-r--r--tests/ui/impl-trait/transmute/in-defining-scope.stderr29
-rw-r--r--tests/ui/impl-trait/transmute/outside-of-defining-scope.rs12
-rw-r--r--tests/ui/issues/issue-23302-1.stderr12
-rw-r--r--tests/ui/issues/issue-23302-2.stderr13
-rw-r--r--tests/ui/issues/issue-23302-3.stderr10
-rw-r--r--tests/ui/recursion/recursive-static-definition.stderr9
-rw-r--r--tests/ui/specialization/ctfe/default-assoc-const.rs18
-rw-r--r--tests/ui/specialization/ctfe/default-assoc-const.stderr12
-rw-r--r--tests/ui/specialization/ctfe/default-assoc-type.rs27
-rw-r--r--tests/ui/specialization/ctfe/default-assoc-type.stderr12
-rw-r--r--tests/ui/treat-err-as-bug/err.stderr2
-rw-r--r--tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr5
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.stderr50
32 files changed, 363 insertions, 108 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 9d22df50d4f..4236117d75b 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -225,17 +225,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
-    // see comment in eval_to_allocation_raw_provider for what we're doing here
-    if key.param_env.reveal() == Reveal::All {
-        let mut key = key;
-        key.param_env = key.param_env.with_user_facing();
-        match tcx.eval_to_const_value_raw(key) {
-            // try again with reveal all as requested
-            Err(ErrorHandled::TooGeneric(_)) => {}
-            // deduplicate calls
-            other => return other,
-        }
-    }
+    // Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
+    // opaque types. This is needed for trivial things like `size_of`, but also for using associated
+    // types that are not specified in the opaque type.
+    assert_eq!(key.param_env.reveal(), Reveal::All);
 
     // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
     // Catch such calls and evaluate them instead of trying to load a constant's MIR.
@@ -265,24 +258,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
-    // Because the constant is computed twice (once per value of `Reveal`), we are at risk of
-    // reporting the same error twice here. To resolve this, we check whether we can evaluate the
-    // constant in the more restrictive `Reveal::UserFacing`, which most likely already was
-    // computed. For a large percentage of constants that will already have succeeded. Only
-    // associated constants of generic functions will fail due to not enough monomorphization
-    // information being available.
-
-    // In case we fail in the `UserFacing` variant, we just do the real computation.
-    if key.param_env.reveal() == Reveal::All {
-        let mut key = key;
-        key.param_env = key.param_env.with_user_facing();
-        match tcx.eval_to_allocation_raw(key) {
-            // try again with reveal all as requested
-            Err(ErrorHandled::TooGeneric(_)) => {}
-            // deduplicate calls
-            other => return other,
-        }
-    }
+    // Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
+    // opaque types. This is needed for trivial things like `size_of`, but also for using associated
+    // types that are not specified in the opaque type.
+
+    assert_eq!(key.param_env.reveal(), Reveal::All);
     if cfg!(debug_assertions) {
         // Make sure we format the instance even if we do not print it.
         // This serves as a regression test against an ICE on printing.
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 092b59deeff..b20df1b2343 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -145,7 +145,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> EvalToConstValueResult<'tcx> {
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
-        let inputs = self.erase_regions(param_env.and(cid));
+        let inputs = self.erase_regions(param_env.with_reveal_all_normalized(self).and(cid));
         if let Some(span) = span {
             // The query doesn't know where it is being invoked, so we need to fix the span.
             self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
@@ -164,7 +164,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> EvalToValTreeResult<'tcx> {
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
-        let inputs = self.erase_regions(param_env.and(cid));
+        let inputs = self.erase_regions(param_env.with_reveal_all_normalized(self).and(cid));
         debug!(?inputs);
         if let Some(span) = span {
             // The query doesn't know where it is being invoked, so we need to fix the span.
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
index 21062fdaf58..88b17be601c 100644
--- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
@@ -9,11 +9,6 @@ note: ...which requires simplifying constant for the type system `IMPL_REF_BAR`.
    |
 LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
    | ^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires simplifying constant for the type system `IMPL_REF_BAR`...
-  --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
-   |
-LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
   --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:27
    |
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
index e4abf6203e8..fd1b4f2f964 100644
--- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
@@ -9,11 +9,6 @@ note: ...which requires simplifying constant for the type system `DEFAULT_REF_BA
    |
 LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires simplifying constant for the type system `DEFAULT_REF_BAR`...
-  --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
-   |
-LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
   --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:30
    |
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
index 05ebd76f500..303400f928e 100644
--- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
@@ -9,11 +9,6 @@ note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`
    |
 LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
    | ^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`...
-  --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
-   |
-LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
   --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:28
    |
diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.stderr b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
index c748af608d1..2fcb3d41dd9 100644
--- a/tests/ui/consts/const-eval/const-eval-query-stack.stderr
+++ b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
@@ -7,7 +7,6 @@ LL | const X: i32 = 1 / 0;
 query stack during panic:
 #0 [eval_to_allocation_raw] const-evaluating + checking `X`
 #1 [eval_to_const_value_raw] simplifying constant for the type system `X`
-#2 [eval_to_const_value_raw] simplifying constant for the type system `X`
-#3 [lint_mod] linting top-level module
-#4 [analysis] running analysis passes on this crate
+#2 [lint_mod] linting top-level module
+#3 [analysis] running analysis passes on this crate
 end of query stack
diff --git a/tests/ui/consts/const-size_of-cycle.stderr b/tests/ui/consts/const-size_of-cycle.stderr
index a5679400c2f..cd0ea556425 100644
--- a/tests/ui/consts/const-size_of-cycle.stderr
+++ b/tests/ui/consts/const-size_of-cycle.stderr
@@ -9,11 +9,6 @@ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`..
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`...
-  --> $DIR/const-size_of-cycle.rs:4:17
-   |
-LL |     bytes: [u8; std::mem::size_of::<Foo>()]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires computing layout of `[u8; std::mem::size_of::<Foo>()]`...
    = note: ...which requires normalizing `[u8; std::mem::size_of::<Foo>()]`...
diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr
index 4f2d92ba3cd..de70a457f16 100644
--- a/tests/ui/consts/issue-36163.stderr
+++ b/tests/ui/consts/issue-36163.stderr
@@ -20,11 +20,17 @@ note: ...which requires const-evaluating + checking `A`...
 LL | const A: isize = Foo::B as isize;
    |                  ^^^^^^^^^^^^^^^
    = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle
-note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}`
-  --> $DIR/issue-36163.rs:4:9
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-36163.rs:1:1
    |
-LL |     B = A,
-   |         ^
+LL | / const A: isize = Foo::B as isize;
+LL | |
+LL | | enum Foo {
+LL | |     B = A,
+LL | | }
+LL | |
+LL | | fn main() {}
+   | |____________^
    = 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 1 previous error
diff --git a/tests/ui/consts/issue-44415.stderr b/tests/ui/consts/issue-44415.stderr
index adb5747c424..641945fce9f 100644
--- a/tests/ui/consts/issue-44415.stderr
+++ b/tests/ui/consts/issue-44415.stderr
@@ -9,11 +9,6 @@ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`..
    |
 LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`...
-  --> $DIR/issue-44415.rs:6:17
-   |
-LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires computing layout of `[u8; unsafe { intrinsics::size_of::<Foo>() }]`...
    = note: ...which requires normalizing `[u8; unsafe { intrinsics::size_of::<Foo>() }]`...
diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr
index 3bbb685a678..5b4a0418b1e 100644
--- a/tests/ui/consts/recursive-zst-static.default.stderr
+++ b/tests/ui/consts/recursive-zst-static.default.stderr
@@ -1,15 +1,10 @@
 error[E0391]: cycle detected when const-evaluating + checking `FOO`
-  --> $DIR/recursive-zst-static.rs:10:1
-   |
-LL | static FOO: () = FOO;
-   | ^^^^^^^^^^^^^^
-   |
-note: ...which requires const-evaluating + checking `FOO`...
   --> $DIR/recursive-zst-static.rs:10:18
    |
 LL | static FOO: () = FOO;
    |                  ^^^
-   = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
+   |
+   = note: ...which immediately requires const-evaluating + checking `FOO` again
 note: cycle used when linting top-level module
   --> $DIR/recursive-zst-static.rs:10:1
    |
diff --git a/tests/ui/consts/recursive-zst-static.unleash.stderr b/tests/ui/consts/recursive-zst-static.unleash.stderr
index 3bbb685a678..5b4a0418b1e 100644
--- a/tests/ui/consts/recursive-zst-static.unleash.stderr
+++ b/tests/ui/consts/recursive-zst-static.unleash.stderr
@@ -1,15 +1,10 @@
 error[E0391]: cycle detected when const-evaluating + checking `FOO`
-  --> $DIR/recursive-zst-static.rs:10:1
-   |
-LL | static FOO: () = FOO;
-   | ^^^^^^^^^^^^^^
-   |
-note: ...which requires const-evaluating + checking `FOO`...
   --> $DIR/recursive-zst-static.rs:10:18
    |
 LL | static FOO: () = FOO;
    |                  ^^^
-   = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
+   |
+   = note: ...which immediately requires const-evaluating + checking `FOO` again
 note: cycle used when linting top-level module
   --> $DIR/recursive-zst-static.rs:10:1
    |
diff --git a/tests/ui/consts/write-to-static-mut-in-static.stderr b/tests/ui/consts/write-to-static-mut-in-static.stderr
index 5665e56439e..caee433a681 100644
--- a/tests/ui/consts/write-to-static-mut-in-static.stderr
+++ b/tests/ui/consts/write-to-static-mut-in-static.stderr
@@ -5,17 +5,12 @@ LL | pub static mut B: () = unsafe { A = 1; };
    |                                 ^^^^^ modifying a static's initial value from another static's initializer
 
 error[E0391]: cycle detected when const-evaluating + checking `C`
-  --> $DIR/write-to-static-mut-in-static.rs:5:1
-   |
-LL | pub static mut C: u32 = unsafe { C = 1; 0 };
-   | ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires const-evaluating + checking `C`...
   --> $DIR/write-to-static-mut-in-static.rs:5:34
    |
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    |                                  ^^^^^
-   = note: ...which again requires const-evaluating + checking `C`, completing the cycle
+   |
+   = note: ...which immediately requires const-evaluating + checking `C` again
 note: cycle used when linting top-level module
   --> $DIR/write-to-static-mut-in-static.rs:1:1
    |
diff --git a/tests/ui/impl-trait/in-ctfe/array-len-size-of.rs b/tests/ui/impl-trait/in-ctfe/array-len-size-of.rs
new file mode 100644
index 00000000000..01ba902ef0c
--- /dev/null
+++ b/tests/ui/impl-trait/in-ctfe/array-len-size-of.rs
@@ -0,0 +1,16 @@
+//! Check that const eval can use the size of opaque types.
+// check-pass
+use std::mem;
+fn returns_opaque() -> impl Sized {
+    0u8
+}
+
+struct NamedOpaqueType {
+    data: [mem::MaybeUninit<u8>; size_of_fut(returns_opaque)],
+}
+
+const fn size_of_fut<FUT>(x: fn() -> FUT) -> usize {
+    mem::size_of::<FUT>()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-ctfe/array-len.rs b/tests/ui/impl-trait/in-ctfe/array-len.rs
new file mode 100644
index 00000000000..73ae20495d5
--- /dev/null
+++ b/tests/ui/impl-trait/in-ctfe/array-len.rs
@@ -0,0 +1,22 @@
+//! Check that array lengths can observe associated types of opaque types
+// check-pass
+trait MyTrait: Copy {
+    const ASSOC: usize;
+}
+
+impl MyTrait for u8 {
+    const ASSOC: usize = 32;
+}
+
+const fn yeet() -> impl MyTrait {
+    0u8
+}
+
+const fn output<T: MyTrait>(_: T) -> usize {
+    <T as MyTrait>::ASSOC
+}
+
+fn main() {
+    let x = [0u8; output(yeet())];
+    println!("{:?}", x);
+}
diff --git a/tests/ui/impl-trait/in-ctfe/enum-discr.rs b/tests/ui/impl-trait/in-ctfe/enum-discr.rs
new file mode 100644
index 00000000000..8e4384adaa4
--- /dev/null
+++ b/tests/ui/impl-trait/in-ctfe/enum-discr.rs
@@ -0,0 +1,26 @@
+//! check that const eval can observe associated types of opaque types.
+// check-pass
+trait MyTrait: Copy {
+    const ASSOC: usize;
+}
+
+impl MyTrait for u8 {
+    const ASSOC: usize = 32;
+}
+
+const fn yeet() -> impl MyTrait {
+    0u8
+}
+
+const fn output<T: MyTrait>(_: T) -> usize {
+    <T as MyTrait>::ASSOC
+}
+
+#[repr(usize)]
+enum Foo {
+    Bar = output(yeet()),
+}
+
+fn main() {
+    println!("{}", Foo::Bar as usize);
+}
diff --git a/tests/ui/impl-trait/in-ctfe/fully_monomorphic_const_eval.rs b/tests/ui/impl-trait/in-ctfe/fully_monomorphic_const_eval.rs
new file mode 100644
index 00000000000..82a9a30a623
--- /dev/null
+++ b/tests/ui/impl-trait/in-ctfe/fully_monomorphic_const_eval.rs
@@ -0,0 +1,29 @@
+//! This test ensures that we do look at the hidden types of
+//! opaque types during const eval in order to obtain the exact type
+//! of associated types.
+
+// check-pass
+
+trait MyTrait: Copy {
+    const ASSOC: usize;
+}
+
+impl MyTrait for u8 {
+    const ASSOC: usize = 32;
+}
+
+const fn yeet() -> impl MyTrait {
+    0u8
+}
+
+const fn output<T: MyTrait>(_: T) -> usize {
+    <T as MyTrait>::ASSOC
+}
+
+struct Foo<'a>(&'a ());
+const NEED_REVEAL_ALL: usize = output(yeet());
+
+fn promote_div() -> &'static usize {
+    &(10 / NEED_REVEAL_ALL)
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs b/tests/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs
new file mode 100644
index 00000000000..8e3269726fc
--- /dev/null
+++ b/tests/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs
@@ -0,0 +1,24 @@
+//! Check that pattern matching can observe the hidden type of opaque types.
+// check-pass
+trait MyTrait: Copy {
+    const ASSOC: u8;
+}
+
+impl MyTrait for () {
+    const ASSOC: u8 = 0;
+}
+
+const fn yeet() -> impl MyTrait {}
+
+const fn output<T: MyTrait>(_: T) -> u8 {
+    <T as MyTrait>::ASSOC
+}
+
+const CT: u8 = output(yeet());
+
+fn main() {
+    match 0 {
+        CT => (),
+        1.. => (),
+    }
+}
diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.rs b/tests/ui/impl-trait/transmute/in-defining-scope.rs
new file mode 100644
index 00000000000..b0b77d60b24
--- /dev/null
+++ b/tests/ui/impl-trait/transmute/in-defining-scope.rs
@@ -0,0 +1,14 @@
+// This causes a query cycle due to using `Reveal::All`,
+// in #119821 const eval was changed to always use `Reveal::All`
+//
+// See that PR for more details.
+use std::mem::transmute;
+fn foo() -> impl Sized {
+    //~^ ERROR cycle detected when computing type of
+    unsafe {
+        transmute::<_, u8>(foo());
+    }
+    0u8
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.stderr b/tests/ui/impl-trait/transmute/in-defining-scope.stderr
new file mode 100644
index 00000000000..69812f43072
--- /dev/null
+++ b/tests/ui/impl-trait/transmute/in-defining-scope.stderr
@@ -0,0 +1,29 @@
+error[E0391]: cycle detected when computing type of `foo::{opaque#0}`
+  --> $DIR/in-defining-scope.rs:6:13
+   |
+LL | fn foo() -> impl Sized {
+   |             ^^^^^^^^^^
+   |
+note: ...which requires computing type of opaque `foo::{opaque#0}`...
+  --> $DIR/in-defining-scope.rs:6:13
+   |
+LL | fn foo() -> impl Sized {
+   |             ^^^^^^^^^^
+note: ...which requires type-checking `foo`...
+  --> $DIR/in-defining-scope.rs:6:1
+   |
+LL | fn foo() -> impl Sized {
+   | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which requires computing layout of `foo::{opaque#0}`...
+   = note: ...which requires normalizing `foo::{opaque#0}`...
+   = note: ...which again requires computing type of `foo::{opaque#0}`, completing the cycle
+note: cycle used when checking that `foo::{opaque#0}` is well-formed
+  --> $DIR/in-defining-scope.rs:6:13
+   |
+LL | fn foo() -> impl Sized {
+   |             ^^^^^^^^^^
+   = 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 1 previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/impl-trait/transmute/outside-of-defining-scope.rs b/tests/ui/impl-trait/transmute/outside-of-defining-scope.rs
new file mode 100644
index 00000000000..7bc22ea416f
--- /dev/null
+++ b/tests/ui/impl-trait/transmute/outside-of-defining-scope.rs
@@ -0,0 +1,12 @@
+//! Check that typeck can observe the size of an opaque type.
+// check-pass
+use std::mem::transmute;
+fn foo() -> impl Sized {
+    0u8
+}
+
+fn main() {
+    unsafe {
+        transmute::<_, u8>(foo());
+    }
+}
diff --git a/tests/ui/issues/issue-23302-1.stderr b/tests/ui/issues/issue-23302-1.stderr
index 5c2758dc609..53131f9130d 100644
--- a/tests/ui/issues/issue-23302-1.stderr
+++ b/tests/ui/issues/issue-23302-1.stderr
@@ -10,11 +10,15 @@ note: ...which requires const-evaluating + checking `X::A::{constant#0}`...
 LL |     A = X::A as isize,
    |         ^^^^^^^^^^^^^
    = note: ...which again requires simplifying constant for the type system `X::A::{constant#0}`, completing the cycle
-note: cycle used when simplifying constant for the type system `X::A::{constant#0}`
-  --> $DIR/issue-23302-1.rs:4:9
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-23302-1.rs:3:1
    |
-LL |     A = X::A as isize,
-   |         ^^^^^^^^^^^^^
+LL | / enum X {
+LL | |     A = X::A as isize,
+LL | | }
+LL | |
+LL | | fn main() { }
+   | |_____________^
    = 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 1 previous error
diff --git a/tests/ui/issues/issue-23302-2.stderr b/tests/ui/issues/issue-23302-2.stderr
index 93665af69dd..d55d88762be 100644
--- a/tests/ui/issues/issue-23302-2.stderr
+++ b/tests/ui/issues/issue-23302-2.stderr
@@ -10,11 +10,16 @@ note: ...which requires const-evaluating + checking `Y::A::{constant#0}`...
 LL |     A = Y::B as isize,
    |         ^^^^^^^^^^^^^
    = note: ...which again requires simplifying constant for the type system `Y::A::{constant#0}`, completing the cycle
-note: cycle used when simplifying constant for the type system `Y::A::{constant#0}`
-  --> $DIR/issue-23302-2.rs:4:9
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-23302-2.rs:3:1
    |
-LL |     A = Y::B as isize,
-   |         ^^^^^^^^^^^^^
+LL | / enum Y {
+LL | |     A = Y::B as isize,
+LL | |     B,
+LL | | }
+LL | |
+LL | | fn main() { }
+   | |_____________^
    = 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 1 previous error
diff --git a/tests/ui/issues/issue-23302-3.stderr b/tests/ui/issues/issue-23302-3.stderr
index b3e933a2171..e23957c6de7 100644
--- a/tests/ui/issues/issue-23302-3.stderr
+++ b/tests/ui/issues/issue-23302-3.stderr
@@ -20,11 +20,15 @@ note: ...which requires const-evaluating + checking `B`...
 LL | const B: i32 = A;
    |                ^
    = note: ...which again requires simplifying constant for the type system `A`, completing the cycle
-note: cycle used when simplifying constant for the type system `A`
+note: cycle used when linting top-level module
   --> $DIR/issue-23302-3.rs:1:1
    |
-LL | const A: i32 = B;
-   | ^^^^^^^^^^^^
+LL | / const A: i32 = B;
+LL | |
+LL | | const B: i32 = A;
+LL | |
+LL | | fn main() { }
+   | |_____________^
    = 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 1 previous error
diff --git a/tests/ui/recursion/recursive-static-definition.stderr b/tests/ui/recursion/recursive-static-definition.stderr
index 570d203d07f..4fc3ee68ebc 100644
--- a/tests/ui/recursion/recursive-static-definition.stderr
+++ b/tests/ui/recursion/recursive-static-definition.stderr
@@ -1,15 +1,10 @@
 error[E0391]: cycle detected when const-evaluating + checking `FOO`
-  --> $DIR/recursive-static-definition.rs:1:1
-   |
-LL | pub static FOO: u32 = FOO;
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires const-evaluating + checking `FOO`...
   --> $DIR/recursive-static-definition.rs:1:23
    |
 LL | pub static FOO: u32 = FOO;
    |                       ^^^
-   = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
+   |
+   = note: ...which immediately requires const-evaluating + checking `FOO` again
 note: cycle used when linting top-level module
   --> $DIR/recursive-static-definition.rs:1:1
    |
diff --git a/tests/ui/specialization/ctfe/default-assoc-const.rs b/tests/ui/specialization/ctfe/default-assoc-const.rs
new file mode 100644
index 00000000000..bb3b735caa3
--- /dev/null
+++ b/tests/ui/specialization/ctfe/default-assoc-const.rs
@@ -0,0 +1,18 @@
+//! Regression test for revealing associated types through specialization during const eval.
+// check-pass
+#![feature(specialization)]
+//~^ WARNING the feature `specialization` is incomplete and may not be safe to use
+
+trait Foo {
+    const ASSOC: usize;
+}
+
+impl Foo for u32 {
+    default const ASSOC: usize = 0;
+}
+
+fn foo() -> [u8; 0] {
+    [0; <u32 as Foo>::ASSOC]
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/ctfe/default-assoc-const.stderr b/tests/ui/specialization/ctfe/default-assoc-const.stderr
new file mode 100644
index 00000000000..933b6dcf8f9
--- /dev/null
+++ b/tests/ui/specialization/ctfe/default-assoc-const.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/default-assoc-const.rs:3:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/ctfe/default-assoc-type.rs b/tests/ui/specialization/ctfe/default-assoc-type.rs
new file mode 100644
index 00000000000..3624a0f160c
--- /dev/null
+++ b/tests/ui/specialization/ctfe/default-assoc-type.rs
@@ -0,0 +1,27 @@
+//! Regression test showing that we can access associated types during const eval,
+//! even if they rely on specialization.
+// check-pass
+#![feature(specialization)]
+//~^ WARNING the feature `specialization` is incomplete and may not be safe to use
+
+trait Foo {
+    type Assoc: Trait;
+}
+
+impl<T> Foo for Vec<T> {
+    default type Assoc = u32;
+}
+
+trait Trait {
+    const ASSOC: usize;
+}
+
+impl Trait for u32 {
+    const ASSOC: usize = 0;
+}
+
+fn foo() -> [u8; 0] {
+    [0; <<Vec<u32> as Foo>::Assoc as Trait>::ASSOC]
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/ctfe/default-assoc-type.stderr b/tests/ui/specialization/ctfe/default-assoc-type.stderr
new file mode 100644
index 00000000000..23fa213caff
--- /dev/null
+++ b/tests/ui/specialization/ctfe/default-assoc-type.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/default-assoc-type.rs:4:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/treat-err-as-bug/err.stderr b/tests/ui/treat-err-as-bug/err.stderr
index 4c5d0e5ae79..f1b61c3607b 100644
--- a/tests/ui/treat-err-as-bug/err.stderr
+++ b/tests/ui/treat-err-as-bug/err.stderr
@@ -8,5 +8,5 @@ error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
 #0 [eval_to_allocation_raw] const-evaluating + checking `C`
-#1 [eval_to_allocation_raw] const-evaluating + checking `C`
+#1 [lint_mod] linting top-level module
 end of query stack
diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index 94113b336c3..7f80c3cfaba 100644
--- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `Alph
 LL |     V3 = Self::V1 {} as u8 + 2,
    |          ^^^^^^^^^^^^^^^^^^^^^
    |
-note: ...which requires simplifying constant for the type system `Alpha::V3::{constant#0}`...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const-evaluating + checking `Alpha::V3::{constant#0}`...
   --> $DIR/self-in-enum-definition.rs:5:10
    |
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.rs b/tests/ui/type-alias-impl-trait/in-where-clause.rs
new file mode 100644
index 00000000000..0ad6e7a6f60
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.rs
@@ -0,0 +1,16 @@
+//! We evaluate `1 + 2` with `Reveal::All` during typeck, causing
+//! us to to get the concrete type of `Bar` while computing it.
+//! This again requires type checking `foo`.
+#![feature(type_alias_impl_trait)]
+type Bar = impl Sized;
+//~^ ERROR: cycle
+//~| ERROR: cycle
+
+fn foo() -> Bar
+where
+    Bar: Send,
+{
+    [0; 1 + 2]
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
new file mode 100644
index 00000000000..9c08b8f127d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
@@ -0,0 +1,50 @@
+error[E0391]: cycle detected when computing type of `Bar::{opaque#0}`
+  --> $DIR/in-where-clause.rs:5:12
+   |
+LL | type Bar = impl Sized;
+   |            ^^^^^^^^^^
+   |
+note: ...which requires computing type of opaque `Bar::{opaque#0}`...
+  --> $DIR/in-where-clause.rs:5:12
+   |
+LL | type Bar = impl Sized;
+   |            ^^^^^^^^^^
+note: ...which requires type-checking `foo`...
+  --> $DIR/in-where-clause.rs:9:1
+   |
+LL | / fn foo() -> Bar
+LL | | where
+LL | |     Bar: Send,
+   | |______________^
+   = note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(<Bar as core::marker::Send>, polarity:Positive), bound_vars: [] }]`...
+   = note: ...which again requires computing type of `Bar::{opaque#0}`, completing the cycle
+note: cycle used when checking that `Bar::{opaque#0}` is well-formed
+  --> $DIR/in-where-clause.rs:5:12
+   |
+LL | type Bar = impl Sized;
+   |            ^^^^^^^^^^
+   = 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[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
+  --> $DIR/in-where-clause.rs:5:12
+   |
+LL | type Bar = impl Sized;
+   |            ^^^^^^^^^^
+   |
+note: ...which requires type-checking `foo`...
+  --> $DIR/in-where-clause.rs:13:9
+   |
+LL |     [0; 1 + 2]
+   |         ^^^^^
+   = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Send`...
+   = note: ...which again requires computing type of opaque `Bar::{opaque#0}`, completing the cycle
+note: cycle used when computing type of `Bar::{opaque#0}`
+  --> $DIR/in-where-clause.rs:5:12
+   |
+LL | type Bar = impl Sized;
+   |            ^^^^^^^^^^
+   = 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 2 previous errors
+
+For more information about this error, try `rustc --explain E0391`.