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 9d22df50d4f34..4236117d75b91 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 092b59deeff36..b20df1b23434e 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 21062fdaf5859..88b17be601ceb 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 e4abf6203e8f2..fd1b4f2f964b0 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 = ::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 = ::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 05ebd76f50012..303400f928e65 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 = ::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 = ::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 c748af608d1e6..2fcb3d41dd927 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 a5679400c2f0e..cd0ea55642545 100644 --- a/tests/ui/consts/const-size_of-cycle.stderr +++ b/tests/ui/consts/const-size_of-cycle.stderr @@ -7,11 +7,6 @@ LL | bytes: [u8; std::mem::size_of::()] 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::()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -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::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr index 4f2d92ba3cde0..de70a457f16f2 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 adb5747c42408..641945fce9fd4 100644 --- a/tests/ui/consts/issue-44415.stderr +++ b/tests/ui/consts/issue-44415.stderr @@ -7,11 +7,6 @@ LL | bytes: [u8; unsafe { intrinsics::size_of::() }], note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... --> $DIR/issue-44415.rs:6:17 | -LL | bytes: [u8; unsafe { intrinsics::size_of::() }], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... - --> $DIR/issue-44415.rs:6:17 - | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr index 3bbb685a67819..5b4a0418b1e9a 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 3bbb685a67819..5b4a0418b1e9a 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 5665e56439e01..caee433a6813a 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 0000000000000..01ba902ef0c0d --- /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; size_of_fut(returns_opaque)], +} + +const fn size_of_fut(x: fn() -> FUT) -> usize { + mem::size_of::() +} + +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 0000000000000..73ae20495d577 --- /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) -> usize { + ::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 0000000000000..8e4384adaa4cb --- /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) -> usize { + ::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 0000000000000..82a9a30a62362 --- /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) -> usize { + ::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 0000000000000..8e3269726fc4a --- /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) -> u8 { + ::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 0000000000000..b0b77d60b245e --- /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 0000000000000..69812f43072b0 --- /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 0000000000000..7bc22ea416f06 --- /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 5c2758dc60900..53131f9130d9c 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 93665af69dd8d..d55d88762be43 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 b3e933a21718e..e23957c6de754 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 570d203d07f7c..4fc3ee68ebc29 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 0000000000000..bb3b735caa312 --- /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; ::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 0000000000000..933b6dcf8f998 --- /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 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 0000000000000..3624a0f160c5e --- /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 Foo for Vec { + default type Assoc = u32; +} + +trait Trait { + const ASSOC: usize; +} + +impl Trait for u32 { + const ASSOC: usize = 0; +} + +fn foo() -> [u8; 0] { + [0; < 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 0000000000000..23fa213caffb3 --- /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 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 4c5d0e5ae7987..f1b61c3607b77 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 94113b336c330..7f80c3cfaba44 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 0000000000000..0ad6e7a6f6014 --- /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 0000000000000..9c08b8f127d27 --- /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(, 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`.