From 9d843171d10b4b3f0847cc45933cfca8f99a4c63 Mon Sep 17 00:00:00 2001 From: b-naber Date: Wed, 16 Feb 2022 10:56:01 +0100 Subject: [PATCH 1/9] bless tests --- Cargo.lock | 1 + ...allocation2.main.ConstProp.after.64bit.mir | 32 +++---- ..._line_doc_comment_2.DeduplicateBlocks.diff | 2 +- .../inline/inline_diverging.g.Inline.diff | 2 +- ...line_into_box_place.main.Inline.64bit.diff | 9 +- ...ue_59352.num_to_digit.PreCodegen.after.mir | 2 +- ...age_markers.main.RemoveStorageMarkers.diff | 2 +- .../associated-consts/defaults-cyclic-fail.rs | 1 + .../defaults-cyclic-fail.stderr | 28 +----- ...-assoc-const-static-recursion-trait.stderr | 7 +- .../borrowck/issue-88434-minimal-example.rs | 2 + .../issue-88434-minimal-example.stderr | 20 +++- ...ssue-88434-removal-index-should-be-less.rs | 2 + ...-88434-removal-index-should-be-less.stderr | 20 +++- .../ui/const-ptr/out_of_bounds_read.stderr | 6 +- .../const-eval/const-eval-query-stack.rs | 2 + .../const-eval/const-eval-query-stack.stderr | 17 +++- src/test/ui/consts/const-integer-bool-ops.rs | 10 ++ .../ui/consts/const-integer-bool-ops.stderr | 95 +++++++++++++++---- .../const-mut-refs/issue-76510.64bit.stderr | 12 ++- .../ui/consts/const-mut-refs/issue-76510.rs | 1 + src/test/ui/consts/const-tup-index-span.rs | 1 + .../ui/consts/const-tup-index-span.stderr | 11 ++- src/test/ui/consts/invalid-union.64bit.stderr | 2 +- src/test/ui/consts/issue-36163.stderr | 40 ++------ src/test/ui/issues/issue-17252.stderr | 15 +-- src/test/ui/issues/issue-23302-1.stderr | 17 +--- src/test/ui/issues/issue-23302-2.stderr | 17 +--- src/test/ui/issues/issue-23302-3.stderr | 30 ++---- src/test/ui/issues/issue-41394.rs | 1 + src/test/ui/issues/issue-41394.stderr | 11 ++- src/test/ui/issues/issue-54954.rs | 2 + src/test/ui/issues/issue-54954.stderr | 18 +++- ...issue-69602-type-err-during-codegen-ice.rs | 1 + ...e-69602-type-err-during-codegen-ice.stderr | 10 +- src/test/ui/issues/issue-77919.rs | 1 + src/test/ui/issues/issue-77919.stderr | 16 +++- src/test/ui/resolve/issue-50599.rs | 1 + src/test/ui/resolve/issue-50599.stderr | 11 ++- .../ui/type/type-dependent-def-issue-49241.rs | 1 + .../type-dependent-def-issue-49241.stderr | 11 ++- 41 files changed, 286 insertions(+), 204 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80f0a0b8b5ba3..3f6831f3f765b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2327,6 +2327,7 @@ dependencies = [ "compiletest_rs", "env_logger 0.9.0", "getrandom 0.2.0", + "hex 0.4.2", "libc", "log", "measureme 9.1.2", diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir index ef651f01c9b98..e2acd610b8053 100644 --- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir @@ -21,44 +21,44 @@ fn main() -> () { } alloc1 (static: FOO, size: 16, align: 8) { - ╾───────alloc28───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾───────alloc22───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc28 (size: 72, align: 8) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc13───────╼ │ ....░░░░╾──────╼ +alloc22 (size: 72, align: 8) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc9────────╼ │ ....░░░░╾──────╼ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ - 0x20 │ ╾───────alloc18───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc26───────╼ │ ....*...╾──────╼ + 0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc20───────╼ │ ....*...╾──────╼ 0x40 │ 03 00 00 00 00 00 00 00 │ ........ } -alloc13 (size: 0, align: 8) {} +alloc9 (size: 0, align: 8) {} -alloc18 (size: 16, align: 8) { - ╾───────alloc16───────╼ ╾───────alloc17───────╼ │ ╾──────╼╾──────╼ +alloc14 (size: 16, align: 8) { + ╾───────alloc12───────╼ ╾───────alloc13───────╼ │ ╾──────╼╾──────╼ } -alloc16 (size: 1, align: 1) { +alloc12 (size: 1, align: 1) { 05 │ . } -alloc17 (size: 1, align: 1) { +alloc13 (size: 1, align: 1) { 06 │ . } -alloc26 (size: 24, align: 8) { - 0x00 │ ╾─────alloc22+0x3─────╼ ╾───────alloc23───────╼ │ ╾──────╼╾──────╼ - 0x10 │ ╾─────alloc25+0x2─────╼ │ ╾──────╼ +alloc20 (size: 24, align: 8) { + 0x00 │ ╾─────alloc17+0x3─────╼ ╾───────alloc18───────╼ │ ╾──────╼╾──────╼ + 0x10 │ ╾─────alloc19+0x2─────╼ │ ╾──────╼ } -alloc22 (size: 4, align: 1) { +alloc17 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } -alloc23 (size: 1, align: 1) { +alloc18 (size: 1, align: 1) { 2a │ * } -alloc25 (size: 4, align: 1) { +alloc19 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } diff --git a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff index 372b14eb7c92a..122bef522cf4d 100644 --- a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff +++ b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff @@ -26,7 +26,7 @@ - _2 = transmute::<&str, &[u8]>(move _8) -> bb14; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL + _2 = transmute::<&str, &[u8]>(move _8) -> bb12; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL // mir::Constant - // + span: $SRC_DIR/core/src/str/mod.rs:LL:COL + // + span: $DIR/deduplicate_blocks.rs:3:11: 3:23 // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&str) -> &[u8] {transmute::<&str, &[u8]>}, val: Value(Scalar()) } } diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index 3b9d5e727b8a3..cb79cdd3579ea 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -39,7 +39,7 @@ // mir::Constant - // + span: $DIR/inline-diverging.rs:16:9: 16:14 - // + literal: Const { ty: fn() -> ! {panic}, val: Value(Scalar()) } -+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL ++ // + span: $DIR/inline-diverging.rs:16:9: 16:16 + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(Scalar()) } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff index 0f83b0c4a27ad..ed4a8602a2413 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff @@ -34,7 +34,10 @@ - (*_5) = Vec::::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + _7 = &mut (*_5); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 -+ ((*_7).0: alloc::raw_vec::RawVec) = const alloc::raw_vec::RawVec:: { ptr: Unique:: { pointer: {0x4 as *const u32}, _marker: PhantomData:: }, cap: 0_usize, alloc: std::alloc::Global }; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_7).0: alloc::raw_vec::RawVec) = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ // ty::Const ++ // + ty: alloc::raw_vec::RawVec ++ // + val: Unevaluated(alloc::raw_vec::RawVec::::NEW, [u32], None) // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 - // + user_ty: UserType(1) @@ -44,8 +47,8 @@ - bb2: { + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // + user_ty: UserType(0) -+ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } -+ ((*_7).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(5:77 ~ alloc[25db]::raw_vec::{impl#0}::NEW), const_param_did: None }, substs: [u32], promoted: None }) } ++ ((*_7).1: usize) = const 0_usize; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43 + StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index e2051c85af215..c5c063e8cecf1 100644 --- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -38,7 +38,7 @@ fn num_to_digit(_1: char) -> u32 { _8 = _2; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL _7 = char::methods::::to_digit(move _8, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL // mir::Constant - // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL + // + span: $DIR/issue-59352.rs:14:8: 14:23 // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value(Scalar()) } } diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff index 312031b7a0ff4..ec76424afa55e 100644 --- a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff +++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff @@ -58,7 +58,7 @@ _14 = &mut (*_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL _7 = as iter::range::RangeIteratorImpl>::spec_next(move _14) -> bb4; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL // mir::Constant - // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + span: $DIR/remove_storage_markers.rs:8:14: 8:19 // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range) -> Option< as iter::range::RangeIteratorImpl>::Item> { as iter::range::RangeIteratorImpl>::spec_next}, val: Value(Scalar()) } } diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.rs b/src/test/ui/associated-consts/defaults-cyclic-fail.rs index 2f1858d39b3c6..6c1c68b9f2931 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.rs +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.rs @@ -4,6 +4,7 @@ // Cyclic assoc. const defaults don't error unless *used* trait Tr { const A: u8 = Self::B; + //~^ ERROR cycle detected when const-evaluating + checking `Tr::A` const B: u8 = Self::A; } diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr index 3fb4ab72fe6d6..550897790e9ff 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr @@ -1,37 +1,15 @@ -error[E0391]: cycle detected when normalizing `<() as Tr>::A` - | -note: ...which requires simplifying constant for the type system `Tr::A`... - --> $DIR/defaults-cyclic-fail.rs:6:5 - | -LL | const A: u8 = Self::B; - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `Tr::A`... - --> $DIR/defaults-cyclic-fail.rs:6:5 - | -LL | const A: u8 = Self::B; - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `Tr::A`... - --> $DIR/defaults-cyclic-fail.rs:6:5 +error[E0391]: cycle detected when const-evaluating + checking `Tr::A` + --> $DIR/defaults-cyclic-fail.rs:5:5 | LL | const A: u8 = Self::B; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires normalizing `<() as Tr>::B`... -note: ...which requires simplifying constant for the type system `Tr::B`... - --> $DIR/defaults-cyclic-fail.rs:8:5 | -LL | const B: u8 = Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `Tr::B`... - --> $DIR/defaults-cyclic-fail.rs:8:5 - | -LL | const B: u8 = Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Tr::B`... --> $DIR/defaults-cyclic-fail.rs:8:5 | LL | const B: u8 = Self::A; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires normalizing `<() as Tr>::A`, completing the cycle + = note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle note: cycle used when const-evaluating + checking `main::promoted[1]` --> $DIR/defaults-cyclic-fail.rs:14:1 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 020d758e153c2..bf8412f3e770c 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -6,10 +6,6 @@ LL | const BAR: u32 = TRAIT_REF_BAR; | = note: ...which requires normalizing `TRAIT_REF_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 simplifying constant for the type system `TRAIT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | @@ -31,6 +27,9 @@ note: ...which requires simplifying constant for the type system `>>>>>> 53eca42efca (bless tests) note: ...which requires const-evaluating + checking `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.rs b/src/test/ui/borrowck/issue-88434-minimal-example.rs index 632f8dc3ad6f5..90baca253d268 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.rs +++ b/src/test/ui/borrowck/issue-88434-minimal-example.rs @@ -1,6 +1,8 @@ // Regression test related to issue 88434 const _CONST: &() = &f(&|_| {}); +//~^ ERROR any use of this value will cause an error +//~| WARNING this was previously accepted by the compiler but is being phased out const fn f(_: &F) where diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr index d9635e1ee464c..1af7c606b7185 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr +++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-minimal-example.rs:9:5 + --> $DIR/issue-88434-minimal-example.rs:12:5 | LL | const _CONST: &() = &f(&|_| {}); | ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:3:22 @@ -7,11 +7,23 @@ LL | const _CONST: &() = &f(&|_| {}); LL | panic!() | ^^^^^^^^ | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:9:5 - | inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:31]>` at $SRC_DIR/std/src/panic.rs:LL:COL + | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:12:5 + | inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:4:25: 4:31]>` at $SRC_DIR/std/src/panic.rs:LL:COL | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: any use of this value will cause an error + --> $DIR/issue-88434-minimal-example.rs:4:21 + | +LL | const _CONST: &() = &f(&|_| {}); + | --------------------^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs index f0a6dcd4eb3b8..b1fc1615ece77 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs @@ -1,6 +1,8 @@ // Regression test for issue 88434 const _CONST: &[u8] = &f(&[], |_| {}); +//~^ ERROR any use of this value will cause an error +//~| WARNING this was previously const fn f(_: &[u8], _: F) -> &[u8] where diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index 44e244ae9cc3f..f2a381a73ef49 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-removal-index-should-be-less.rs:9:5 + --> $DIR/issue-88434-removal-index-should-be-less.rs:12:5 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:3:24 @@ -7,11 +7,23 @@ LL | const _CONST: &[u8] = &f(&[], |_| {}); LL | panic!() | ^^^^^^^^ | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:9:5 - | inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL + | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:12:5 + | inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:4:31: 4:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: any use of this value will cause an error + --> $DIR/issue-88434-removal-index-should-be-less.rs:4:23 + | +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ----------------------^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr index 678714d0e055a..52b173c4d04a8 100644 --- a/src/test/ui/const-ptr/out_of_bounds_read.stderr +++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | memory access failed: alloc7 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL | ::: $DIR/out_of_bounds_read.rs:12:33 @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | memory access failed: alloc7 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL | ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -37,7 +37,7 @@ error[E0080]: evaluation of constant value failed LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | memory access failed: alloc7 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL | ::: $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.rs b/src/test/ui/consts/const-eval/const-eval-query-stack.rs index e73e54ff5f1b3..8412fefcb658f 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.rs +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.rs @@ -23,5 +23,7 @@ const X: i32 = 1 / 0; //~WARN any use of this value will cause an error fn main() { let x: &'static i32 = &X; //~^ ERROR evaluation of constant value failed + //~| ERROR erroneous constant used + //~| WARNING this was previously accepted by the compiler println!("x={}", x); } diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 8bd5c08dc4649..2de2ef181babd 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -1,5 +1,5 @@ warning: any use of this value will cause an error - --> $DIR/const-eval-query-stack.rs:20:16 + --> $DIR/const-eval-query-stack.rs:19:16 | LL | const X: i32 = 1 / 0; | ---------------^^^^^- @@ -7,7 +7,7 @@ LL | const X: i32 = 1 / 0; | attempt to divide `1_i32` by zero | note: the lint level is defined here - --> $DIR/const-eval-query-stack.rs:19:8 + --> $DIR/const-eval-query-stack.rs:18:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -15,10 +15,21 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error[E0080]: evaluation of constant value failed - --> $DIR/const-eval-query-stack.rs:24:28 + --> $DIR/const-eval-query-stack.rs:23:28 | LL | let x: &'static i32 = &X; | ^ referenced constant has errors + +error: erroneous constant used + --> $DIR/const-eval-query-stack.rs:23:27 + | +LL | let x: &'static i32 = &X; + | ^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + query stack during panic: #0 [try_normalize_mir_const_after_erasing_regions] normalizing `main::promoted[1]` #1 [mir_drops_elaborated_and_const_checked] elaborating drops for `main` diff --git a/src/test/ui/consts/const-integer-bool-ops.rs b/src/test/ui/consts/const-integer-bool-ops.rs index 35915a7a606a4..6924956bdf706 100644 --- a/src/test/ui/consts/const-integer-bool-ops.rs +++ b/src/test/ui/consts/const-integer-bool-ops.rs @@ -6,6 +6,7 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; +//~^ ERROR evaluation of constant value failed const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -15,6 +16,7 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; +//~^ ERROR evaluation of constant value failed const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -24,6 +26,7 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; +//~^ ERROR evaluation of constant value failed const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -33,36 +36,43 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; +//~^ ERROR evaluation of constant value failed const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; +//~^ ERROR evaluation of constant value failed const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; +//~^ ERROR evaluation of constant value failed const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; +//~^ ERROR evaluation of constant value failed const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; +//~^ ERROR evaluation of constant value failed const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; +//~^ ERROR evaluation of constant value failed const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; +//~^ ERROR evaluation of constant value failed fn main() { let _ = ARR; diff --git a/src/test/ui/consts/const-integer-bool-ops.stderr b/src/test/ui/consts/const-integer-bool-ops.stderr index 4e503e5a5c0a4..9001fefd1029f 100644 --- a/src/test/ui/consts/const-integer-bool-ops.stderr +++ b/src/test/ui/consts/const-integer-bool-ops.stderr @@ -16,96 +16,157 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:8:18 + | +LL | const ARR: [i32; X] = [99; 34]; + | ^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:10:19 + --> $DIR/const-integer-bool-ops.rs:11:19 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:10:25 + --> $DIR/const-integer-bool-ops.rs:11:25 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:10:19 + --> $DIR/const-integer-bool-ops.rs:11:19 | LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:18:19 + | +LL | const ARR1: [i32; X1] = [99; 47]; + | ^^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:19:19 + --> $DIR/const-integer-bool-ops.rs:21:19 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:19:26 + --> $DIR/const-integer-bool-ops.rs:21:26 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:19:19 + --> $DIR/const-integer-bool-ops.rs:21:19 | LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0308]: mismatched types +error[E0080]: evaluation of constant value failed --> $DIR/const-integer-bool-ops.rs:28:19 | +LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; + | ^^ referenced constant has errors + +error[E0308]: mismatched types + --> $DIR/const-integer-bool-ops.rs:31:19 + | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:28:26 + --> $DIR/const-integer-bool-ops.rs:31:26 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:28:19 + --> $DIR/const-integer-bool-ops.rs:31:19 | LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:38:19 + | +LL | const ARR3: [i32; X3] = [99; 6]; + | ^^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:37:18 + --> $DIR/const-integer-bool-ops.rs:41:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:44:19 + | +LL | const ARRR: [i32; Y] = [99; 1]; + | ^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:42:19 + --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:50:20 + | +LL | const ARRR1: [i32; Y1] = [99; 1]; + | ^^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:47:19 + --> $DIR/const-integer-bool-ops.rs:53:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:56:20 + | +LL | const ARRR2: [i32; Y2] = [99; 1]; + | ^^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:52:19 + --> $DIR/const-integer-bool-ops.rs:59:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:62:20 + | +LL | const ARRR3: [i32; Y3] = [99; 0]; + | ^^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:57:19 + --> $DIR/const-integer-bool-ops.rs:65:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:68:20 + | +LL | const ARRR4: [i32; Y4] = [99; 0]; + | ^^ referenced constant has errors + error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:62:19 + --> $DIR/const-integer-bool-ops.rs:71:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error: aborting due to 18 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/const-integer-bool-ops.rs:74:20 + | +LL | const ARRR5: [i32; Y5] = [99; 0]; + | ^^ referenced constant has errors + +error: aborting due to 28 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0080, E0308. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr index 61b00be345fee..0f420ae1b6b7c 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr +++ b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -19,7 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -error: aborting due to 3 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/issue-76510.rs:11:70 + | +LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); + | ^ referenced constant has errors + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0596, E0658, E0764. -For more information about an error, try `rustc --explain E0596`. +Some errors have detailed explanations: E0080, E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.rs b/src/test/ui/consts/const-mut-refs/issue-76510.rs index 143d2fb6b9a3a..08cf64ee330db 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.rs +++ b/src/test/ui/consts/const-mut-refs/issue-76510.rs @@ -9,6 +9,7 @@ const S: &'static mut str = &mut " hello "; const fn trigger() -> [(); unsafe { let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); + //~^ ERROR evaluation of constant value failed 0 }] { [(); 0] diff --git a/src/test/ui/consts/const-tup-index-span.rs b/src/test/ui/consts/const-tup-index-span.rs index 8057d64369a23..763263c6aeb4f 100644 --- a/src/test/ui/consts/const-tup-index-span.rs +++ b/src/test/ui/consts/const-tup-index-span.rs @@ -4,6 +4,7 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected tuple, found `usize` const ARR: [i32; TUP.0] = []; +//~^ ERROR evaluation of constant value failed fn main() { } diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr index d301f8c4054c2..b178e05e27a09 100644 --- a/src/test/ui/consts/const-tup-index-span.stderr +++ b/src/test/ui/consts/const-tup-index-span.stderr @@ -11,6 +11,13 @@ help: use a trailing comma to create a tuple with one element LL | const TUP: (usize,) = (5usize << 64,); | + ++ -error: aborting due to previous error +error[E0080]: evaluation of constant value failed + --> $DIR/const-tup-index-span.rs:6:18 + | +LL | const ARR: [i32; TUP.0] = []; + | ^^^ referenced constant has errors + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0080, E0308. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index 6bfa97a2fded7..3e89d7c0e489f 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -6,7 +6,7 @@ LL | fn main() { | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc7────────╼ │ ╾──────╼ + ╾───────alloc6────────╼ │ ╾──────╼ } error: erroneous constant used diff --git a/src/test/ui/consts/issue-36163.stderr b/src/test/ui/consts/issue-36163.stderr index 113f86cf0f99f..9ac6c984cb0cd 100644 --- a/src/test/ui/consts/issue-36163.stderr +++ b/src/test/ui/consts/issue-36163.stderr @@ -1,48 +1,20 @@ -error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}` +error[E0391]: cycle detected when const-evaluating + checking `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | -note: ...which requires simplifying constant for the type system `Foo::B::{constant#0}`... - --> $DIR/issue-36163.rs:4:9 - | -LL | B = A, - | ^ -note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`... - --> $DIR/issue-36163.rs:4:9 - | -LL | B = A, - | ^ - = note: ...which requires normalizing `A`... -note: ...which requires simplifying constant for the type system `A`... - --> $DIR/issue-36163.rs:1:1 - | -LL | const A: isize = Foo::B as isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `A`... - --> $DIR/issue-36163.rs:1:1 - | -LL | const A: isize = Foo::B as isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-36163.rs:1:1 | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires normalizing `A`... - = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/issue-36163.rs:1:1 + = note: ...which again requires const-evaluating + checking `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 | -LL | / const A: isize = Foo::B as isize; -LL | | -LL | | enum Foo { -LL | | B = A, -LL | | } -LL | | -LL | | fn main() {} - | |____________^ +LL | B = A, + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index 1148577016ab4..4856418ed6002 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -1,21 +1,10 @@ -error[E0391]: cycle detected when normalizing `FOO` - | -note: ...which requires simplifying constant for the type system `FOO`... - --> $DIR/issue-17252.rs:1:1 - | -LL | const FOO: usize = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `FOO`... +error[E0391]: cycle detected when const-evaluating + checking `FOO` --> $DIR/issue-17252.rs:1:1 | LL | const FOO: usize = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `FOO`... - --> $DIR/issue-17252.rs:1:1 | -LL | const FOO: usize = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires normalizing `FOO`, completing the cycle + = note: ...which immediately requires const-evaluating + checking `FOO` again note: cycle used when const-evaluating + checking `main::{constant#0}` --> $DIR/issue-17252.rs:4:18 | diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index d3a1993536a00..9366050d7ecdf 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -1,26 +1,15 @@ -error[E0391]: cycle detected when simplifying constant for the type system `X::A::{constant#0}` +error[E0391]: cycle detected when const-evaluating + checking `X::A::{constant#0}` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `X::A::{constant#0}`... + = note: ...which immediately requires const-evaluating + checking `X::A::{constant#0}` again +note: cycle used when simplifying constant for the type system `X::A::{constant#0}` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `X::A::{constant#0}`... - --> $DIR/issue-23302-1.rs:4:9 - | -LL | A = X::A as isize, - | ^^^^^^^^^^^^^ - = note: ...which requires normalizing `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 collecting item types in top-level module - --> $DIR/issue-23302-1.rs:3:1 - | -LL | enum X { - | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index d3b78ea1af5f5..b97ae287a47a9 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -1,26 +1,15 @@ -error[E0391]: cycle detected when simplifying constant for the type system `Y::A::{constant#0}` +error[E0391]: cycle detected when const-evaluating + checking `Y::A::{constant#0}` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `Y::A::{constant#0}`... + = note: ...which immediately requires const-evaluating + checking `Y::A::{constant#0}` again +note: cycle used when simplifying constant for the type system `Y::A::{constant#0}` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `Y::A::{constant#0}`... - --> $DIR/issue-23302-2.rs:4:9 - | -LL | A = Y::B as isize, - | ^^^^^^^^^^^^^ - = note: ...which requires normalizing `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 collecting item types in top-level module - --> $DIR/issue-23302-2.rs:3:1 - | -LL | enum Y { - | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index 5233b832ecc79..1a07d4a95bcfa 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -1,38 +1,20 @@ -error[E0391]: cycle detected when simplifying constant for the type system `A` +error[E0391]: cycle detected when const-evaluating + checking `A` --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `A`... - --> $DIR/issue-23302-3.rs:1:1 - | -LL | const A: i32 = B; - | ^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `A`... - --> $DIR/issue-23302-3.rs:1:1 - | -LL | const A: i32 = B; - | ^^^^^^^^^^^^^^^^^ - = note: ...which requires normalizing `B`... -note: ...which requires simplifying constant for the type system `B`... - --> $DIR/issue-23302-3.rs:3:1 - | -LL | const B: i32 = A; - | ^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `B`... +note: ...which requires const-evaluating + checking `B`... --> $DIR/issue-23302-3.rs:3:1 | LL | const B: i32 = A; | ^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `B`... - --> $DIR/issue-23302-3.rs:3:1 + = note: ...which again requires const-evaluating + checking `A`, completing the cycle +note: cycle used when simplifying constant for the type system `A` + --> $DIR/issue-23302-3.rs:1:1 | -LL | const B: i32 = A; +LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ - = note: ...which requires normalizing `A`... - = note: ...which again requires simplifying constant for the type system `A`, completing the cycle - = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-41394.rs b/src/test/ui/issues/issue-41394.rs index 06a330813406a..64873ac35a002 100644 --- a/src/test/ui/issues/issue-41394.rs +++ b/src/test/ui/issues/issue-41394.rs @@ -5,6 +5,7 @@ enum Foo { enum Bar { A = Foo::A as isize + //~^ ERROR evaluation of constant value failed } fn main() {} diff --git a/src/test/ui/issues/issue-41394.stderr b/src/test/ui/issues/issue-41394.stderr index fa95ca9c18a10..47a24547d4533 100644 --- a/src/test/ui/issues/issue-41394.stderr +++ b/src/test/ui/issues/issue-41394.stderr @@ -6,6 +6,13 @@ LL | A = "" + 1 | | | &str -error: aborting due to previous error +error[E0080]: evaluation of constant value failed + --> $DIR/issue-41394.rs:7:9 + | +LL | A = Foo::A as isize + | ^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0369`. +Some errors have detailed explanations: E0080, E0369. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs index 42a4d5b674b22..ddd3914154147 100644 --- a/src/test/ui/issues/issue-54954.rs +++ b/src/test/ui/issues/issue-54954.rs @@ -9,6 +9,8 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + //~^ ERROR evaluation of constant value failed + //~| ERROR evaluation of constant value failed z } diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr index efe2ef504a2ba..6e8d3cac9a7e4 100644 --- a/src/test/ui/issues/issue-54954.stderr +++ b/src/test/ui/issues/issue-54954.stderr @@ -12,7 +12,19 @@ LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); | = note: cannot satisfy `_: Tt` -error: aborting due to 2 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/issue-54954.rs:11:15 + | +LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + | ^^^^^^^ referenced constant has errors + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-54954.rs:11:34 + | +LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + | ^^^^^^^ referenced constant has errors + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0283, E0379. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0080, E0283, E0379. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs index 2c5257ce063cb..6851b67cb3b3a 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs @@ -19,4 +19,5 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` fn main() { let _ = [0; B::VALUE]; + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr index 8ae0f8b804c93..cb5b397849c06 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr @@ -13,7 +13,13 @@ LL | type MyA: TraitA; LL | impl TraitB for B { | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation -error: aborting due to 2 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 + | +LL | let _ = [0; B::VALUE]; + | ^^^^^^^^ referenced constant has errors + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0046, E0437. +Some errors have detailed explanations: E0046, E0080, E0437. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index 966d76d148af3..c2946ad94b0b7 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,5 +1,6 @@ fn main() { [1; >::VAL]; + //~^ ERROR evaluation of constant value failed } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index 97bd5ab36b65d..8d5d6cb037749 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:9:9 + --> $DIR/issue-77919.rs:10:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:11:63 + --> $DIR/issue-77919.rs:12:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:11:1 + --> $DIR/issue-77919.rs:12:1 | LL | const VAL: T; | ------------- `VAL` from trait @@ -26,7 +26,13 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: aborting due to 3 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/issue-77919.rs:2:9 + | +LL | [1; >::VAL]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0046, E0412. +Some errors have detailed explanations: E0046, E0080, E0412. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/resolve/issue-50599.rs b/src/test/ui/resolve/issue-50599.rs index 00588735b9a59..78a20cf8ebb05 100644 --- a/src/test/ui/resolve/issue-50599.rs +++ b/src/test/ui/resolve/issue-50599.rs @@ -2,4 +2,5 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/resolve/issue-50599.stderr b/src/test/ui/resolve/issue-50599.stderr index 7ec567a06f09d..effa16e55e54e 100644 --- a/src/test/ui/resolve/issue-50599.stderr +++ b/src/test/ui/resolve/issue-50599.stderr @@ -11,6 +11,13 @@ LL | use std::f32::consts::LOG10_2; LL | use std::f64::consts::LOG10_2; | -error: aborting due to previous error +error[E0080]: evaluation of constant value failed + --> $DIR/issue-50599.rs:4:29 + | +LL | let mut digits = [0u32; M]; + | ^ referenced constant has errors + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0080, E0425. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index 4b6bc6124dbf3..51bd116fbd61c 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -2,4 +2,5 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 64c7687f7a882..02f267c6c8d73 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -6,6 +6,13 @@ LL | const l: usize = v.count(); | | | help: consider using `let` instead of `const`: `let l` -error: aborting due to previous error +error[E0080]: evaluation of constant value failed + --> $DIR/type-dependent-def-issue-49241.rs:4:18 + | +LL | let s: [u32; l] = v.into_iter().collect(); + | ^ referenced constant has errors + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0435`. +Some errors have detailed explanations: E0080, E0435. +For more information about an error, try `rustc --explain E0080`. From b38077ea0b9021cf69401289f23951f96d996129 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 21 Feb 2022 22:43:15 +0100 Subject: [PATCH 2/9] change thir to use mir::ConstantKind instead of ty::Const --- Cargo.lock | 1 - .../rustc_const_eval/src/const_eval/mod.rs | 70 ++++++ compiler/rustc_const_eval/src/lib.rs | 8 + compiler/rustc_middle/src/mir/mod.rs | 210 +++++++++++++++++- compiler/rustc_middle/src/mir/query.rs | 9 +- compiler/rustc_middle/src/query/mod.rs | 20 ++ compiler/rustc_middle/src/thir.rs | 16 +- .../rustc_middle/src/thir/abstract_const.rs | 2 +- compiler/rustc_middle/src/thir/visit.rs | 9 + compiler/rustc_middle/src/ty/consts/kind.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 14 +- compiler/rustc_mir_build/src/build/cfg.rs | 2 +- .../src/build/expr/as_constant.rs | 3 + .../src/build/expr/as_rvalue.rs | 6 +- .../rustc_mir_build/src/build/matches/mod.rs | 4 +- .../src/build/matches/simplify.rs | 4 +- .../rustc_mir_build/src/build/matches/test.rs | 17 +- compiler/rustc_mir_build/src/build/misc.rs | 5 +- compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_mir_build/src/thir/constant.rs | 1 + compiler/rustc_mir_build/src/thir/cx/expr.rs | 5 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 20 ++ .../src/thir/pattern/const_to_pat.rs | 30 +-- .../src/thir/pattern/deconstruct_pat.rs | 38 ++-- .../rustc_mir_build/src/thir/pattern/mod.rs | 69 +++--- compiler/rustc_privacy/src/lib.rs | 8 +- .../src/traits/const_evaluatable.rs | 64 +++++- .../src/traits/fulfill.rs | 2 +- .../src/traits/object_safety.rs | 6 +- 29 files changed, 534 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f6831f3f765b..80f0a0b8b5ba3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2327,7 +2327,6 @@ dependencies = [ "compiletest_rs", "env_logger 0.9.0", "getrandom 0.2.0", - "hex 0.4.2", "libc", "log", "measureme 9.1.2", diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 6fd7f707e7e5d..d321dc28d8568 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -172,6 +172,40 @@ pub(crate) fn try_destructure_const<'tcx>( Ok(mir::DestructuredConst { variant, fields }) } +pub(crate) fn destructure_mir_constant<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + val: mir::ConstantKind<'tcx>, +) -> mir::DestructuredMirConstant<'tcx> { + trace!("destructure_const: {:?}", val); + let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); + let op = ecx.mir_const_to_op(&val, None).unwrap(); + + // We go to `usize` as we cannot allocate anything bigger anyway. + let (field_count, variant, down) = match val.ty().kind() { + ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op), + ty::Adt(def, _) if def.variants.is_empty() => { + return mir::DestructuredMirConstant { variant: None, fields: &[] }; + } + ty::Adt(def, _) => { + let variant = ecx.read_discriminant(&op).unwrap().1; + let down = ecx.operand_downcast(&op, variant).unwrap(); + (def.variants[variant].fields.len(), Some(variant), down) + } + ty::Tuple(substs) => (substs.len(), None, op), + _ => bug!("cannot destructure constant {:?}", val), + }; + + let fields_iter = (0..field_count).map(|i| { + let field_op = ecx.operand_field(&down, i).unwrap(); + let val = op_to_const(&ecx, &field_op); + mir::ConstantKind::Val(val, field_op.layout.ty) + }); + let fields = tcx.arena.alloc_from_iter(fields_iter); + + mir::DestructuredMirConstant { variant, fields } +} + pub(crate) fn deref_const<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -207,3 +241,39 @@ pub(crate) fn deref_const<'tcx>( tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty }) } + +#[instrument(skip(tcx), level = "debug")] +pub(crate) fn deref_mir_constant<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + val: mir::ConstantKind<'tcx>, +) -> mir::ConstantKind<'tcx> { + let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); + let op = ecx.mir_const_to_op(&val, None).unwrap(); + let mplace = ecx.deref_operand(&op).unwrap(); + if let Some(alloc_id) = mplace.ptr.provenance { + assert_eq!( + tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().mutability, + Mutability::Not, + "deref_const cannot be used with mutable allocations as \ + that could allow pattern matching to observe mutable statics", + ); + } + + let ty = match mplace.meta { + MemPlaceMeta::None => mplace.layout.ty, + MemPlaceMeta::Poison => bug!("poison metadata in `deref_const`: {:#?}", mplace), + // In case of unsized types, figure out the real type behind. + MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { + ty::Str => bug!("there's no sized equivalent of a `str`"), + ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()), + _ => bug!( + "type {} should not have metadata, but had {:?}", + mplace.layout.ty, + mplace.meta + ), + }, + }; + + mir::ConstantKind::Val(op_to_const(&ecx, &mplace.into()), ty) +} diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index d688331ae0a56..493c8ec5fdd0c 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -45,6 +45,10 @@ pub fn provide(providers: &mut Providers) { let (param_env, value) = param_env_and_value.into_parts(); const_eval::try_destructure_const(tcx, param_env, value).ok() }; + providers.destructure_mir_constant = |tcx, param_env_and_value| { + let (param_env, value) = param_env_and_value.into_parts(); + const_eval::destructure_mir_constant(tcx, param_env, value) + }; providers.const_to_valtree = |tcx, param_env_and_value| { let (param_env, raw) = param_env_and_value.into_parts(); const_eval::const_to_valtree(tcx, param_env, raw) @@ -53,4 +57,8 @@ pub fn provide(providers: &mut Providers) { let (param_env, value) = param_env_and_value.into_parts(); const_eval::deref_const(tcx, param_env, value) }; + providers.deref_mir_constant = |tcx, param_env_and_value| { + let (param_env, value) = param_env_and_value.into_parts(); + const_eval::deref_mir_constant(tcx, param_env, value) + } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0a4f84558fee4..785df763b1c8b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -9,13 +9,13 @@ use crate::ty::adjustment::PointerCast; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::subst::{Subst, SubstsRef}; +use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{CtorKind, Namespace}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::{self, GeneratorKind}; use rustc_hir::{self as hir, HirId}; use rustc_session::Session; @@ -2664,6 +2664,16 @@ impl<'tcx> ConstantKind<'tcx> { } } + pub fn try_val(&self) -> Option> { + match self { + ConstantKind::Ty(c) => match c.val() { + ty::ConstKind::Value(v) => Some(v), + _ => None, + }, + ConstantKind::Val(v, _) => Some(*v), + } + } + #[inline] pub fn try_to_value(self) -> Option> { match self { @@ -2692,6 +2702,32 @@ impl<'tcx> ConstantKind<'tcx> { self.try_to_scalar_int()?.try_into().ok() } + #[inline] + pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { + match self { + Self::Ty(c) => { + // FIXME Need to use a different evaluation function that directly returns a `ConstValue` + // if evaluation succeeds and does not create a ValTree first + if let Some(val) = c.val().try_eval(tcx, param_env) { + match val { + Ok(val) => Self::Val(val, c.ty()), + Err(ErrorReported) => Self::Ty(tcx.const_error(self.ty())), + } + } else { + self + } + } + Self::Val(_, _) => self, + } + } + + #[inline] + /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. + pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 { + self.try_eval_bits(tcx, param_env, ty) + .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self)) + } + #[inline] pub fn try_eval_bits( &self, @@ -2726,25 +2762,181 @@ impl<'tcx> ConstantKind<'tcx> { } } + pub fn from_bits( + tcx: TyCtxt<'tcx>, + bits: u128, + param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Self { + let size = tcx + .layout_of(param_env_ty) + .unwrap_or_else(|e| { + bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e) + }) + .size; + let cv = ConstValue::Scalar(Scalar::from_uint(bits, size)); + + Self::Val(cv, param_env_ty.value) + } + pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self { let cv = ConstValue::from_bool(v); Self::Val(cv, tcx.types.bool) } - pub fn from_zero_sized(ty: Ty<'tcx>) -> Self { + pub fn zero_sized(ty: Ty<'tcx>) -> Self { let cv = ConstValue::Scalar(Scalar::ZST); Self::Val(cv, ty) } pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { let ty = tcx.types.usize; - let size = tcx - .layout_of(ty::ParamEnv::empty().and(ty)) - .unwrap_or_else(|e| bug!("could not compute layout for {:?}: {:?}", ty, e)) - .size; - let cv = ConstValue::Scalar(Scalar::from_uint(n as u128, size)); + Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty)) + } - Self::Val(cv, ty) + #[instrument(skip(tcx), level = "debug")] + pub fn try_eval_lit_or_param( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + ) -> Option { + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + // currently have to be wrapped in curly brackets, so it's necessary to special-case. + let expr = match &expr.kind { + hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { + block.expr.as_ref().unwrap() + } + _ => expr, + }; + + let lit_input = match expr.kind { + hir::ExprKind::Lit(ref lit) => { + Some(interpret::LitToConstInput { lit: &lit.node, ty, neg: false }) + } + hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind { + hir::ExprKind::Lit(ref lit) => { + Some(interpret::LitToConstInput { lit: &lit.node, ty, neg: true }) + } + _ => None, + }, + _ => None, + }; + + if let Some(lit_input) = lit_input { + // If an error occurred, ignore that it's a literal and leave reporting the error up to + // mir. + match tcx.at(expr.span).lit_to_mir_constant(lit_input) { + Ok(c) => return Some(c), + Err(e) => { + tcx.sess.delay_span_bug( + expr.span, + &format!("Const::from_anon_const: couldn't lit_to_const {:?}", e), + ); + } + } + } + use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; + match expr.kind { + ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { + // Find the name and index of the const parameter by indexing the generics of + // the parent item and construct a `ParamConst`. + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + let item_id = tcx.hir().get_parent_node(hir_id); + let item_def_id = tcx.hir().local_def_id(item_id); + let generics = tcx.generics_of(item_def_id.to_def_id()); + let index = generics.param_def_id_to_index[&def_id]; + let name = tcx.hir().name(hir_id); + let ty_const = tcx.mk_const(ty::ConstS { + val: ty::ConstKind::Param(ty::ParamConst::new(index, name)), + ty, + }); + + Some(Self::Ty(ty_const)) + } + _ => None, + } + } + + #[instrument(skip(tcx), level = "debug")] + pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + + let body_id = match tcx.hir().get(hir_id) { + hir::Node::AnonConst(ac) => ac.body, + _ => span_bug!( + tcx.def_span(def_id.to_def_id()), + "from_inline_const can only process anonymous constants" + ), + }; + + let expr = &tcx.hir().body(body_id).value; + + let ty = tcx.typeck(def_id).node_type(hir_id); + + let ret = match Self::try_eval_lit_or_param(tcx, ty, expr) { + Some(v) => v, + None => { + let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()); + let parent_substs = + tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id)); + let substs = ty::InlineConstSubsts::new( + tcx, + ty::InlineConstSubstsParts { parent_substs, ty }, + ) + .substs; + let ty_const = tcx.mk_const(ty::ConstS { + val: ty::ConstKind::Unevaluated(ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id).to_global(), + substs, + promoted: None, + }), + ty, + }); + + Self::Ty(ty_const) + } + }; + debug_assert!(!ret.has_free_regions()); + ret + } + + /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly + /// converted to a constant, everything else becomes `Unevaluated`. + pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id)) + } + + #[instrument(skip(tcx), level = "debug")] + fn from_opt_const_arg_anon_const( + tcx: TyCtxt<'tcx>, + def: ty::WithOptConstParam, + ) -> Self { + let body_id = match tcx.hir().get_by_def_id(def.did) { + hir::Node::AnonConst(ac) => ac.body, + _ => span_bug!( + tcx.def_span(def.did.to_def_id()), + "from_anon_const can only process anonymous constants" + ), + }; + + let expr = &tcx.hir().body(body_id).value; + debug!(?expr); + + let ty = tcx.type_of(def.def_id_for_type_of()); + + match Self::try_eval_lit_or_param(tcx, ty, expr) { + Some(v) => v, + None => { + let ty_const = tcx.mk_const(ty::ConstS { + val: ty::ConstKind::Unevaluated(ty::Unevaluated { + def: def.to_global(), + substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), + promoted: None, + }), + ty, + }); + Self::Ty(ty_const) + } + } } } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index cee510a42413a..978ed55c4e48e 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,6 +1,6 @@ //! Values computed by queries that use MIR. -use crate::mir::{Body, Promoted}; +use crate::mir::{self, Body, Promoted}; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::stable_map::FxHashMap; use rustc_data_structures::vec_map::VecMap; @@ -421,6 +421,13 @@ pub struct DestructuredConst<'tcx> { pub fields: &'tcx [ty::Const<'tcx>], } +/// The constituent parts of an ADT or array. +#[derive(Copy, Clone, Debug, HashStable)] +pub struct DestructuredMirConstant<'tcx> { + pub variant: Option, + pub fields: &'tcx [mir::ConstantKind<'tcx>], +} + /// Coverage information summarized from a MIR if instrumented for source code coverage (see /// compiler option `-Cinstrument-coverage`). This information is generated by the /// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 14c11187fc5ee..3d783a0d64c29 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -940,6 +940,13 @@ rustc_queries! { remap_env_constness } + /// Destructure an `mir::ConstantKind` ADT or array into its variant index + /// and its field values. + query destructure_mir_constant(key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>) -> mir::DestructuredMirConstant<'tcx> { + desc { "destructure mir constant"} + remap_env_constness + } + /// Dereference a constant reference or raw pointer and turn the result into a constant /// again. query deref_const( @@ -949,6 +956,15 @@ rustc_queries! { remap_env_constness } + /// Dereference a constant reference or raw pointer and turn the result into a constant + /// again. + query deref_mir_constant( + key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> + ) -> mir::ConstantKind<'tcx> { + desc { "deref constant" } + remap_env_constness + } + query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { desc { "get a &core::panic::Location referring to a span" } } @@ -960,6 +976,10 @@ rustc_queries! { desc { "converting literal to const" } } + query lit_to_mir_constant(key: LitToConstInput<'tcx>) -> Result, LitToConstError> { + desc { "converting literal to mir constant" } + } + query check_match(key: DefId) { desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index b31cc17a9594d..e4e3424cb8933 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -19,11 +19,11 @@ use rustc_middle::infer::canonical::Canonical; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{ - BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp, UserTypeProjection, + self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp, UserTypeProjection, }; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, AdtDef, Const, Ty, UpvarSubsts, UserType}; +use rustc_middle::ty::{self, AdtDef, Ty, UpvarSubsts, UserType}; use rustc_middle::ty::{ CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, }; @@ -193,7 +193,7 @@ pub enum StmtKind<'tcx> { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Expr<'_>, 104); +rustc_data_structures::static_assert_size!(Expr<'_>, 144); /// A THIR expression. #[derive(Debug, HashStable)] @@ -375,7 +375,7 @@ pub enum ExprKind<'tcx> { /// An array literal constructed from one repeated element, e.g. `[1; 5]`. Repeat { value: ExprId, - count: Const<'tcx>, + count: ty::Const<'tcx>, }, /// An array, e.g. `[a, b, c, d]`. Array { @@ -522,7 +522,7 @@ pub enum InlineAsmOperand<'tcx> { out_expr: Option, }, Const { - value: Const<'tcx>, + value: mir::ConstantKind<'tcx>, span: Span, }, SymFn { @@ -661,7 +661,7 @@ pub enum PatKind<'tcx> { /// * Opaque constants, that must not be matched structurally. So anything that does not derive /// `PartialEq` and `Eq`. Constant { - value: ty::Const<'tcx>, + value: mir::ConstantKind<'tcx>, }, Range(PatRange<'tcx>), @@ -691,8 +691,8 @@ pub enum PatKind<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, HashStable)] pub struct PatRange<'tcx> { - pub lo: ty::Const<'tcx>, - pub hi: ty::Const<'tcx>, + pub lo: mir::ConstantKind<'tcx>, + pub hi: mir::ConstantKind<'tcx>, pub end: RangeEnd, } diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs index e02ed414574b4..4cd195d29646f 100644 --- a/compiler/rustc_middle/src/thir/abstract_const.rs +++ b/compiler/rustc_middle/src/thir/abstract_const.rs @@ -22,7 +22,7 @@ pub enum CastKind { /// A node of an `AbstractConst`. #[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub enum Node<'tcx> { - Leaf(ty::Const<'tcx>), + Leaf(mir::ConstantKind<'tcx>), Binop(mir::BinOp, NodeId, NodeId), UnaryOp(mir::UnOp, NodeId), FunctionCall(NodeId, &'tcx [NodeId]), diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 451fa46638771..d052898991ddb 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -1,6 +1,8 @@ use super::{ Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir, }; +use crate::mir::ConstantKind; +use crate::ty::Const; pub trait Visitor<'a, 'tcx: 'a>: Sized { fn thir(&self) -> &'a Thir<'tcx>; @@ -24,6 +26,8 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized { fn visit_pat(&mut self, pat: &Pat<'tcx>) { walk_pat(self, pat); } + + fn visit_constant(&mut self, _constant: ConstantKind<'tcx>) {} } pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) { @@ -90,8 +94,13 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp visitor.visit_expr(&visitor.thir()[value]) } } +<<<<<<< HEAD ConstBlock { did: _, substs: _ } => {} Repeat { value, count: _ } => { +======= + ConstBlock { value } => visitor.visit_constant(value), + Repeat { value, count } => { +>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) visitor.visit_expr(&visitor.thir()[value]); } Array { ref fields } | Tuple { ref fields } => { diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index b8da35abd4703..26dc1a0736661 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -126,7 +126,7 @@ impl<'tcx> ConstKind<'tcx> { #[inline] /// Tries to evaluate the constant if it is `Unevaluated`. If that isn't possible or necessary /// return `None`. - pub(super) fn try_eval( + pub fn try_eval( self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 7d9a917d04c76..960f9c0acd48d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -662,8 +662,8 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { impl<'tcx> Ty<'tcx> { /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. - pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { - let val = match self.kind() { + pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option { + match self.kind() { ty::Int(_) | ty::Uint(_) => { let (size, signed) = int_size_and_signed(tcx, self); let val = @@ -676,14 +676,13 @@ impl<'tcx> Ty<'tcx> { ty::FloatTy::F64 => rustc_apfloat::ieee::Double::INFINITY.to_bits(), }), _ => None, - }; - val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self))) + } } /// Returns the minimum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. - pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { - let val = match self.kind() { + pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option { + match self.kind() { ty::Int(_) | ty::Uint(_) => { let (size, signed) = int_size_and_signed(tcx, self); let val = if signed { size.truncate(size.signed_int_min() as u128) } else { 0 }; @@ -695,8 +694,7 @@ impl<'tcx> Ty<'tcx> { ty::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(), }), _ => None, - }; - val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self))) + } } /// Checks whether values of this type `T` are *moved* or *copied* diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index dca9a63120c32..ac92b03e5f385 100644 --- a/compiler/rustc_mir_build/src/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs @@ -73,7 +73,7 @@ impl<'tcx> CFG<'tcx> { Rvalue::Use(Operand::Constant(Box::new(Constant { span: source_info.span, user_ty: None, - literal: ConstantKind::from_zero_sized(tcx.types.unit), + literal: ConstantKind::zero_sized(tcx.types.unit), }))), ); } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 6856ded3498ee..00d26c5e12c92 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -85,6 +85,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { span, user_ty: None, literal } } + ExprKind::ConstBlock { value } => { + Constant { span: span, user_ty: None, literal: value } + } _ => span_bug!(span, "expression is not a valid constant {:?}", kind), } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 3f8a1a3f79504..be777418433a5 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -322,7 +322,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(Rvalue::Use(Operand::Constant(Box::new(Constant { span: expr_span, user_ty: None, - literal: ty::Const::zero_sized(this.tcx, this.tcx.types.unit).into(), + literal: ConstantKind::zero_sized(this.tcx.types.unit), })))) } ExprKind::Yield { .. } @@ -552,7 +552,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { let param_ty = ty::ParamEnv::empty().and(ty); let size = self.tcx.layout_of(param_ty).unwrap().size; - let literal = ty::Const::from_bits(self.tcx, size.unsigned_int_max(), param_ty); + let literal = ConstantKind::from_bits(self.tcx, size.unsigned_int_max(), param_ty); self.literal_operand(span, literal) } @@ -563,7 +563,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let param_ty = ty::ParamEnv::empty().and(ty); let bits = self.tcx.layout_of(param_ty).unwrap().size.bits(); let n = 1 << (bits - 1); - let literal = ty::Const::from_bits(self.tcx, n, param_ty); + let literal = ConstantKind::from_bits(self.tcx, n, param_ty); self.literal_operand(span, literal) } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 219d101aa7ccf..23bd085f6f674 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -964,13 +964,13 @@ enum TestKind<'tcx> { /// /// For `bool` we always generate two edges, one for `true` and one for /// `false`. - options: FxIndexMap, u128>, + options: FxIndexMap, u128>, }, /// Test for equality with value, possibly after an unsizing coercion to /// `ty`, Eq { - value: ty::Const<'tcx>, + value: ConstantKind<'tcx>, // Integer types are handled by `SwitchInt`, and constants with ADT // types are converted back into patterns, so this can only be `&str`, // `&[T]`, `f32` or `f64`. diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 7f53d9dd70502..895df5808dbe1 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -228,9 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => (None, 0), }; if let Some((min, max, sz)) = range { - if let (Some(lo), Some(hi)) = - (lo.val().try_to_bits(sz), hi.val().try_to_bits(sz)) - { + if let (Some(lo), Some(hi)) = (lo.try_to_bits(sz), hi.try_to_bits(sz)) { // We want to compare ranges numerically, but the order of the bitwise // representation of signed integers does not match their numeric order. // Thus, to correct the ordering, we need to shift the range of signed diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 96069f05b40f3..983987f0799c3 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { test_place: &PlaceBuilder<'tcx>, candidate: &Candidate<'pat, 'tcx>, switch_ty: Ty<'tcx>, - options: &mut FxIndexMap, u128>, + options: &mut FxIndexMap, u128>, ) -> bool { let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else { return false; @@ -366,7 +366,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block: BasicBlock, make_target_blocks: impl FnOnce(&mut Self) -> Vec, source_info: SourceInfo, - value: ty::Const<'tcx>, + value: ConstantKind<'tcx>, place: Place<'tcx>, mut ty: Ty<'tcx>, ) { @@ -760,7 +760,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern) } - fn const_range_contains(&self, range: PatRange<'tcx>, value: ty::Const<'tcx>) -> Option { + fn const_range_contains( + &self, + range: PatRange<'tcx>, + value: ConstantKind<'tcx>, + ) -> Option { use std::cmp::Ordering::*; let tcx = self.tcx; @@ -777,7 +781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn values_not_contained_in_range( &self, range: PatRange<'tcx>, - options: &FxIndexMap, u128>, + options: &FxIndexMap, u128>, ) -> Option { for &val in options.keys() { if self.const_range_contains(range, val)? { @@ -823,7 +827,7 @@ fn trait_method<'tcx>( method_name: Symbol, self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], -) -> ty::Const<'tcx> { +) -> ConstantKind<'tcx> { let substs = tcx.mk_substs_trait(self_ty, params); // The unhygienic comparison here is acceptable because this is only @@ -836,5 +840,6 @@ fn trait_method<'tcx>( let method_ty = tcx.type_of(item.def_id); let method_ty = method_ty.subst(tcx, substs); - ty::Const::zero_sized(tcx, method_ty) + + ConstantKind::zero_sized(method_ty) } diff --git a/compiler/rustc_mir_build/src/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs index 3516eca1c1469..8b1ab482ee8be 100644 --- a/compiler/rustc_mir_build/src/build/misc.rs +++ b/compiler/rustc_mir_build/src/build/misc.rs @@ -25,8 +25,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Convenience function for creating a literal operand, one /// without any user type annotation. - crate fn literal_operand(&mut self, span: Span, literal: ty::Const<'tcx>) -> Operand<'tcx> { - let literal = literal.into(); + crate fn literal_operand(&mut self, span: Span, literal: ConstantKind<'tcx>) -> Operand<'tcx> { let constant = Box::new(Constant { span, user_ty: None, literal }); Operand::Constant(constant) } @@ -34,7 +33,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Returns a zero literal operand for the appropriate type, works for // bool, char and integers. crate fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { - let literal = ty::Const::from_bits(self.tcx, 0, ty::ParamEnv::empty().and(ty)); + let literal = ConstantKind::from_bits(self.tcx, 0, ty::ParamEnv::empty().and(ty)); self.literal_operand(span, literal) } diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 6687e1160ede8..10be229f08495 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -27,6 +27,7 @@ use rustc_middle::ty::query::Providers; pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; providers.lit_to_const = thir::constant::lit_to_const; + providers.lit_to_mir_constant = thir::constant::lit_to_mir_constant; providers.mir_built = build::mir_built; providers.thir_check_unsafety = check_unsafety::thir_check_unsafety; providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg; diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 30d7fdb7fec36..d955f2b2d96b6 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -3,6 +3,7 @@ use rustc_ast as ast; use rustc_middle::mir::interpret::{ Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; +use rustc_middle::mir::ConstantKind; use rustc_middle::ty::{self, ParamEnv, TyCtxt}; use rustc_span::symbol::Symbol; use rustc_target::abi::Size; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e6afc89baa03b..67384242ffa81 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -8,7 +8,7 @@ use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; -use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp}; +use rustc_middle::mir::{self, BinOp, BorrowKind, Field, UnOp}; use rustc_middle::thir::*; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast, @@ -491,7 +491,8 @@ impl<'tcx> Cx<'tcx> { hir::InlineAsmOperand::Const { ref anon_const } => { let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id); + let value = + mir::ConstantKind::from_anon_const(self.tcx, anon_const_def_id); let span = self.tcx.hir().span(anon_const.hir_id); InlineAsmOperand::Const { value, span } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index f17fe38b292cb..96c3986d796a6 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -12,6 +12,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::HirId; use rustc_hir::Node; use rustc_middle::middle::region; +use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::mir::ConstantKind; use rustc_middle::thir::*; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; @@ -75,6 +77,24 @@ impl<'tcx> Cx<'tcx> { } } + #[instrument(skip(self), level = "debug")] + crate fn const_eval_literal( + &mut self, + lit: &'tcx ast::LitKind, + ty: Ty<'tcx>, + sp: Span, + neg: bool, + ) -> ConstantKind<'tcx> { + match self.tcx.at(sp).lit_to_mir_constant(LitToConstInput { lit, ty, neg }) { + Ok(c) => c, + Err(LitToConstError::Reported) => { + // create a dummy value and continue compiling + ConstantKind::Ty(self.tcx.const_error(ty)) + } + Err(LitToConstError::TypeError) => bug!("const_eval_literal: had type error"), + } + } + crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> { let p = match self.tcx.hir().get(p.hir_id) { Node::Pat(p) | Node::Binding(p) => p, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 2298cc7cddf47..e2b7958bde70d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,7 +1,7 @@ use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; -use rustc_middle::mir::Field; +use rustc_middle::mir::{self, Field}; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; @@ -22,7 +22,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub(super) fn const_to_pat( &self, - cv: ty::Const<'tcx>, + cv: mir::ConstantKind<'tcx>, id: hir::HirId, span: Span, mir_structural_match_violation: bool, @@ -152,7 +152,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { ty.is_structural_eq_shallow(self.infcx.tcx) } - fn to_pat(&mut self, cv: ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> { + fn to_pat( + &mut self, + cv: mir::ConstantKind<'tcx>, + mir_structural_match_violation: bool, + ) -> Pat<'tcx> { trace!(self.treat_byte_string_as_slice); // This method is just a wrapper handling a validity check; the heavy lifting is // performed by the recursive `recur` method, which is not meant to be @@ -246,7 +250,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { fn field_pats( &self, - vals: impl Iterator>, + vals: impl Iterator>, ) -> Result>, FallbackToConstRef> { vals.enumerate() .map(|(idx, val)| { @@ -259,7 +263,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // Recursive helper for `to_pat`; invoke that (instead of calling this directly). fn recur( &self, - cv: ty::Const<'tcx>, + cv: mir::ConstantKind<'tcx>, mir_structural_match_violation: bool, ) -> Result, FallbackToConstRef> { let id = self.id; @@ -365,7 +369,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { PatKind::Wild } ty::Adt(adt_def, substs) if adt_def.is_enum() => { - let destructured = tcx.destructure_const(param_env.and(cv)); + let destructured = tcx.destructure_mir_constant(param_env.and(cv)); PatKind::Variant { adt_def: *adt_def, substs, @@ -376,12 +380,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { } } ty::Tuple(_) | ty::Adt(_, _) => { - let destructured = tcx.destructure_const(param_env.and(cv)); + let destructured = tcx.destructure_mir_constant(param_env.and(cv)); PatKind::Leaf { subpatterns: self.field_pats(destructured.fields.iter().copied())? } } ty::Array(..) => PatKind::Array { prefix: tcx - .destructure_const(param_env.and(cv)) + .destructure_mir_constant(param_env.and(cv)) .fields .iter() .map(|val| self.recur(*val, false)) @@ -412,12 +416,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // arrays. ty::Array(..) if !self.treat_byte_string_as_slice => { let old = self.behind_reference.replace(true); - let array = tcx.deref_const(self.param_env.and(cv)); + let array = tcx.deref_mir_constant(self.param_env.and(cv)); let val = PatKind::Deref { subpattern: Pat { kind: Box::new(PatKind::Array { prefix: tcx - .destructure_const(param_env.and(array)) + .destructure_mir_constant(param_env.and(array)) .fields .iter() .map(|val| self.recur(*val, false)) @@ -438,12 +442,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // pattern. ty::Slice(elem_ty) => { let old = self.behind_reference.replace(true); - let array = tcx.deref_const(self.param_env.and(cv)); + let array = tcx.deref_mir_constant(self.param_env.and(cv)); let val = PatKind::Deref { subpattern: Pat { kind: Box::new(PatKind::Slice { prefix: tcx - .destructure_const(param_env.and(array)) + .destructure_mir_constant(param_env.and(array)) .fields .iter() .map(|val| self.recur(*val, false)) @@ -512,7 +516,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // we fall back to a const pattern. If we do not do this, we may end up with // a !structural-match constant that is not of reference type, which makes it // very hard to invoke `PartialEq::eq` on it as a fallback. - let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) { + let val = match self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false) { Ok(subpattern) => PatKind::Deref { subpattern }, Err(_) => PatKind::Constant { value: cv }, }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 1fadd0c26fc49..d237308fc50c3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -52,10 +52,10 @@ use rustc_data_structures::captures::Captures; use rustc_index::vec::Idx; use rustc_hir::{HirId, RangeEnd}; -use rustc_middle::mir::Field; +use rustc_middle::mir::{self, Field}; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::{self, Const, Ty, TyCtxt, VariantDef}; +use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue}; use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; @@ -136,20 +136,30 @@ impl IntRange { fn from_const<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: Const<'tcx>, + value: mir::ConstantKind<'tcx>, ) -> Option { let ty = value.ty(); if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) { let val = (|| { - if let ty::ConstKind::Value(ConstValue::Scalar(scalar)) = value.val() { - // For this specific pattern we can skip a lot of effort and go - // straight to the result, after doing a bit of checking. (We - // could remove this branch and just fall through, which - // is more general but much slower.) - if let Ok(bits) = scalar.to_bits_or_ptr_internal(target_size) { - return Some(bits); + match value { + mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) => { + // For this specific pattern we can skip a lot of effort and go + // straight to the result, after doing a bit of checking. (We + // could remove this branch and just fall through, which + // is more general but much slower.) + if let Ok(bits) = scalar.to_bits_or_ptr_internal(target_size) { + return Some(bits); + } } + mir::ConstantKind::Ty(c) => match c.val() { + ty::ConstKind::Value(_) => bug!( + "encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val" + ), + _ => {} + }, + _ => {} } + // This is a more general form of the previous case. value.try_eval_bits(tcx, param_env, ty) })()?; @@ -234,8 +244,8 @@ impl IntRange { let (lo, hi) = (lo ^ bias, hi ^ bias); let env = ty::ParamEnv::empty().and(ty); - let lo_const = ty::Const::from_bits(tcx, lo, env); - let hi_const = ty::Const::from_bits(tcx, hi, env); + let lo_const = mir::ConstantKind::from_bits(tcx, lo, env); + let hi_const = mir::ConstantKind::from_bits(tcx, hi, env); let kind = if lo == hi { PatKind::Constant { value: lo_const } @@ -630,9 +640,9 @@ pub(super) enum Constructor<'tcx> { /// Ranges of integer literal values (`2`, `2..=5` or `2..5`). IntRange(IntRange), /// Ranges of floating-point literal values (`2.0..=5.2`). - FloatRange(ty::Const<'tcx>, ty::Const<'tcx>, RangeEnd), + FloatRange(mir::ConstantKind<'tcx>, mir::ConstantKind<'tcx>, RangeEnd), /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately. - Str(ty::Const<'tcx>), + Str(mir::ConstantKind<'tcx>), /// Array and slice patterns. Slice(Slice), /// Constants that must not be matched structurally. They are treated as black diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 72b597bb13d29..be11b57c830dc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -17,7 +17,7 @@ use rustc_hir::RangeEnd; use rustc_index::vec::Idx; use rustc_middle::mir::interpret::{get_slice_bytes, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; -use rustc_middle::mir::UserTypeProjection; +use rustc_middle::mir::{self, UserTypeProjection}; use rustc_middle::mir::{BorrowKind, Field, Mutability}; use rustc_middle::thir::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; @@ -121,8 +121,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { fn lower_pattern_range( &mut self, ty: Ty<'tcx>, - lo: ty::Const<'tcx>, - hi: ty::Const<'tcx>, + lo: mir::ConstantKind<'tcx>, + hi: mir::ConstantKind<'tcx>, end: RangeEnd, span: Span, ) -> PatKind<'tcx> { @@ -177,16 +177,24 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ty: Ty<'tcx>, lo: Option<&PatKind<'tcx>>, hi: Option<&PatKind<'tcx>>, - ) -> Option<(ty::Const<'tcx>, ty::Const<'tcx>)> { + ) -> Option<(mir::ConstantKind<'tcx>, mir::ConstantKind<'tcx>)> { match (lo, hi) { (Some(PatKind::Constant { value: lo }), Some(PatKind::Constant { value: hi })) => { Some((*lo, *hi)) } (Some(PatKind::Constant { value: lo }), None) => { - Some((*lo, ty.numeric_max_val(self.tcx)?)) + let hi = ty.numeric_max_val(self.tcx)?; + Some(( + *lo, + mir::ConstantKind::from_bits(self.tcx, hi, ty::ParamEnv::empty().and(ty)), + )) } (None, Some(PatKind::Constant { value: hi })) => { - Some((ty.numeric_min_val(self.tcx)?, *hi)) + let lo = ty.numeric_min_val(self.tcx)?; + Some(( + mir::ConstantKind::from_bits(self.tcx, lo, ty::ParamEnv::empty().and(ty)), + *hi, + )) } _ => None, } @@ -488,9 +496,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) { Ok(value) => { - let const_ = - ty::Const::from_value(self.tcx, value, self.typeck_results.node_type(id)); - + let const_ = mir::ConstantKind::Val(value, ty); let pattern = self.const_to_pat(const_, id, span, mir_structural_match_violation); if !is_associated_const { @@ -539,25 +545,30 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { span: Span, ) -> PatKind<'tcx> { let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id); + let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const_def_id); // Evaluate early like we do in `lower_path`. let value = value.eval(self.tcx, self.param_env); - match value.val() { - ConstKind::Param(_) => { - self.errors.push(PatternError::ConstParamInPattern(span)); - return PatKind::Wild; - } - ConstKind::Unevaluated(_) => { - // If we land here it means the const can't be evaluated because it's `TooGeneric`. - self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); - return PatKind::Wild; + match value { + mir::ConstantKind::Ty(c) => { + match c.val() { + ConstKind::Param(_) => { + self.errors.push(PatternError::ConstParamInPattern(span)); + return PatKind::Wild; + } + ConstKind::Unevaluated(_) => { + // If we land here it means the const can't be evaluated because it's `TooGeneric`. + self.tcx + .sess + .span_err(span, "constant pattern depends on a generic parameter"); + return PatKind::Wild; + } + _ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"), + } } - _ => (), + mir::ConstantKind::Val(_, _) => *self.const_to_pat(value, id, span, false).kind, } - - *self.const_to_pat(value, id, span, false).kind } /// Converts literals, paths and negation of literals to patterns. @@ -584,8 +595,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let lit_input = LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg }; - match self.tcx.at(expr.span).lit_to_const(lit_input) { - Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span, false).kind, + match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) { + Ok(constant) => *self.const_to_pat(constant, expr.hir_id, lit.span, false).kind, Err(LitToConstError::Reported) => PatKind::Wild, Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), } @@ -739,15 +750,14 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { } } +#[instrument(skip(tcx), level = "debug")] crate fn compare_const_vals<'tcx>( tcx: TyCtxt<'tcx>, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, + a: mir::ConstantKind<'tcx>, + b: mir::ConstantKind<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Option { - trace!("compare_const_vals: {:?}, {:?}", a, b); - let from_bool = |v: bool| v.then_some(Ordering::Equal); let fallback = || from_bool(a == b); @@ -759,7 +769,8 @@ crate fn compare_const_vals<'tcx>( // Early return for equal constants (so e.g. references to ZSTs can be compared, even if they // are just integer addresses). - if a.val() == b.val() { + // FIXME This might be wrong + if a == b { return from_bool(true); } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 0ce97de413496..47af6bae6bb27 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -19,6 +19,7 @@ use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; +use rustc_middle::mir::ConstantKind; use rustc_middle::span_bug; use rustc_middle::thir::abstract_const::Node as ACNode; use rustc_middle::ty::fold::TypeVisitor; @@ -156,7 +157,10 @@ where ct: AbstractConst<'tcx>, ) -> ControlFlow { const_evaluatable::walk_abstract_const(tcx, ct, |node| match node.root(tcx) { - ACNode::Leaf(leaf) => self.visit_const(leaf), + ACNode::Leaf(leaf) => match leaf { + ConstantKind::Ty(c) => self.visit_const(c), + ConstantKind::Val(_, ty) => self.visit_ty(ty), + }, ACNode::Cast(_, _, ty) => self.visit_ty(ty), ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => { ControlFlow::CONTINUE @@ -284,7 +288,7 @@ where fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow { self.visit_ty(c.ty())?; let tcx = self.def_id_visitor.tcx(); - if let Ok(Some(ct)) = AbstractConst::from_const(tcx, c) { + if let Ok(Some(ct)) = AbstractConst::from_constant(tcx, ConstantKind::Ty(c)) { self.visit_abstract_const_expr(tcx, ct)?; } ControlFlow::CONTINUE diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 2b9cc75f1b753..cdec38db12495 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -37,9 +37,14 @@ pub fn is_const_evaluatable<'cx, 'tcx>( param_env: ty::ParamEnv<'tcx>, span: Span, ) -> Result<(), NotConstEvaluatable> { +<<<<<<< HEAD let tcx = infcx.tcx; if tcx.features().generic_const_exprs { +======= + if infcx.tcx.features().generic_const_exprs { + let tcx = infcx.tcx; +>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) match AbstractConst::new(tcx, uv)? { // We are looking at a generic abstract constant. Some(ct) => { @@ -244,7 +249,7 @@ impl<'tcx> AbstractConst<'tcx> { Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs })) } - pub fn from_const( + pub fn from_constant( tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, ) -> Result>, ErrorGuaranteed> { @@ -376,6 +381,10 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { visit::walk_pat(self, pat); } } + + fn visit_constant(&mut self, ct: mir::ConstantKind<'tcx>) { + self.is_poly |= ct.has_param_types_or_consts(); + } } let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; @@ -414,10 +423,10 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.recurse_build(self.body_id)?; for n in self.nodes.iter() { - if let Node::Leaf(ty::Const(Interned( + if let Node::Leaf(mir::ConstantKind::Ty(ty::Const(Interned( ty::ConstS { val: ty::ConstKind::Unevaluated(ct), ty: _ }, _, - ))) = n + )))) = n { // `AbstractConst`s should not contain any promoteds as they require references which // are not allowed. @@ -637,6 +646,7 @@ pub(super) fn thir_abstract_const<'tcx>( } } +#[instrument(skip(tcx), level = "debug")] pub(super) fn try_unify_abstract_consts<'tcx>( tcx: TyCtxt<'tcx>, (a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>), @@ -806,3 +816,51 @@ impl<'tcx> ConstUnifyCtxt<'tcx> { } } } + +/* Think I need these changes +======= + match (a_ct, b_ct) { + (mir::ConstantKind::Ty(a_ct), mir::ConstantKind::Ty(b_ct)) => { + match (a_ct.val(), b_ct.val()) { + // We can just unify errors with everything to reduce the amount of + // emitted errors here. + (ty::ConstKind::Error(_), _) | (_, ty::ConstKind::Error(_)) => true, + (ty::ConstKind::Param(a_param), ty::ConstKind::Param(b_param)) => { + a_param == b_param + } + (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => { + a_val == b_val + } + + // If we have `fn a() -> [u8; N + 1]` and `fn b() -> [u8; 1 + M]` + // we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This + // means that we only allow inference variables if they are equal. + (ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => { + a_val == b_val + } + // We expand generic anonymous constants at the start of this function, so this + // branch should only be taking when dealing with associated constants, at + // which point directly comparing them seems like the desired behavior. + // + // FIXME(generic_const_exprs): This isn't actually the case. + // We also take this branch for concrete anonymous constants and + // expand generic anonymous constants with concrete substs. + (ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => { + a_uv == b_uv + } + // FIXME(generic_const_exprs): We may want to either actually try + // to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like + // this, for now we just return false here. + _ => false, + } + } + (mir::ConstantKind::Val(a_val, a_ty), mir::ConstantKind::Val(b_val, b_ty)) => { + a_val == b_val && a_ty == b_ty + } + _ => { + // FIXME Can it happen that we need to compare ConstantKind::Ty(ConstKind::Value) + // with a ConstantKind::Val and vice versa? + false +>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) + + */ \ No newline at end of file diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 053e871c14f6e..d82876eeac12c 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -407,7 +407,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let pred = ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder)); ProcessResult::Changed(mk_pending(vec![ - obligation.with(pred.to_predicate(self.selcx.tcx())), + obligation.with(pred.to_predicate(self.selcx.tcx())) ])) } ty::PredicateKind::TypeWellFormedFromEnv(..) => { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 6cceec8621304..67f153e0abdd7 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -17,6 +17,7 @@ use crate::traits::{self, Obligation, ObligationCause}; use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_middle::mir::ConstantKind; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{Predicate, ToPredicate}; @@ -836,7 +837,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { match node.root(self.tcx) { - Node::Leaf(leaf) => self.visit_const(leaf), + Node::Leaf(leaf) => match leaf { + ConstantKind::Ty(c) => self.visit_const(c), + ConstantKind::Val(_, ty) => self.visit_ty(ty), + }, Node::Cast(_, _, ty) => self.visit_ty(ty), Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { ControlFlow::CONTINUE From ac60db231c96738b874fb31a755ef49a0d71926c Mon Sep 17 00:00:00 2001 From: b-naber Date: Wed, 9 Mar 2022 13:56:12 +0100 Subject: [PATCH 3/9] do use ty::Const in patterns and abstract consts --- compiler/rustc_middle/src/thir.rs | 12 ++-- .../rustc_middle/src/thir/abstract_const.rs | 2 +- compiler/rustc_middle/src/thir/visit.rs | 5 -- compiler/rustc_middle/src/ty/consts/kind.rs | 7 ++- .../rustc_mir_build/src/build/matches/mod.rs | 4 +- .../src/build/matches/simplify.rs | 4 +- .../rustc_mir_build/src/build/matches/test.rs | 20 +++---- compiler/rustc_mir_build/src/build/misc.rs | 7 ++- .../src/thir/pattern/const_to_pat.rs | 30 +++++----- .../src/thir/pattern/deconstruct_pat.rs | 39 +++++-------- .../rustc_mir_build/src/thir/pattern/mod.rs | 58 ++++++++----------- .../src/thir/pattern/usefulness.rs | 13 +++-- compiler/rustc_privacy/src/lib.rs | 8 +-- .../src/traits/const_evaluatable.rs | 17 +++--- .../src/traits/object_safety.rs | 6 +- 15 files changed, 105 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index e4e3424cb8933..b970ee0186c2e 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -661,7 +661,7 @@ pub enum PatKind<'tcx> { /// * Opaque constants, that must not be matched structurally. So anything that does not derive /// `PartialEq` and `Eq`. Constant { - value: mir::ConstantKind<'tcx>, + value: ty::Const<'tcx>, }, Range(PatRange<'tcx>), @@ -691,8 +691,8 @@ pub enum PatKind<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, HashStable)] pub struct PatRange<'tcx> { - pub lo: mir::ConstantKind<'tcx>, - pub hi: mir::ConstantKind<'tcx>, + pub lo: ty::Const<'tcx>, + pub hi: ty::Const<'tcx>, pub end: RangeEnd, } @@ -736,7 +736,11 @@ impl<'tcx> fmt::Display for Pat<'tcx> { Some(adt_def.variant(variant_index)) } _ => self.ty.ty_adt_def().and_then(|adt| { - if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None } + if !adt.is_enum() { + Some(adt.non_enum_variant()) + } else { + None + } }), }; diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs index 4cd195d29646f..e02ed414574b4 100644 --- a/compiler/rustc_middle/src/thir/abstract_const.rs +++ b/compiler/rustc_middle/src/thir/abstract_const.rs @@ -22,7 +22,7 @@ pub enum CastKind { /// A node of an `AbstractConst`. #[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub enum Node<'tcx> { - Leaf(mir::ConstantKind<'tcx>), + Leaf(ty::Const<'tcx>), Binop(mir::BinOp, NodeId, NodeId), UnaryOp(mir::UnOp, NodeId), FunctionCall(NodeId, &'tcx [NodeId]), diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index d052898991ddb..abf9696454e8e 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -94,13 +94,8 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp visitor.visit_expr(&visitor.thir()[value]) } } -<<<<<<< HEAD ConstBlock { did: _, substs: _ } => {} Repeat { value, count: _ } => { -======= - ConstBlock { value } => visitor.visit_constant(value), - Repeat { value, count } => { ->>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) visitor.visit_expr(&visitor.thir()[value]); } Array { ref fields } | Tuple { ref fields } => { diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 26dc1a0736661..777ab7739f08b 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -76,7 +76,11 @@ static_assert_size!(ConstKind<'_>, 40); impl<'tcx> ConstKind<'tcx> { #[inline] pub fn try_to_value(self) -> Option> { - if let ConstKind::Value(val) = self { Some(val) } else { None } + if let ConstKind::Value(val) = self { + Some(val) + } else { + None + } } #[inline] @@ -126,6 +130,7 @@ impl<'tcx> ConstKind<'tcx> { #[inline] /// Tries to evaluate the constant if it is `Unevaluated`. If that isn't possible or necessary /// return `None`. + // FIXME(@lcnr): Completely rework the evaluation/normalization system for `ty::Const` once valtrees are merged. pub fn try_eval( self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 23bd085f6f674..219d101aa7ccf 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -964,13 +964,13 @@ enum TestKind<'tcx> { /// /// For `bool` we always generate two edges, one for `true` and one for /// `false`. - options: FxIndexMap, u128>, + options: FxIndexMap, u128>, }, /// Test for equality with value, possibly after an unsizing coercion to /// `ty`, Eq { - value: ConstantKind<'tcx>, + value: ty::Const<'tcx>, // Integer types are handled by `SwitchInt`, and constants with ADT // types are converted back into patterns, so this can only be `&str`, // `&[T]`, `f32` or `f64`. diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 895df5808dbe1..7f53d9dd70502 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -228,7 +228,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => (None, 0), }; if let Some((min, max, sz)) = range { - if let (Some(lo), Some(hi)) = (lo.try_to_bits(sz), hi.try_to_bits(sz)) { + if let (Some(lo), Some(hi)) = + (lo.val().try_to_bits(sz), hi.val().try_to_bits(sz)) + { // We want to compare ranges numerically, but the order of the bitwise // representation of signed integers does not match their numeric order. // Thus, to correct the ordering, we need to shift the range of signed diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 983987f0799c3..806c260d110ea 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { test_place: &PlaceBuilder<'tcx>, candidate: &Candidate<'pat, 'tcx>, switch_ty: Ty<'tcx>, - options: &mut FxIndexMap, u128>, + options: &mut FxIndexMap, u128>, ) -> bool { let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else { return false; @@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } else if let [success, fail] = *make_target_blocks(self) { assert_eq!(value.ty(), ty); - let expect = self.literal_operand(test.span, value); + let expect = self.literal_operand(test.span, value.into()); let val = Operand::Copy(place); self.compare(block, success, fail, source_info, BinOp::Eq, expect, val); } else { @@ -277,8 +277,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let target_blocks = make_target_blocks(self); // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons. - let lo = self.literal_operand(test.span, lo); - let hi = self.literal_operand(test.span, hi); + let lo = self.literal_operand(test.span, lo.into()); + let hi = self.literal_operand(test.span, hi.into()); let val = Operand::Copy(place); let [success, fail] = *target_blocks else { @@ -366,11 +366,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block: BasicBlock, make_target_blocks: impl FnOnce(&mut Self) -> Vec, source_info: SourceInfo, - value: ConstantKind<'tcx>, + value: ty::Const<'tcx>, place: Place<'tcx>, mut ty: Ty<'tcx>, ) { - let mut expect = self.literal_operand(source_info.span, value); + let mut expect = self.literal_operand(source_info.span, value.into()); let mut val = Operand::Copy(place); // If we're using `b"..."` as a pattern, we need to insert an @@ -760,11 +760,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern) } - fn const_range_contains( - &self, - range: PatRange<'tcx>, - value: ConstantKind<'tcx>, - ) -> Option { + fn const_range_contains(&self, range: PatRange<'tcx>, value: ty::Const<'tcx>) -> Option { use std::cmp::Ordering::*; let tcx = self.tcx; @@ -781,7 +777,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn values_not_contained_in_range( &self, range: PatRange<'tcx>, - options: &FxIndexMap, u128>, + options: &FxIndexMap, u128>, ) -> Option { for &val in options.keys() { if self.const_range_contains(range, val)? { diff --git a/compiler/rustc_mir_build/src/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs index 8b1ab482ee8be..84762d602f8db 100644 --- a/compiler/rustc_mir_build/src/build/misc.rs +++ b/compiler/rustc_mir_build/src/build/misc.rs @@ -3,6 +3,7 @@ use crate::build::Builder; +use rustc_middle::mir; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; use rustc_span::{Span, DUMMY_SP}; @@ -25,7 +26,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Convenience function for creating a literal operand, one /// without any user type annotation. - crate fn literal_operand(&mut self, span: Span, literal: ConstantKind<'tcx>) -> Operand<'tcx> { + crate fn literal_operand( + &mut self, + span: Span, + literal: mir::ConstantKind<'tcx>, + ) -> Operand<'tcx> { let constant = Box::new(Constant { span, user_ty: None, literal }); Operand::Constant(constant) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index e2b7958bde70d..2298cc7cddf47 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,7 +1,7 @@ use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; -use rustc_middle::mir::{self, Field}; +use rustc_middle::mir::Field; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; @@ -22,7 +22,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub(super) fn const_to_pat( &self, - cv: mir::ConstantKind<'tcx>, + cv: ty::Const<'tcx>, id: hir::HirId, span: Span, mir_structural_match_violation: bool, @@ -152,11 +152,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { ty.is_structural_eq_shallow(self.infcx.tcx) } - fn to_pat( - &mut self, - cv: mir::ConstantKind<'tcx>, - mir_structural_match_violation: bool, - ) -> Pat<'tcx> { + fn to_pat(&mut self, cv: ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> { trace!(self.treat_byte_string_as_slice); // This method is just a wrapper handling a validity check; the heavy lifting is // performed by the recursive `recur` method, which is not meant to be @@ -250,7 +246,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { fn field_pats( &self, - vals: impl Iterator>, + vals: impl Iterator>, ) -> Result>, FallbackToConstRef> { vals.enumerate() .map(|(idx, val)| { @@ -263,7 +259,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // Recursive helper for `to_pat`; invoke that (instead of calling this directly). fn recur( &self, - cv: mir::ConstantKind<'tcx>, + cv: ty::Const<'tcx>, mir_structural_match_violation: bool, ) -> Result, FallbackToConstRef> { let id = self.id; @@ -369,7 +365,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { PatKind::Wild } ty::Adt(adt_def, substs) if adt_def.is_enum() => { - let destructured = tcx.destructure_mir_constant(param_env.and(cv)); + let destructured = tcx.destructure_const(param_env.and(cv)); PatKind::Variant { adt_def: *adt_def, substs, @@ -380,12 +376,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { } } ty::Tuple(_) | ty::Adt(_, _) => { - let destructured = tcx.destructure_mir_constant(param_env.and(cv)); + let destructured = tcx.destructure_const(param_env.and(cv)); PatKind::Leaf { subpatterns: self.field_pats(destructured.fields.iter().copied())? } } ty::Array(..) => PatKind::Array { prefix: tcx - .destructure_mir_constant(param_env.and(cv)) + .destructure_const(param_env.and(cv)) .fields .iter() .map(|val| self.recur(*val, false)) @@ -416,12 +412,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // arrays. ty::Array(..) if !self.treat_byte_string_as_slice => { let old = self.behind_reference.replace(true); - let array = tcx.deref_mir_constant(self.param_env.and(cv)); + let array = tcx.deref_const(self.param_env.and(cv)); let val = PatKind::Deref { subpattern: Pat { kind: Box::new(PatKind::Array { prefix: tcx - .destructure_mir_constant(param_env.and(array)) + .destructure_const(param_env.and(array)) .fields .iter() .map(|val| self.recur(*val, false)) @@ -442,12 +438,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // pattern. ty::Slice(elem_ty) => { let old = self.behind_reference.replace(true); - let array = tcx.deref_mir_constant(self.param_env.and(cv)); + let array = tcx.deref_const(self.param_env.and(cv)); let val = PatKind::Deref { subpattern: Pat { kind: Box::new(PatKind::Slice { prefix: tcx - .destructure_mir_constant(param_env.and(array)) + .destructure_const(param_env.and(array)) .fields .iter() .map(|val| self.recur(*val, false)) @@ -516,7 +512,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // we fall back to a const pattern. If we do not do this, we may end up with // a !structural-match constant that is not of reference type, which makes it // very hard to invoke `PartialEq::eq` on it as a fallback. - let val = match self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false) { + let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) { Ok(subpattern) => PatKind::Deref { subpattern }, Err(_) => PatKind::Constant { value: cv }, }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index d237308fc50c3..20229d0a19fde 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -52,7 +52,7 @@ use rustc_data_structures::captures::Captures; use rustc_index::vec::Idx; use rustc_hir::{HirId, RangeEnd}; -use rustc_middle::mir::{self, Field}; +use rustc_middle::mir::Field; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; @@ -136,30 +136,20 @@ impl IntRange { fn from_const<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: mir::ConstantKind<'tcx>, + value: ty::Const<'tcx>, ) -> Option { let ty = value.ty(); if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) { let val = (|| { - match value { - mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) => { - // For this specific pattern we can skip a lot of effort and go - // straight to the result, after doing a bit of checking. (We - // could remove this branch and just fall through, which - // is more general but much slower.) - if let Ok(bits) = scalar.to_bits_or_ptr_internal(target_size) { - return Some(bits); - } + if let ty::ConstKind::Value(ConstValue::Scalar(scalar)) = value.val() { + // For this specific pattern we can skip a lot of effort and go + // straight to the result, after doing a bit of checking. (We + // could remove this branch and just fall through, which + // is more general but much slower.) + if let Ok(bits) = scalar.to_bits_or_ptr_internal(target_size) { + return Some(bits); } - mir::ConstantKind::Ty(c) => match c.val() { - ty::ConstKind::Value(_) => bug!( - "encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val" - ), - _ => {} - }, - _ => {} } - // This is a more general form of the previous case. value.try_eval_bits(tcx, param_env, ty) })()?; @@ -244,8 +234,8 @@ impl IntRange { let (lo, hi) = (lo ^ bias, hi ^ bias); let env = ty::ParamEnv::empty().and(ty); - let lo_const = mir::ConstantKind::from_bits(tcx, lo, env); - let hi_const = mir::ConstantKind::from_bits(tcx, hi, env); + let lo_const = ty::Const::from_bits(tcx, lo, env); + let hi_const = ty::Const::from_bits(tcx, hi, env); let kind = if lo == hi { PatKind::Constant { value: lo_const } @@ -640,9 +630,9 @@ pub(super) enum Constructor<'tcx> { /// Ranges of integer literal values (`2`, `2..=5` or `2..5`). IntRange(IntRange), /// Ranges of floating-point literal values (`2.0..=5.2`). - FloatRange(mir::ConstantKind<'tcx>, mir::ConstantKind<'tcx>, RangeEnd), + FloatRange(ty::Const<'tcx>, ty::Const<'tcx>, RangeEnd), /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately. - Str(mir::ConstantKind<'tcx>), + Str(ty::Const<'tcx>), /// Array and slice patterns. Slice(Slice), /// Constants that must not be matched structurally. They are treated as black @@ -839,7 +829,8 @@ impl<'tcx> Constructor<'tcx> { } } (Str(self_val), Str(other_val)) => { - // FIXME: there's probably a more direct way of comparing for equality + // FIXME Once valtrees are available we can directly use the bytes + // in the `Str` variant of the valtree for the comparison here. match compare_const_vals( pcx.cx.tcx, *self_val, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index be11b57c830dc..38c944b98d360 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -17,7 +17,7 @@ use rustc_hir::RangeEnd; use rustc_index::vec::Idx; use rustc_middle::mir::interpret::{get_slice_bytes, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; -use rustc_middle::mir::{self, UserTypeProjection}; +use rustc_middle::mir::UserTypeProjection; use rustc_middle::mir::{BorrowKind, Field, Mutability}; use rustc_middle::thir::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; @@ -121,8 +121,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { fn lower_pattern_range( &mut self, ty: Ty<'tcx>, - lo: mir::ConstantKind<'tcx>, - hi: mir::ConstantKind<'tcx>, + lo: ty::Const<'tcx>, + hi: ty::Const<'tcx>, end: RangeEnd, span: Span, ) -> PatKind<'tcx> { @@ -177,24 +177,18 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ty: Ty<'tcx>, lo: Option<&PatKind<'tcx>>, hi: Option<&PatKind<'tcx>>, - ) -> Option<(mir::ConstantKind<'tcx>, mir::ConstantKind<'tcx>)> { + ) -> Option<(ty::Const<'tcx>, ty::Const<'tcx>)> { match (lo, hi) { (Some(PatKind::Constant { value: lo }), Some(PatKind::Constant { value: hi })) => { Some((*lo, *hi)) } (Some(PatKind::Constant { value: lo }), None) => { let hi = ty.numeric_max_val(self.tcx)?; - Some(( - *lo, - mir::ConstantKind::from_bits(self.tcx, hi, ty::ParamEnv::empty().and(ty)), - )) + Some((*lo, ty::Const::from_bits(self.tcx, hi, ty::ParamEnv::empty().and(ty)))) } (None, Some(PatKind::Constant { value: hi })) => { let lo = ty.numeric_min_val(self.tcx)?; - Some(( - mir::ConstantKind::from_bits(self.tcx, lo, ty::ParamEnv::empty().and(ty)), - *hi, - )) + Some((ty::Const::from_bits(self.tcx, lo, ty::ParamEnv::empty().and(ty)), *hi)) } _ => None, } @@ -496,7 +490,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) { Ok(value) => { - let const_ = mir::ConstantKind::Val(value, ty); + let const_ = ty::Const::from_value(self.tcx, value, ty); let pattern = self.const_to_pat(const_, id, span, mir_structural_match_violation); if !is_associated_const { @@ -545,30 +539,25 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { span: Span, ) -> PatKind<'tcx> { let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const_def_id); + let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id); // Evaluate early like we do in `lower_path`. let value = value.eval(self.tcx, self.param_env); - match value { - mir::ConstantKind::Ty(c) => { - match c.val() { - ConstKind::Param(_) => { - self.errors.push(PatternError::ConstParamInPattern(span)); - return PatKind::Wild; - } - ConstKind::Unevaluated(_) => { - // If we land here it means the const can't be evaluated because it's `TooGeneric`. - self.tcx - .sess - .span_err(span, "constant pattern depends on a generic parameter"); - return PatKind::Wild; - } - _ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"), - } + match value.val() { + ConstKind::Param(_) => { + self.errors.push(PatternError::ConstParamInPattern(span)); + return PatKind::Wild; } - mir::ConstantKind::Val(_, _) => *self.const_to_pat(value, id, span, false).kind, + ConstKind::Unevaluated(_) => { + // If we land here it means the const can't be evaluated because it's `TooGeneric`. + self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); + return PatKind::Wild; + } + _ => (), } + + *self.const_to_pat(value, id, span, false).kind } /// Converts literals, paths and negation of literals to patterns. @@ -595,7 +584,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let lit_input = LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg }; - match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) { + match self.tcx.at(expr.span).lit_to_const(lit_input) { Ok(constant) => *self.const_to_pat(constant, expr.hir_id, lit.span, false).kind, Err(LitToConstError::Reported) => PatKind::Wild, Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), @@ -750,11 +739,12 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { } } +// FIXME: Get rid of this function once valtrees land #[instrument(skip(tcx), level = "debug")] crate fn compare_const_vals<'tcx>( tcx: TyCtxt<'tcx>, - a: mir::ConstantKind<'tcx>, - b: mir::ConstantKind<'tcx>, + a: ty::Const<'tcx>, + b: ty::Const<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Option { diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 15bb5adf8ba19..687b2e23c9fcb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -765,10 +765,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>( /// `is_under_guard` is used to inform if the pattern has a guard. If it /// has one it must not be inserted into the matrix. This shouldn't be /// relied on for soundness. -#[instrument( - level = "debug", - skip(cx, matrix, witness_preference, hir_id, is_under_guard, is_top_level) -)] +#[instrument(level = "debug", skip(cx, matrix, hir_id))] fn is_useful<'p, 'tcx>( cx: &MatchCheckCtxt<'p, 'tcx>, matrix: &Matrix<'p, 'tcx>, @@ -800,6 +797,7 @@ fn is_useful<'p, 'tcx>( let ty = v.head().ty(); let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty); + debug!("v.head: {:?}, v.span: {:?}", v.head(), v.head().span()); let pcx = PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive }; // If the first pattern is an or-pattern, expand it. @@ -809,9 +807,11 @@ fn is_useful<'p, 'tcx>( // We try each or-pattern branch in turn. let mut matrix = matrix.clone(); for v in v.expand_or_pat() { + debug!(?v); let usefulness = ensure_sufficient_stack(|| { is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false) }); + debug!(?usefulness); ret.extend(usefulness); // If pattern has a guard don't add it to the matrix. if !is_under_guard { @@ -822,6 +822,7 @@ fn is_useful<'p, 'tcx>( } } else { let v_ctor = v.head().ctor(); + debug!(?v_ctor); if let Constructor::IntRange(ctor_range) = &v_ctor { // Lint on likely incorrect range patterns (#63987) ctor_range.lint_overlapping_range_endpoints( @@ -895,7 +896,7 @@ fn is_useful<'p, 'tcx>( } /// The arm of a match expression. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] crate struct MatchArm<'p, 'tcx> { /// The pattern must have been lowered through `check_match::MatchVisitor::lower_pattern`. crate pat: &'p DeconstructedPat<'p, 'tcx>, @@ -928,6 +929,7 @@ crate struct UsefulnessReport<'p, 'tcx> { /// /// Note: the input patterns must have been lowered through /// `check_match::MatchVisitor::lower_pattern`. +#[instrument(skip(cx, arms), level = "debug")] crate fn compute_match_usefulness<'p, 'tcx>( cx: &MatchCheckCtxt<'p, 'tcx>, arms: &[MatchArm<'p, 'tcx>], @@ -939,6 +941,7 @@ crate fn compute_match_usefulness<'p, 'tcx>( .iter() .copied() .map(|arm| { + debug!(?arm); let v = PatStack::from_pattern(arm.pat); is_useful(cx, &matrix, &v, RealArm, arm.hir_id, arm.has_guard, true); if !arm.has_guard { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 47af6bae6bb27..0ce97de413496 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -19,7 +19,6 @@ use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; -use rustc_middle::mir::ConstantKind; use rustc_middle::span_bug; use rustc_middle::thir::abstract_const::Node as ACNode; use rustc_middle::ty::fold::TypeVisitor; @@ -157,10 +156,7 @@ where ct: AbstractConst<'tcx>, ) -> ControlFlow { const_evaluatable::walk_abstract_const(tcx, ct, |node| match node.root(tcx) { - ACNode::Leaf(leaf) => match leaf { - ConstantKind::Ty(c) => self.visit_const(c), - ConstantKind::Val(_, ty) => self.visit_ty(ty), - }, + ACNode::Leaf(leaf) => self.visit_const(leaf), ACNode::Cast(_, _, ty) => self.visit_ty(ty), ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => { ControlFlow::CONTINUE @@ -288,7 +284,7 @@ where fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow { self.visit_ty(c.ty())?; let tcx = self.def_id_visitor.tcx(); - if let Ok(Some(ct)) = AbstractConst::from_constant(tcx, ConstantKind::Ty(c)) { + if let Ok(Some(ct)) = AbstractConst::from_const(tcx, c) { self.visit_abstract_const_expr(tcx, ct)?; } ControlFlow::CONTINUE diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index cdec38db12495..709dd346efcc5 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -37,14 +37,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>( param_env: ty::ParamEnv<'tcx>, span: Span, ) -> Result<(), NotConstEvaluatable> { -<<<<<<< HEAD let tcx = infcx.tcx; if tcx.features().generic_const_exprs { -======= - if infcx.tcx.features().generic_const_exprs { - let tcx = infcx.tcx; ->>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) match AbstractConst::new(tcx, uv)? { // We are looking at a generic abstract constant. Some(ct) => { @@ -249,7 +244,7 @@ impl<'tcx> AbstractConst<'tcx> { Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs })) } - pub fn from_constant( + pub fn from_const( tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, ) -> Result>, ErrorGuaranteed> { @@ -382,6 +377,10 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } } + fn visit_const(&mut self, ct: ty::Const<'tcx>) { + self.is_poly |= ct.has_param_types_or_consts(); + } + fn visit_constant(&mut self, ct: mir::ConstantKind<'tcx>) { self.is_poly |= ct.has_param_types_or_consts(); } @@ -423,10 +422,10 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.recurse_build(self.body_id)?; for n in self.nodes.iter() { - if let Node::Leaf(mir::ConstantKind::Ty(ty::Const(Interned( + if let Node::Leaf(ty::Const(Interned( ty::ConstS { val: ty::ConstKind::Unevaluated(ct), ty: _ }, _, - )))) = n + ))) = n { // `AbstractConst`s should not contain any promoteds as they require references which // are not allowed. @@ -863,4 +862,4 @@ impl<'tcx> ConstUnifyCtxt<'tcx> { false >>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) - */ \ No newline at end of file + */ diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 67f153e0abdd7..6cceec8621304 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -17,7 +17,6 @@ use crate::traits::{self, Obligation, ObligationCause}; use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_middle::mir::ConstantKind; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{Predicate, ToPredicate}; @@ -837,10 +836,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { match node.root(self.tcx) { - Node::Leaf(leaf) => match leaf { - ConstantKind::Ty(c) => self.visit_const(c), - ConstantKind::Val(_, ty) => self.visit_ty(ty), - }, + Node::Leaf(leaf) => self.visit_const(leaf), Node::Cast(_, _, ty) => self.visit_ty(ty), Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { ControlFlow::CONTINUE From 0078e5418552bbe888376ed5331836370bcf2c99 Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 25 Mar 2022 10:06:10 +0100 Subject: [PATCH 4/9] rebase and use ty::Const in patterns again --- .../rustc_const_eval/src/const_eval/mod.rs | 6 +- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/thir.rs | 8 +-- compiler/rustc_middle/src/thir/visit.rs | 1 - compiler/rustc_middle/src/ty/consts/kind.rs | 6 +- .../src/build/expr/as_constant.rs | 64 +------------------ compiler/rustc_mir_build/src/thir/constant.rs | 50 +++++++++++++++ compiler/rustc_mir_build/src/thir/cx/mod.rs | 3 +- .../src/traits/const_evaluatable.rs | 52 --------------- .../src/traits/fulfill.rs | 2 +- .../src/matches/overlapping_arms.rs | 17 ++--- .../clippy/clippy_lints/src/neg_multiply.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 4 +- 13 files changed, 73 insertions(+), 144 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index d321dc28d8568..4ea0c89c27b3a 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -184,13 +184,13 @@ pub(crate) fn destructure_mir_constant<'tcx>( // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op), - ty::Adt(def, _) if def.variants.is_empty() => { + ty::Adt(def, _) if def.variants().is_empty() => { return mir::DestructuredMirConstant { variant: None, fields: &[] }; } ty::Adt(def, _) => { let variant = ecx.read_discriminant(&op).unwrap().1; let down = ecx.operand_downcast(&op, variant).unwrap(); - (def.variants[variant].fields.len(), Some(variant), down) + (def.variants()[variant].fields.len(), Some(variant), down) } ty::Tuple(substs) => (substs.len(), None, op), _ => bug!("cannot destructure constant {:?}", val), @@ -253,7 +253,7 @@ pub(crate) fn deref_mir_constant<'tcx>( let mplace = ecx.deref_operand(&op).unwrap(); if let Some(alloc_id) = mplace.ptr.provenance { assert_eq!( - tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().mutability, + tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().0.0.mutability, Mutability::Not, "deref_const cannot be used with mutable allocations as \ that could allow pattern matching to observe mutable statics", diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 785df763b1c8b..5d09d84e19c40 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2711,7 +2711,7 @@ impl<'tcx> ConstantKind<'tcx> { if let Some(val) = c.val().try_eval(tcx, param_env) { match val { Ok(val) => Self::Val(val, c.ty()), - Err(ErrorReported) => Self::Ty(tcx.const_error(self.ty())), + Err(_) => Self::Ty(tcx.const_error(self.ty())), } } else { self diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index b970ee0186c2e..b17343d7692f6 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -193,7 +193,7 @@ pub enum StmtKind<'tcx> { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Expr<'_>, 144); +rustc_data_structures::static_assert_size!(Expr<'_>, 104); /// A THIR expression. #[derive(Debug, HashStable)] @@ -736,11 +736,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { Some(adt_def.variant(variant_index)) } _ => self.ty.ty_adt_def().and_then(|adt| { - if !adt.is_enum() { - Some(adt.non_enum_variant()) - } else { - None - } + if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None } }), }; diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index abf9696454e8e..ab9e966063340 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -2,7 +2,6 @@ use super::{ Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir, }; use crate::mir::ConstantKind; -use crate::ty::Const; pub trait Visitor<'a, 'tcx: 'a>: Sized { fn thir(&self) -> &'a Thir<'tcx>; diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 777ab7739f08b..35d286d2c5781 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -76,11 +76,7 @@ static_assert_size!(ConstKind<'_>, 40); impl<'tcx> ConstKind<'tcx> { #[inline] pub fn try_to_value(self) -> Option> { - if let ConstKind::Value(val) = self { - Some(val) - } else { - None - } + if let ConstKind::Value(val) = self { Some(val) } else { None } } #[inline] diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 00d26c5e12c92..4a2f544970564 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -1,17 +1,12 @@ //! See docs in build/expr/mod.rs use crate::build::Builder; -use crate::thir::constant::parse_float; -use rustc_ast::ast; use rustc_hir::def_id::DefId; -use rustc_middle::mir::interpret::{ - Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, -}; +use rustc_middle::mir::interpret::{ConstValue, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; -use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that @@ -32,11 +27,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Literal { lit, neg } => { let literal = - match lit_to_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) { + match tcx.lit_to_mir_constant(LitToConstInput { lit: &lit.node, ty, neg }) { Ok(c) => c, Err(LitToConstError::Reported) => ConstantKind::Ty(tcx.const_error(ty)), Err(LitToConstError::TypeError) => { - bug!("encountered type error in `lit_to_constant") + bug!("encountered type error in `lit_to_mir_constant") } }; @@ -85,60 +80,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { span, user_ty: None, literal } } - ExprKind::ConstBlock { value } => { - Constant { span: span, user_ty: None, literal: value } - } _ => span_bug!(span, "expression is not a valid constant {:?}", kind), } } } - -crate fn lit_to_constant<'tcx>( - tcx: TyCtxt<'tcx>, - lit_input: LitToConstInput<'tcx>, -) -> Result, LitToConstError> { - let LitToConstInput { lit, ty, neg } = lit_input; - let trunc = |n| { - let param_ty = ty::ParamEnv::reveal_all().and(ty); - let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; - trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); - let result = width.truncate(n); - trace!("trunc result: {}", result); - Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) - }; - - let value = match (lit, &ty.kind()) { - (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { - let s = s.as_str(); - let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); - let allocation = tcx.intern_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: s.len() } - } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) - if matches!(inner_ty.kind(), ty::Slice(_)) => - { - let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); - let allocation = tcx.intern_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: data.len() } - } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { - let id = tcx.allocate_bytes(data); - ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) - } - (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { - ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) - } - (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { - trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })? - } - (ast::LitKind::Float(n, _), ty::Float(fty)) => { - parse_float(*n, *fty, neg).ok_or(LitToConstError::Reported)? - } - (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), - (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), - (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported), - _ => return Err(LitToConstError::TypeError), - }; - - Ok(ConstantKind::Val(value, ty)) -} diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index d955f2b2d96b6..3fc3e7338d85e 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -59,6 +59,56 @@ crate fn lit_to_const<'tcx>( Ok(ty::Const::from_value(tcx, lit, ty)) } +crate fn lit_to_mir_constant<'tcx>( + tcx: TyCtxt<'tcx>, + lit_input: LitToConstInput<'tcx>, +) -> Result, LitToConstError> { + let LitToConstInput { lit, ty, neg } = lit_input; + let trunc = |n| { + let param_ty = ty::ParamEnv::reveal_all().and(ty); + let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; + trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); + let result = width.truncate(n); + trace!("trunc result: {}", result); + Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) + }; + + let value = match (lit, &ty.kind()) { + (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { + let s = s.as_str(); + let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); + let allocation = tcx.intern_const_alloc(allocation); + ConstValue::Slice { data: allocation, start: 0, end: s.len() } + } + (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) + if matches!(inner_ty.kind(), ty::Slice(_)) => + { + let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); + let allocation = tcx.intern_const_alloc(allocation); + ConstValue::Slice { data: allocation, start: 0, end: data.len() } + } + (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { + let id = tcx.allocate_bytes(data); + ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) + } + (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { + ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) + } + (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { + trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })? + } + (ast::LitKind::Float(n, _), ty::Float(fty)) => { + parse_float(*n, *fty, neg).ok_or(LitToConstError::Reported)? + } + (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), + (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), + (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported), + _ => return Err(LitToConstError::TypeError), + }; + + Ok(ConstantKind::Val(value, ty)) +} + // FIXME move this to rustc_mir_build::build pub(crate) fn parse_float<'tcx>( num: Symbol, diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 96c3986d796a6..820434bd37300 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -5,6 +5,7 @@ use crate::thir::pattern::pat_from_hir; use crate::thir::util::UserAnnotatedTyHelpers; +use rustc_ast::ast; use rustc_data_structures::steal::Steal; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -15,7 +16,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::mir::ConstantKind; use rustc_middle::thir::*; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; crate fn thir_body<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 709dd346efcc5..498412b5cfd17 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -377,10 +377,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } } - fn visit_const(&mut self, ct: ty::Const<'tcx>) { - self.is_poly |= ct.has_param_types_or_consts(); - } - fn visit_constant(&mut self, ct: mir::ConstantKind<'tcx>) { self.is_poly |= ct.has_param_types_or_consts(); } @@ -815,51 +811,3 @@ impl<'tcx> ConstUnifyCtxt<'tcx> { } } } - -/* Think I need these changes -======= - match (a_ct, b_ct) { - (mir::ConstantKind::Ty(a_ct), mir::ConstantKind::Ty(b_ct)) => { - match (a_ct.val(), b_ct.val()) { - // We can just unify errors with everything to reduce the amount of - // emitted errors here. - (ty::ConstKind::Error(_), _) | (_, ty::ConstKind::Error(_)) => true, - (ty::ConstKind::Param(a_param), ty::ConstKind::Param(b_param)) => { - a_param == b_param - } - (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => { - a_val == b_val - } - - // If we have `fn a() -> [u8; N + 1]` and `fn b() -> [u8; 1 + M]` - // we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This - // means that we only allow inference variables if they are equal. - (ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => { - a_val == b_val - } - // We expand generic anonymous constants at the start of this function, so this - // branch should only be taking when dealing with associated constants, at - // which point directly comparing them seems like the desired behavior. - // - // FIXME(generic_const_exprs): This isn't actually the case. - // We also take this branch for concrete anonymous constants and - // expand generic anonymous constants with concrete substs. - (ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => { - a_uv == b_uv - } - // FIXME(generic_const_exprs): We may want to either actually try - // to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like - // this, for now we just return false here. - _ => false, - } - } - (mir::ConstantKind::Val(a_val, a_ty), mir::ConstantKind::Val(b_val, b_ty)) => { - a_val == b_val && a_ty == b_ty - } - _ => { - // FIXME Can it happen that we need to compare ConstantKind::Ty(ConstKind::Value) - // with a ConstantKind::Val and vice versa? - false ->>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const) - - */ diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index d82876eeac12c..053e871c14f6e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -407,7 +407,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let pred = ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder)); ProcessResult::Changed(mk_pending(vec![ - obligation.with(pred.to_predicate(self.selcx.tcx())) + obligation.with(pred.to_predicate(self.selcx.tcx())), ])) } ty::PredicateKind::TypeWellFormedFromEnv(..) => { diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs index 7e65812669029..b5fa847451d1f 100644 --- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{constant, constant_full_int, miri_to_const, FullInt}; +use clippy_utils::consts::{constant, constant_full_int, FullInt}; use clippy_utils::diagnostics::span_lint_and_note; use core::cmp::Ordering; use rustc_hir::{Arm, Expr, PatKind, RangeEnd}; @@ -32,18 +32,15 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) .filter_map(|arm| { if let Arm { pat, guard: None, .. } = *arm { if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind { - let lhs_const = match lhs { - Some(lhs) => constant(cx, cx.typeck_results(), lhs)?.0, - None => miri_to_const(ty.numeric_min_val(cx.tcx)?)?, + let lhs_val = match lhs { + Some(lhs) => constant(cx, cx.typeck_results(), lhs)?.0.int_value(cx, ty)?, + None => FullInt::U(ty.numeric_min_val(cx.tcx)?), }; - let rhs_const = match rhs { - Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0, - None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?, + let rhs_val = match rhs { + Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0.int_value(cx, ty)?, + None => FullInt::U(ty.numeric_max_val(cx.tcx)?), }; - let lhs_val = lhs_const.int_value(cx, ty)?; - let rhs_val = rhs_const.int_value(cx, ty)?; - let rhs_bound = match range_end { RangeEnd::Included => EndBound::Included(rhs_val), RangeEnd::Excluded => EndBound::Excluded(rhs_val), diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs index 0d05c83ffe45e..6ba9ba0753d49 100644 --- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs +++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for NegMultiply { fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { if_chain! { if let ExprKind::Lit(ref l) = lit.kind; - if consts::lit_to_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1); + if consts::lit_to_mir_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1); if cx.typeck_results().expr_ty(exp).is_integral(); then { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 1d6f7acab139b..be46b791aa4b6 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -179,7 +179,7 @@ impl Constant { } /// Parses a `LitKind` to a `Constant`. -pub fn lit_to_constant(lit: &LitKind, ty: Option>) -> Constant { +pub fn lit_to_mir_constant(lit: &LitKind, ty: Option>) -> Constant { match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), @@ -301,7 +301,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { if is_direct_expn_of(e.span, "cfg").is_some() { None } else { - Some(lit_to_constant(&lit.node, self.typeck_results.expr_ty_opt(e))) + Some(lit_to_mir_constant(&lit.node, self.typeck_results.expr_ty_opt(e))) } }, ExprKind::Array(vec) => self.multi(vec).map(Constant::Vec), From d0e05f04266c5725b11677e5c74d33f930e76207 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 28 Mar 2022 10:25:30 +0200 Subject: [PATCH 5/9] update tests --- ...allocation2.main.ConstProp.after.64bit.mir | 32 +++---- ..._line_doc_comment_2.DeduplicateBlocks.diff | 2 +- .../inline/inline_diverging.g.Inline.diff | 2 +- ...line_into_box_place.main.Inline.64bit.diff | 9 +- ...ue_59352.num_to_digit.PreCodegen.after.mir | 2 +- ...age_markers.main.RemoveStorageMarkers.diff | 2 +- .../associated-consts/defaults-cyclic-fail.rs | 1 - .../defaults-cyclic-fail.stderr | 28 +++++- ...-assoc-const-static-recursion-trait.stderr | 7 +- .../borrowck/issue-88434-minimal-example.rs | 2 - .../issue-88434-minimal-example.stderr | 20 +--- ...ssue-88434-removal-index-should-be-less.rs | 2 - ...-88434-removal-index-should-be-less.stderr | 20 +--- .../ui/const-ptr/out_of_bounds_read.stderr | 6 +- .../const-eval/const-eval-query-stack.rs | 2 - .../const-eval/const-eval-query-stack.stderr | 17 +--- src/test/ui/consts/const-integer-bool-ops.rs | 10 -- .../ui/consts/const-integer-bool-ops.stderr | 95 ++++--------------- .../const-mut-refs/issue-76510.64bit.stderr | 12 +-- .../ui/consts/const-mut-refs/issue-76510.rs | 1 - src/test/ui/consts/const-tup-index-span.rs | 1 - .../ui/consts/const-tup-index-span.stderr | 11 +-- src/test/ui/consts/invalid-union.64bit.stderr | 2 +- src/test/ui/consts/issue-36163.stderr | 40 ++++++-- src/test/ui/issues/issue-17252.stderr | 15 ++- src/test/ui/issues/issue-23302-1.stderr | 17 +++- src/test/ui/issues/issue-23302-2.stderr | 17 +++- src/test/ui/issues/issue-23302-3.stderr | 30 ++++-- src/test/ui/issues/issue-41394.rs | 1 - src/test/ui/issues/issue-41394.stderr | 11 +-- src/test/ui/issues/issue-54954.rs | 2 - src/test/ui/issues/issue-54954.stderr | 18 +--- ...issue-69602-type-err-during-codegen-ice.rs | 1 - ...e-69602-type-err-during-codegen-ice.stderr | 10 +- src/test/ui/issues/issue-77919.rs | 1 - src/test/ui/issues/issue-77919.stderr | 16 +--- src/test/ui/resolve/issue-50599.rs | 1 - src/test/ui/resolve/issue-50599.stderr | 11 +-- .../ui/type/type-dependent-def-issue-49241.rs | 1 - .../type-dependent-def-issue-49241.stderr | 11 +-- 40 files changed, 204 insertions(+), 285 deletions(-) diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir index e2acd610b8053..ef651f01c9b98 100644 --- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir @@ -21,44 +21,44 @@ fn main() -> () { } alloc1 (static: FOO, size: 16, align: 8) { - ╾───────alloc22───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾───────alloc28───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc22 (size: 72, align: 8) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc9────────╼ │ ....░░░░╾──────╼ +alloc28 (size: 72, align: 8) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc13───────╼ │ ....░░░░╾──────╼ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ - 0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc20───────╼ │ ....*...╾──────╼ + 0x20 │ ╾───────alloc18───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc26───────╼ │ ....*...╾──────╼ 0x40 │ 03 00 00 00 00 00 00 00 │ ........ } -alloc9 (size: 0, align: 8) {} +alloc13 (size: 0, align: 8) {} -alloc14 (size: 16, align: 8) { - ╾───────alloc12───────╼ ╾───────alloc13───────╼ │ ╾──────╼╾──────╼ +alloc18 (size: 16, align: 8) { + ╾───────alloc16───────╼ ╾───────alloc17───────╼ │ ╾──────╼╾──────╼ } -alloc12 (size: 1, align: 1) { +alloc16 (size: 1, align: 1) { 05 │ . } -alloc13 (size: 1, align: 1) { +alloc17 (size: 1, align: 1) { 06 │ . } -alloc20 (size: 24, align: 8) { - 0x00 │ ╾─────alloc17+0x3─────╼ ╾───────alloc18───────╼ │ ╾──────╼╾──────╼ - 0x10 │ ╾─────alloc19+0x2─────╼ │ ╾──────╼ +alloc26 (size: 24, align: 8) { + 0x00 │ ╾─────alloc22+0x3─────╼ ╾───────alloc23───────╼ │ ╾──────╼╾──────╼ + 0x10 │ ╾─────alloc25+0x2─────╼ │ ╾──────╼ } -alloc17 (size: 4, align: 1) { +alloc22 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } -alloc18 (size: 1, align: 1) { +alloc23 (size: 1, align: 1) { 2a │ * } -alloc19 (size: 4, align: 1) { +alloc25 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } diff --git a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff index 122bef522cf4d..372b14eb7c92a 100644 --- a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff +++ b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff @@ -26,7 +26,7 @@ - _2 = transmute::<&str, &[u8]>(move _8) -> bb14; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL + _2 = transmute::<&str, &[u8]>(move _8) -> bb12; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL // mir::Constant - // + span: $DIR/deduplicate_blocks.rs:3:11: 3:23 + // + span: $SRC_DIR/core/src/str/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&str) -> &[u8] {transmute::<&str, &[u8]>}, val: Value(Scalar()) } } diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index cb79cdd3579ea..3b9d5e727b8a3 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -39,7 +39,7 @@ // mir::Constant - // + span: $DIR/inline-diverging.rs:16:9: 16:14 - // + literal: Const { ty: fn() -> ! {panic}, val: Value(Scalar()) } -+ // + span: $DIR/inline-diverging.rs:16:9: 16:16 ++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(Scalar()) } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff index ed4a8602a2413..0f83b0c4a27ad 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff @@ -34,10 +34,7 @@ - (*_5) = Vec::::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + _7 = &mut (*_5); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 -+ ((*_7).0: alloc::raw_vec::RawVec) = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43 -+ // ty::Const -+ // + ty: alloc::raw_vec::RawVec -+ // + val: Unevaluated(alloc::raw_vec::RawVec::::NEW, [u32], None) ++ ((*_7).0: alloc::raw_vec::RawVec) = const alloc::raw_vec::RawVec:: { ptr: Unique:: { pointer: {0x4 as *const u32}, _marker: PhantomData:: }, cap: 0_usize, alloc: std::alloc::Global }; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 - // + user_ty: UserType(1) @@ -47,8 +44,8 @@ - bb2: { + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // + user_ty: UserType(0) -+ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(5:77 ~ alloc[25db]::raw_vec::{impl#0}::NEW), const_param_did: None }, substs: [u32], promoted: None }) } -+ ((*_7).1: usize) = const 0_usize; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } ++ ((*_7).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index c5c063e8cecf1..e2051c85af215 100644 --- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -38,7 +38,7 @@ fn num_to_digit(_1: char) -> u32 { _8 = _2; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL _7 = char::methods::::to_digit(move _8, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL // mir::Constant - // + span: $DIR/issue-59352.rs:14:8: 14:23 + // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value(Scalar()) } } diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff index ec76424afa55e..312031b7a0ff4 100644 --- a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff +++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff @@ -58,7 +58,7 @@ _14 = &mut (*_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL _7 = as iter::range::RangeIteratorImpl>::spec_next(move _14) -> bb4; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL // mir::Constant - // + span: $DIR/remove_storage_markers.rs:8:14: 8:19 + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range) -> Option< as iter::range::RangeIteratorImpl>::Item> { as iter::range::RangeIteratorImpl>::spec_next}, val: Value(Scalar()) } } diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.rs b/src/test/ui/associated-consts/defaults-cyclic-fail.rs index 6c1c68b9f2931..2f1858d39b3c6 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.rs +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.rs @@ -4,7 +4,6 @@ // Cyclic assoc. const defaults don't error unless *used* trait Tr { const A: u8 = Self::B; - //~^ ERROR cycle detected when const-evaluating + checking `Tr::A` const B: u8 = Self::A; } diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr index 550897790e9ff..3fb4ab72fe6d6 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr @@ -1,15 +1,37 @@ -error[E0391]: cycle detected when const-evaluating + checking `Tr::A` - --> $DIR/defaults-cyclic-fail.rs:5:5 +error[E0391]: cycle detected when normalizing `<() as Tr>::A` + | +note: ...which requires simplifying constant for the type system `Tr::A`... + --> $DIR/defaults-cyclic-fail.rs:6:5 + | +LL | const A: u8 = Self::B; + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `Tr::A`... + --> $DIR/defaults-cyclic-fail.rs:6:5 + | +LL | const A: u8 = Self::B; + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `Tr::A`... + --> $DIR/defaults-cyclic-fail.rs:6:5 | LL | const A: u8 = Self::B; | ^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `<() as Tr>::B`... +note: ...which requires simplifying constant for the type system `Tr::B`... + --> $DIR/defaults-cyclic-fail.rs:8:5 | +LL | const B: u8 = Self::A; + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `Tr::B`... + --> $DIR/defaults-cyclic-fail.rs:8:5 + | +LL | const B: u8 = Self::A; + | ^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Tr::B`... --> $DIR/defaults-cyclic-fail.rs:8:5 | LL | const B: u8 = Self::A; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle + = note: ...which again requires normalizing `<() as Tr>::A`, completing the cycle note: cycle used when const-evaluating + checking `main::promoted[1]` --> $DIR/defaults-cyclic-fail.rs:14:1 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index bf8412f3e770c..020d758e153c2 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -6,6 +6,10 @@ LL | const BAR: u32 = TRAIT_REF_BAR; | = note: ...which requires normalizing `TRAIT_REF_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 simplifying constant for the type system `TRAIT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | @@ -27,9 +31,6 @@ note: ...which requires simplifying constant for the type system `>>>>>> 53eca42efca (bless tests) note: ...which requires const-evaluating + checking `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.rs b/src/test/ui/borrowck/issue-88434-minimal-example.rs index 90baca253d268..632f8dc3ad6f5 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.rs +++ b/src/test/ui/borrowck/issue-88434-minimal-example.rs @@ -1,8 +1,6 @@ // Regression test related to issue 88434 const _CONST: &() = &f(&|_| {}); -//~^ ERROR any use of this value will cause an error -//~| WARNING this was previously accepted by the compiler but is being phased out const fn f(_: &F) where diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr index 1af7c606b7185..d9635e1ee464c 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr +++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-minimal-example.rs:12:5 + --> $DIR/issue-88434-minimal-example.rs:9:5 | LL | const _CONST: &() = &f(&|_| {}); | ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:3:22 @@ -7,23 +7,11 @@ LL | const _CONST: &() = &f(&|_| {}); LL | panic!() | ^^^^^^^^ | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:12:5 - | inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:4:25: 4:31]>` at $SRC_DIR/std/src/panic.rs:LL:COL + | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:9:5 + | inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:31]>` at $SRC_DIR/std/src/panic.rs:LL:COL | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error: any use of this value will cause an error - --> $DIR/issue-88434-minimal-example.rs:4:21 - | -LL | const _CONST: &() = &f(&|_| {}); - | --------------------^^^^^^^^^^^- - | | - | referenced constant has errors - | - = note: `#[deny(const_err)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs index b1fc1615ece77..f0a6dcd4eb3b8 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs @@ -1,8 +1,6 @@ // Regression test for issue 88434 const _CONST: &[u8] = &f(&[], |_| {}); -//~^ ERROR any use of this value will cause an error -//~| WARNING this was previously const fn f(_: &[u8], _: F) -> &[u8] where diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index f2a381a73ef49..44e244ae9cc3f 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-removal-index-should-be-less.rs:12:5 + --> $DIR/issue-88434-removal-index-should-be-less.rs:9:5 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:3:24 @@ -7,23 +7,11 @@ LL | const _CONST: &[u8] = &f(&[], |_| {}); LL | panic!() | ^^^^^^^^ | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:12:5 - | inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:4:31: 4:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL + | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:9:5 + | inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error: any use of this value will cause an error - --> $DIR/issue-88434-removal-index-should-be-less.rs:4:23 - | -LL | const _CONST: &[u8] = &f(&[], |_| {}); - | ----------------------^^^^^^^^^^^^^^^- - | | - | referenced constant has errors - | - = note: `#[deny(const_err)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr index 52b173c4d04a8..678714d0e055a 100644 --- a/src/test/ui/const-ptr/out_of_bounds_read.stderr +++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | memory access failed: alloc7 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL | ::: $DIR/out_of_bounds_read.rs:12:33 @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | memory access failed: alloc7 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL | ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -37,7 +37,7 @@ error[E0080]: evaluation of constant value failed LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | memory access failed: alloc7 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL | ::: $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.rs b/src/test/ui/consts/const-eval/const-eval-query-stack.rs index 8412fefcb658f..e73e54ff5f1b3 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.rs +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.rs @@ -23,7 +23,5 @@ const X: i32 = 1 / 0; //~WARN any use of this value will cause an error fn main() { let x: &'static i32 = &X; //~^ ERROR evaluation of constant value failed - //~| ERROR erroneous constant used - //~| WARNING this was previously accepted by the compiler println!("x={}", x); } diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 2de2ef181babd..8bd5c08dc4649 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -1,5 +1,5 @@ warning: any use of this value will cause an error - --> $DIR/const-eval-query-stack.rs:19:16 + --> $DIR/const-eval-query-stack.rs:20:16 | LL | const X: i32 = 1 / 0; | ---------------^^^^^- @@ -7,7 +7,7 @@ LL | const X: i32 = 1 / 0; | attempt to divide `1_i32` by zero | note: the lint level is defined here - --> $DIR/const-eval-query-stack.rs:18:8 + --> $DIR/const-eval-query-stack.rs:19:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -15,21 +15,10 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error[E0080]: evaluation of constant value failed - --> $DIR/const-eval-query-stack.rs:23:28 + --> $DIR/const-eval-query-stack.rs:24:28 | LL | let x: &'static i32 = &X; | ^ referenced constant has errors - -error: erroneous constant used - --> $DIR/const-eval-query-stack.rs:23:27 - | -LL | let x: &'static i32 = &X; - | ^^ referenced constant has errors - | - = note: `#[deny(const_err)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 - query stack during panic: #0 [try_normalize_mir_const_after_erasing_regions] normalizing `main::promoted[1]` #1 [mir_drops_elaborated_and_const_checked] elaborating drops for `main` diff --git a/src/test/ui/consts/const-integer-bool-ops.rs b/src/test/ui/consts/const-integer-bool-ops.rs index 6924956bdf706..35915a7a606a4 100644 --- a/src/test/ui/consts/const-integer-bool-ops.rs +++ b/src/test/ui/consts/const-integer-bool-ops.rs @@ -6,7 +6,6 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; -//~^ ERROR evaluation of constant value failed const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -16,7 +15,6 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; -//~^ ERROR evaluation of constant value failed const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -26,7 +24,6 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ ERROR evaluation of constant value failed const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -36,43 +33,36 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; -//~^ ERROR evaluation of constant value failed const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; -//~^ ERROR evaluation of constant value failed const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; -//~^ ERROR evaluation of constant value failed const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; -//~^ ERROR evaluation of constant value failed const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; -//~^ ERROR evaluation of constant value failed const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; -//~^ ERROR evaluation of constant value failed const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; -//~^ ERROR evaluation of constant value failed fn main() { let _ = ARR; diff --git a/src/test/ui/consts/const-integer-bool-ops.stderr b/src/test/ui/consts/const-integer-bool-ops.stderr index 9001fefd1029f..4e503e5a5c0a4 100644 --- a/src/test/ui/consts/const-integer-bool-ops.stderr +++ b/src/test/ui/consts/const-integer-bool-ops.stderr @@ -16,157 +16,96 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:8:18 - | -LL | const ARR: [i32; X] = [99; 34]; - | ^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:25 + --> $DIR/const-integer-bool-ops.rs:10:25 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:18:19 - | -LL | const ARR1: [i32; X1] = [99; 47]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:26 + --> $DIR/const-integer-bool-ops.rs:19:26 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:28:19 - | -LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:26 + --> $DIR/const-integer-bool-ops.rs:28:26 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:38:19 - | -LL | const ARR3: [i32; X3] = [99; 6]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:41:18 + --> $DIR/const-integer-bool-ops.rs:37:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:44:19 - | -LL | const ARRR: [i32; Y] = [99; 1]; - | ^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:47:19 + --> $DIR/const-integer-bool-ops.rs:42:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:50:20 - | -LL | const ARRR1: [i32; Y1] = [99; 1]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:53:19 + --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:56:20 - | -LL | const ARRR2: [i32; Y2] = [99; 1]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:59:19 + --> $DIR/const-integer-bool-ops.rs:52:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:62:20 - | -LL | const ARRR3: [i32; Y3] = [99; 0]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:65:19 + --> $DIR/const-integer-bool-ops.rs:57:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:68:20 - | -LL | const ARRR4: [i32; Y4] = [99; 0]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:71:19 + --> $DIR/const-integer-bool-ops.rs:62:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:74:20 - | -LL | const ARRR5: [i32; Y5] = [99; 0]; - | ^^ referenced constant has errors - -error: aborting due to 28 previous errors +error: aborting due to 18 previous errors -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr index 0f420ae1b6b7c..61b00be345fee 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr +++ b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -19,13 +19,7 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -error[E0080]: evaluation of constant value failed - --> $DIR/issue-76510.rs:11:70 - | -LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - | ^ referenced constant has errors - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0596, E0658, E0764. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.rs b/src/test/ui/consts/const-mut-refs/issue-76510.rs index 08cf64ee330db..143d2fb6b9a3a 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.rs +++ b/src/test/ui/consts/const-mut-refs/issue-76510.rs @@ -9,7 +9,6 @@ const S: &'static mut str = &mut " hello "; const fn trigger() -> [(); unsafe { let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - //~^ ERROR evaluation of constant value failed 0 }] { [(); 0] diff --git a/src/test/ui/consts/const-tup-index-span.rs b/src/test/ui/consts/const-tup-index-span.rs index 763263c6aeb4f..8057d64369a23 100644 --- a/src/test/ui/consts/const-tup-index-span.rs +++ b/src/test/ui/consts/const-tup-index-span.rs @@ -4,7 +4,6 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected tuple, found `usize` const ARR: [i32; TUP.0] = []; -//~^ ERROR evaluation of constant value failed fn main() { } diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr index b178e05e27a09..d301f8c4054c2 100644 --- a/src/test/ui/consts/const-tup-index-span.stderr +++ b/src/test/ui/consts/const-tup-index-span.stderr @@ -11,13 +11,6 @@ help: use a trailing comma to create a tuple with one element LL | const TUP: (usize,) = (5usize << 64,); | + ++ -error[E0080]: evaluation of constant value failed - --> $DIR/const-tup-index-span.rs:6:18 - | -LL | const ARR: [i32; TUP.0] = []; - | ^^^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index 3e89d7c0e489f..6bfa97a2fded7 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -6,7 +6,7 @@ LL | fn main() { | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc6────────╼ │ ╾──────╼ + ╾───────alloc7────────╼ │ ╾──────╼ } error: erroneous constant used diff --git a/src/test/ui/consts/issue-36163.stderr b/src/test/ui/consts/issue-36163.stderr index 9ac6c984cb0cd..113f86cf0f99f 100644 --- a/src/test/ui/consts/issue-36163.stderr +++ b/src/test/ui/consts/issue-36163.stderr @@ -1,20 +1,48 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::B::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | +note: ...which requires simplifying constant for the type system `Foo::B::{constant#0}`... + --> $DIR/issue-36163.rs:4:9 + | +LL | B = A, + | ^ +note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`... + --> $DIR/issue-36163.rs:4:9 + | +LL | B = A, + | ^ + = note: ...which requires normalizing `A`... +note: ...which requires simplifying constant for the type system `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-36163.rs:1:1 | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `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: ...which requires normalizing `A`... + = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle +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() {} + | |____________^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index 4856418ed6002..1148577016ab4 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -1,10 +1,21 @@ -error[E0391]: cycle detected when const-evaluating + checking `FOO` +error[E0391]: cycle detected when normalizing `FOO` + | +note: ...which requires simplifying constant for the type system `FOO`... + --> $DIR/issue-17252.rs:1:1 + | +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `FOO`... --> $DIR/issue-17252.rs:1:1 | LL | const FOO: usize = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `FOO`... + --> $DIR/issue-17252.rs:1:1 | - = note: ...which immediately requires const-evaluating + checking `FOO` again +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires normalizing `FOO`, completing the cycle note: cycle used when const-evaluating + checking `main::{constant#0}` --> $DIR/issue-17252.rs:4:18 | diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index 9366050d7ecdf..d3a1993536a00 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -1,15 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `X::A::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `X::A::{constant#0}` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | - = note: ...which immediately requires const-evaluating + checking `X::A::{constant#0}` again -note: cycle used when simplifying constant for the type system `X::A::{constant#0}` +note: ...which requires simplifying constant for the type system `X::A::{constant#0}`... --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `X::A::{constant#0}`... + --> $DIR/issue-23302-1.rs:4:9 + | +LL | A = X::A as isize, + | ^^^^^^^^^^^^^ + = note: ...which requires normalizing `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 collecting item types in top-level module + --> $DIR/issue-23302-1.rs:3:1 + | +LL | enum X { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index b97ae287a47a9..d3b78ea1af5f5 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -1,15 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `Y::A::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `Y::A::{constant#0}` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | - = note: ...which immediately requires const-evaluating + checking `Y::A::{constant#0}` again -note: cycle used when simplifying constant for the type system `Y::A::{constant#0}` +note: ...which requires simplifying constant for the type system `Y::A::{constant#0}`... --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `Y::A::{constant#0}`... + --> $DIR/issue-23302-2.rs:4:9 + | +LL | A = Y::B as isize, + | ^^^^^^^^^^^^^ + = note: ...which requires normalizing `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 collecting item types in top-level module + --> $DIR/issue-23302-2.rs:3:1 + | +LL | enum Y { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index 1a07d4a95bcfa..5233b832ecc79 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -1,20 +1,38 @@ -error[E0391]: cycle detected when const-evaluating + checking `A` +error[E0391]: cycle detected when simplifying constant for the type system `A` --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `B`... - --> $DIR/issue-23302-3.rs:3:1 +note: ...which requires simplifying constant for the type system `A`... + --> $DIR/issue-23302-3.rs:1:1 | -LL | const B: i32 = A; +LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `A`, completing the cycle -note: cycle used when simplifying constant for the type system `A` +note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `B`... +note: ...which requires simplifying constant for the type system `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `A`... + = note: ...which again requires simplifying constant for the type system `A`, completing the cycle + = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-41394.rs b/src/test/ui/issues/issue-41394.rs index 64873ac35a002..06a330813406a 100644 --- a/src/test/ui/issues/issue-41394.rs +++ b/src/test/ui/issues/issue-41394.rs @@ -5,7 +5,6 @@ enum Foo { enum Bar { A = Foo::A as isize - //~^ ERROR evaluation of constant value failed } fn main() {} diff --git a/src/test/ui/issues/issue-41394.stderr b/src/test/ui/issues/issue-41394.stderr index 47a24547d4533..fa95ca9c18a10 100644 --- a/src/test/ui/issues/issue-41394.stderr +++ b/src/test/ui/issues/issue-41394.stderr @@ -6,13 +6,6 @@ LL | A = "" + 1 | | | &str -error[E0080]: evaluation of constant value failed - --> $DIR/issue-41394.rs:7:9 - | -LL | A = Foo::A as isize - | ^^^^^^^^^^^^^^^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0369. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs index ddd3914154147..42a4d5b674b22 100644 --- a/src/test/ui/issues/issue-54954.rs +++ b/src/test/ui/issues/issue-54954.rs @@ -9,8 +9,6 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - //~^ ERROR evaluation of constant value failed - //~| ERROR evaluation of constant value failed z } diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr index 6e8d3cac9a7e4..efe2ef504a2ba 100644 --- a/src/test/ui/issues/issue-54954.stderr +++ b/src/test/ui/issues/issue-54954.stderr @@ -12,19 +12,7 @@ LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); | = note: cannot satisfy `_: Tt` -error[E0080]: evaluation of constant value failed - --> $DIR/issue-54954.rs:11:15 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ referenced constant has errors - -error[E0080]: evaluation of constant value failed - --> $DIR/issue-54954.rs:11:34 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ referenced constant has errors - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0080, E0283, E0379. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0283, E0379. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs index 6851b67cb3b3a..2c5257ce063cb 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs @@ -19,5 +19,4 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` fn main() { let _ = [0; B::VALUE]; - //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr index cb5b397849c06..8ae0f8b804c93 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr @@ -13,13 +13,7 @@ LL | type MyA: TraitA; LL | impl TraitB for B { | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation -error[E0080]: evaluation of constant value failed - --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 - | -LL | let _ = [0; B::VALUE]; - | ^^^^^^^^ referenced constant has errors - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0046, E0080, E0437. +Some errors have detailed explanations: E0046, E0437. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index c2946ad94b0b7..966d76d148af3 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,6 +1,5 @@ fn main() { [1; >::VAL]; - //~^ ERROR evaluation of constant value failed } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index 8d5d6cb037749..97bd5ab36b65d 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:10:9 + --> $DIR/issue-77919.rs:9:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:12:63 + --> $DIR/issue-77919.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:12:1 + --> $DIR/issue-77919.rs:11:1 | LL | const VAL: T; | ------------- `VAL` from trait @@ -26,13 +26,7 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error[E0080]: evaluation of constant value failed - --> $DIR/issue-77919.rs:2:9 - | -LL | [1; >::VAL]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0046, E0080, E0412. +Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/resolve/issue-50599.rs b/src/test/ui/resolve/issue-50599.rs index 78a20cf8ebb05..00588735b9a59 100644 --- a/src/test/ui/resolve/issue-50599.rs +++ b/src/test/ui/resolve/issue-50599.rs @@ -2,5 +2,4 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; - //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/resolve/issue-50599.stderr b/src/test/ui/resolve/issue-50599.stderr index effa16e55e54e..7ec567a06f09d 100644 --- a/src/test/ui/resolve/issue-50599.stderr +++ b/src/test/ui/resolve/issue-50599.stderr @@ -11,13 +11,6 @@ LL | use std::f32::consts::LOG10_2; LL | use std::f64::consts::LOG10_2; | -error[E0080]: evaluation of constant value failed - --> $DIR/issue-50599.rs:4:29 - | -LL | let mut digits = [0u32; M]; - | ^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0425. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index 51bd116fbd61c..4b6bc6124dbf3 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -2,5 +2,4 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); - //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 02f267c6c8d73..64c7687f7a882 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -6,13 +6,6 @@ LL | const l: usize = v.count(); | | | help: consider using `let` instead of `const`: `let l` -error[E0080]: evaluation of constant value failed - --> $DIR/type-dependent-def-issue-49241.rs:4:18 - | -LL | let s: [u32; l] = v.into_iter().collect(); - | ^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0435. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0435`. From 9b28d3b494f5507b13b04f383bb4ea2bf23294fc Mon Sep 17 00:00:00 2001 From: b-naber Date: Sat, 2 Apr 2022 12:09:22 +0200 Subject: [PATCH 6/9] try to evaluate in from_opt_const_arg_anon_const --- compiler/rustc_middle/src/mir/mod.rs | 79 ++++++++++++++++++-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 7 +- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 5d09d84e19c40..9b39c61719c88 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -9,7 +9,7 @@ use crate::ty::adjustment::PointerCast; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; +use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex}; @@ -2901,14 +2901,19 @@ impl<'tcx> ConstantKind<'tcx> { /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly /// converted to a constant, everything else becomes `Unevaluated`. - pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id)) + pub fn from_anon_const( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + ) -> Self { + Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env) } #[instrument(skip(tcx), level = "debug")] fn from_opt_const_arg_anon_const( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, + param_env: ty::ParamEnv<'tcx>, ) -> Self { let body_id = match tcx.hir().get_by_def_id(def.did) { hir::Node::AnonConst(ac) => ac.body, @@ -2921,11 +2926,72 @@ impl<'tcx> ConstantKind<'tcx> { let expr = &tcx.hir().body(body_id).value; debug!(?expr); + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + // currently have to be wrapped in curly brackets, so it's necessary to special-case. + let expr = match &expr.kind { + hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { + block.expr.as_ref().unwrap() + } + _ => expr, + }; + let ty = tcx.type_of(def.def_id_for_type_of()); - match Self::try_eval_lit_or_param(tcx, ty, expr) { - Some(v) => v, - None => { + // FIXME(const_generics): We currently have to special case parameters because `min_const_generics` + // does not provide the parents generics to anonymous constants. We still allow generic const + // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to + // ever try to substitute the generic parameters in their bodies. + // + // While this doesn't happen as these constants are always used as `ty::ConstKind::Param`, it does + // cause issues if we were to remove that special-case and try to evaluate the constant instead. + use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; + match expr.kind { + ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { + // Find the name and index of the const parameter by indexing the generics of + // the parent item and construct a `ParamConst`. + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + let item_id = tcx.hir().get_parent_node(hir_id); + let item_def_id = tcx.hir().local_def_id(item_id); + let generics = tcx.generics_of(item_def_id.to_def_id()); + let index = generics.param_def_id_to_index[&def_id]; + let name = tcx.hir().name(hir_id); + let ty_const = tcx.mk_const(ty::ConstS { + val: ty::ConstKind::Param(ty::ParamConst::new(index, name)), + ty, + }); + + return Self::Ty(ty_const); + } + _ => {} + } + + let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let parent_substs = if let Some(parent_hir_id) = tcx.hir().find_parent_node(hir_id) { + if let Some(parent_did) = tcx.hir().opt_local_def_id(parent_hir_id) { + InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) + } else { + tcx.mk_substs(Vec::>::new().into_iter()) + } + } else { + tcx.mk_substs(Vec::>::new().into_iter()) + }; + debug!(?parent_substs); + + let did = def.did.to_def_id(); + let child_substs = InternalSubsts::identity_for_item(tcx, did); + let substs = tcx.mk_substs(parent_substs.into_iter().chain(child_substs.into_iter())); + debug!(?substs); + + let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let span = tcx.hir().span(hir_id); + let uneval = ty::Unevaluated::new(def.to_global(), substs); + debug!(?span, ?param_env); + + match tcx.const_eval_resolve(param_env, uneval, Some(span)) { + Ok(val) => Self::Val(val, ty), + Err(_) => { + // Error was handled in `const_eval_resolve`. Here we just create a + // new unevaluated const and error hard later in codegen let ty_const = tcx.mk_const(ty::ConstS { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), @@ -2934,6 +3000,7 @@ impl<'tcx> ConstantKind<'tcx> { }), ty, }); + Self::Ty(ty_const) } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 67384242ffa81..7ef33011234fc 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -491,8 +491,11 @@ impl<'tcx> Cx<'tcx> { hir::InlineAsmOperand::Const { ref anon_const } => { let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = - mir::ConstantKind::from_anon_const(self.tcx, anon_const_def_id); + let value = mir::ConstantKind::from_anon_const( + self.tcx, + anon_const_def_id, + self.param_env, + ); let span = self.tcx.hir().span(anon_const.hir_id); InlineAsmOperand::Const { value, span } From 14e3d038c002956fe07d8862e420ed37d7c194fc Mon Sep 17 00:00:00 2001 From: b-naber Date: Sat, 2 Apr 2022 12:17:07 +0200 Subject: [PATCH 7/9] rebase and remove dead code --- .../rustc_const_eval/src/const_eval/mod.rs | 70 ------------ compiler/rustc_const_eval/src/lib.rs | 8 -- compiler/rustc_middle/src/mir/mod.rs | 108 +----------------- compiler/rustc_middle/src/mir/query.rs | 9 +- compiler/rustc_middle/src/query/mod.rs | 16 --- compiler/rustc_mir_build/src/thir/cx/mod.rs | 23 +--- .../rustc_mir_build/src/thir/pattern/mod.rs | 4 +- 7 files changed, 4 insertions(+), 234 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 4ea0c89c27b3a..6fd7f707e7e5d 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -172,40 +172,6 @@ pub(crate) fn try_destructure_const<'tcx>( Ok(mir::DestructuredConst { variant, fields }) } -pub(crate) fn destructure_mir_constant<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - val: mir::ConstantKind<'tcx>, -) -> mir::DestructuredMirConstant<'tcx> { - trace!("destructure_const: {:?}", val); - let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.mir_const_to_op(&val, None).unwrap(); - - // We go to `usize` as we cannot allocate anything bigger anyway. - let (field_count, variant, down) = match val.ty().kind() { - ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op), - ty::Adt(def, _) if def.variants().is_empty() => { - return mir::DestructuredMirConstant { variant: None, fields: &[] }; - } - ty::Adt(def, _) => { - let variant = ecx.read_discriminant(&op).unwrap().1; - let down = ecx.operand_downcast(&op, variant).unwrap(); - (def.variants()[variant].fields.len(), Some(variant), down) - } - ty::Tuple(substs) => (substs.len(), None, op), - _ => bug!("cannot destructure constant {:?}", val), - }; - - let fields_iter = (0..field_count).map(|i| { - let field_op = ecx.operand_field(&down, i).unwrap(); - let val = op_to_const(&ecx, &field_op); - mir::ConstantKind::Val(val, field_op.layout.ty) - }); - let fields = tcx.arena.alloc_from_iter(fields_iter); - - mir::DestructuredMirConstant { variant, fields } -} - pub(crate) fn deref_const<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -241,39 +207,3 @@ pub(crate) fn deref_const<'tcx>( tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty }) } - -#[instrument(skip(tcx), level = "debug")] -pub(crate) fn deref_mir_constant<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - val: mir::ConstantKind<'tcx>, -) -> mir::ConstantKind<'tcx> { - let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.mir_const_to_op(&val, None).unwrap(); - let mplace = ecx.deref_operand(&op).unwrap(); - if let Some(alloc_id) = mplace.ptr.provenance { - assert_eq!( - tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().0.0.mutability, - Mutability::Not, - "deref_const cannot be used with mutable allocations as \ - that could allow pattern matching to observe mutable statics", - ); - } - - let ty = match mplace.meta { - MemPlaceMeta::None => mplace.layout.ty, - MemPlaceMeta::Poison => bug!("poison metadata in `deref_const`: {:#?}", mplace), - // In case of unsized types, figure out the real type behind. - MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { - ty::Str => bug!("there's no sized equivalent of a `str`"), - ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()), - _ => bug!( - "type {} should not have metadata, but had {:?}", - mplace.layout.ty, - mplace.meta - ), - }, - }; - - mir::ConstantKind::Val(op_to_const(&ecx, &mplace.into()), ty) -} diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 493c8ec5fdd0c..d688331ae0a56 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -45,10 +45,6 @@ pub fn provide(providers: &mut Providers) { let (param_env, value) = param_env_and_value.into_parts(); const_eval::try_destructure_const(tcx, param_env, value).ok() }; - providers.destructure_mir_constant = |tcx, param_env_and_value| { - let (param_env, value) = param_env_and_value.into_parts(); - const_eval::destructure_mir_constant(tcx, param_env, value) - }; providers.const_to_valtree = |tcx, param_env_and_value| { let (param_env, raw) = param_env_and_value.into_parts(); const_eval::const_to_valtree(tcx, param_env, raw) @@ -57,8 +53,4 @@ pub fn provide(providers: &mut Providers) { let (param_env, value) = param_env_and_value.into_parts(); const_eval::deref_const(tcx, param_env, value) }; - providers.deref_mir_constant = |tcx, param_env_and_value| { - let (param_env, value) = param_env_and_value.into_parts(); - const_eval::deref_mir_constant(tcx, param_env, value) - } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9b39c61719c88..9c2a6f205e052 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2721,8 +2721,8 @@ impl<'tcx> ConstantKind<'tcx> { } } - #[inline] /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. + #[inline] pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 { self.try_eval_bits(tcx, param_env, ty) .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self)) @@ -2793,112 +2793,6 @@ impl<'tcx> ConstantKind<'tcx> { Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty)) } - #[instrument(skip(tcx), level = "debug")] - pub fn try_eval_lit_or_param( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - expr: &'tcx hir::Expr<'tcx>, - ) -> Option { - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments - // currently have to be wrapped in curly brackets, so it's necessary to special-case. - let expr = match &expr.kind { - hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { - block.expr.as_ref().unwrap() - } - _ => expr, - }; - - let lit_input = match expr.kind { - hir::ExprKind::Lit(ref lit) => { - Some(interpret::LitToConstInput { lit: &lit.node, ty, neg: false }) - } - hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind { - hir::ExprKind::Lit(ref lit) => { - Some(interpret::LitToConstInput { lit: &lit.node, ty, neg: true }) - } - _ => None, - }, - _ => None, - }; - - if let Some(lit_input) = lit_input { - // If an error occurred, ignore that it's a literal and leave reporting the error up to - // mir. - match tcx.at(expr.span).lit_to_mir_constant(lit_input) { - Ok(c) => return Some(c), - Err(e) => { - tcx.sess.delay_span_bug( - expr.span, - &format!("Const::from_anon_const: couldn't lit_to_const {:?}", e), - ); - } - } - } - use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; - match expr.kind { - ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { - // Find the name and index of the const parameter by indexing the generics of - // the parent item and construct a `ParamConst`. - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - let item_id = tcx.hir().get_parent_node(hir_id); - let item_def_id = tcx.hir().local_def_id(item_id); - let generics = tcx.generics_of(item_def_id.to_def_id()); - let index = generics.param_def_id_to_index[&def_id]; - let name = tcx.hir().name(hir_id); - let ty_const = tcx.mk_const(ty::ConstS { - val: ty::ConstKind::Param(ty::ParamConst::new(index, name)), - ty, - }); - - Some(Self::Ty(ty_const)) - } - _ => None, - } - } - - #[instrument(skip(tcx), level = "debug")] - pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - - let body_id = match tcx.hir().get(hir_id) { - hir::Node::AnonConst(ac) => ac.body, - _ => span_bug!( - tcx.def_span(def_id.to_def_id()), - "from_inline_const can only process anonymous constants" - ), - }; - - let expr = &tcx.hir().body(body_id).value; - - let ty = tcx.typeck(def_id).node_type(hir_id); - - let ret = match Self::try_eval_lit_or_param(tcx, ty, expr) { - Some(v) => v, - None => { - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()); - let parent_substs = - tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id)); - let substs = ty::InlineConstSubsts::new( - tcx, - ty::InlineConstSubstsParts { parent_substs, ty }, - ) - .substs; - let ty_const = tcx.mk_const(ty::ConstS { - val: ty::ConstKind::Unevaluated(ty::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs, - promoted: None, - }), - ty, - }); - - Self::Ty(ty_const) - } - }; - debug_assert!(!ret.has_free_regions()); - ret - } - /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly /// converted to a constant, everything else becomes `Unevaluated`. pub fn from_anon_const( diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 978ed55c4e48e..cee510a42413a 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,6 +1,6 @@ //! Values computed by queries that use MIR. -use crate::mir::{self, Body, Promoted}; +use crate::mir::{Body, Promoted}; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::stable_map::FxHashMap; use rustc_data_structures::vec_map::VecMap; @@ -421,13 +421,6 @@ pub struct DestructuredConst<'tcx> { pub fields: &'tcx [ty::Const<'tcx>], } -/// The constituent parts of an ADT or array. -#[derive(Copy, Clone, Debug, HashStable)] -pub struct DestructuredMirConstant<'tcx> { - pub variant: Option, - pub fields: &'tcx [mir::ConstantKind<'tcx>], -} - /// Coverage information summarized from a MIR if instrumented for source code coverage (see /// compiler option `-Cinstrument-coverage`). This information is generated by the /// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3d783a0d64c29..d382b9c58a27b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -940,13 +940,6 @@ rustc_queries! { remap_env_constness } - /// Destructure an `mir::ConstantKind` ADT or array into its variant index - /// and its field values. - query destructure_mir_constant(key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>) -> mir::DestructuredMirConstant<'tcx> { - desc { "destructure mir constant"} - remap_env_constness - } - /// Dereference a constant reference or raw pointer and turn the result into a constant /// again. query deref_const( @@ -956,15 +949,6 @@ rustc_queries! { remap_env_constness } - /// Dereference a constant reference or raw pointer and turn the result into a constant - /// again. - query deref_mir_constant( - key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> - ) -> mir::ConstantKind<'tcx> { - desc { "deref constant" } - remap_env_constness - } - query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { desc { "get a &core::panic::Location referring to a span" } } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 820434bd37300..f17fe38b292cb 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -5,7 +5,6 @@ use crate::thir::pattern::pat_from_hir; use crate::thir::util::UserAnnotatedTyHelpers; -use rustc_ast::ast; use rustc_data_structures::steal::Steal; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -13,10 +12,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::HirId; use rustc_hir::Node; use rustc_middle::middle::region; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; -use rustc_middle::mir::ConstantKind; use rustc_middle::thir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; crate fn thir_body<'tcx>( @@ -78,24 +75,6 @@ impl<'tcx> Cx<'tcx> { } } - #[instrument(skip(self), level = "debug")] - crate fn const_eval_literal( - &mut self, - lit: &'tcx ast::LitKind, - ty: Ty<'tcx>, - sp: Span, - neg: bool, - ) -> ConstantKind<'tcx> { - match self.tcx.at(sp).lit_to_mir_constant(LitToConstInput { lit, ty, neg }) { - Ok(c) => c, - Err(LitToConstError::Reported) => { - // create a dummy value and continue compiling - ConstantKind::Ty(self.tcx.const_error(ty)) - } - Err(LitToConstError::TypeError) => bug!("const_eval_literal: had type error"), - } - } - crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> { let p = match self.tcx.hir().get(p.hir_id) { Node::Pat(p) | Node::Binding(p) => p, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 38c944b98d360..59b9d2c927929 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -739,7 +739,6 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { } } -// FIXME: Get rid of this function once valtrees land #[instrument(skip(tcx), level = "debug")] crate fn compare_const_vals<'tcx>( tcx: TyCtxt<'tcx>, @@ -759,8 +758,7 @@ crate fn compare_const_vals<'tcx>( // Early return for equal constants (so e.g. references to ZSTs can be compared, even if they // are just integer addresses). - // FIXME This might be wrong - if a == b { + if a.val() == b.val() { return from_bool(true); } From c3491378e3420a19dc98708a2953df5c524c2681 Mon Sep 17 00:00:00 2001 From: b-naber Date: Wed, 6 Apr 2022 10:12:42 +0200 Subject: [PATCH 8/9] get rid of visit_constant in thir visitor --- compiler/rustc_middle/src/thir/visit.rs | 10 ++++++++-- compiler/rustc_middle/src/ty/util.rs | 14 ++++++++------ .../rustc_mir_build/src/thir/pattern/mod.rs | 6 ++---- .../src/traits/const_evaluatable.rs | 4 ---- .../src/matches/overlapping_arms.rs | 17 +++++++++-------- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index ab9e966063340..ef7becde69a66 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -1,7 +1,6 @@ use super::{ Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir, }; -use crate::mir::ConstantKind; pub trait Visitor<'a, 'tcx: 'a>: Sized { fn thir(&self) -> &'a Thir<'tcx>; @@ -26,7 +25,14 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized { walk_pat(self, pat); } - fn visit_constant(&mut self, _constant: ConstantKind<'tcx>) {} + // Note: We don't have visitors for `ty::Const` and `mir::ConstantKind` + // (even though these types occur in THIR) for consistency and to reduce confusion, + // since the lazy creation of constants during thir construction causes most + // 'constants' to not be of type `ty::Const` or `mir::ConstantKind` at that + // stage (they are mostly still identified by `DefId` or `hir::Lit`, see + // the variants `Literal`, `NonHirLiteral` and `NamedConst` in `thir::ExprKind`). + // You have to manually visit `ty::Const` and `mir::ConstantKind` through the + // other `visit*` functions. } pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 960f9c0acd48d..7d9a917d04c76 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -662,8 +662,8 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { impl<'tcx> Ty<'tcx> { /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. - pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option { - match self.kind() { + pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { + let val = match self.kind() { ty::Int(_) | ty::Uint(_) => { let (size, signed) = int_size_and_signed(tcx, self); let val = @@ -676,13 +676,14 @@ impl<'tcx> Ty<'tcx> { ty::FloatTy::F64 => rustc_apfloat::ieee::Double::INFINITY.to_bits(), }), _ => None, - } + }; + val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self))) } /// Returns the minimum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. - pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option { - match self.kind() { + pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { + let val = match self.kind() { ty::Int(_) | ty::Uint(_) => { let (size, signed) = int_size_and_signed(tcx, self); let val = if signed { size.truncate(size.signed_int_min() as u128) } else { 0 }; @@ -694,7 +695,8 @@ impl<'tcx> Ty<'tcx> { ty::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(), }), _ => None, - } + }; + val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self))) } /// Checks whether values of this type `T` are *moved* or *copied* diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 59b9d2c927929..dbcd701c1addd 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -183,12 +183,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Some((*lo, *hi)) } (Some(PatKind::Constant { value: lo }), None) => { - let hi = ty.numeric_max_val(self.tcx)?; - Some((*lo, ty::Const::from_bits(self.tcx, hi, ty::ParamEnv::empty().and(ty)))) + Some((*lo, ty.numeric_max_val(self.tcx)?)) } (None, Some(PatKind::Constant { value: hi })) => { - let lo = ty.numeric_min_val(self.tcx)?; - Some((ty::Const::from_bits(self.tcx, lo, ty::ParamEnv::empty().and(ty)), *hi)) + Some((ty.numeric_min_val(self.tcx)?, *hi)) } _ => None, } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 498412b5cfd17..b409bc3d64e3f 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -376,10 +376,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { visit::walk_pat(self, pat); } } - - fn visit_constant(&mut self, ct: mir::ConstantKind<'tcx>) { - self.is_poly |= ct.has_param_types_or_consts(); - } } let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs index b5fa847451d1f..c0b3e95b18523 100644 --- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{constant, constant_full_int, FullInt}; +use clippy_utils::consts::{constant, constant_full_int, miri_to_const, FullInt}; use clippy_utils::diagnostics::span_lint_and_note; use core::cmp::Ordering; use rustc_hir::{Arm, Expr, PatKind, RangeEnd}; @@ -32,15 +32,16 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) .filter_map(|arm| { if let Arm { pat, guard: None, .. } = *arm { if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind { - let lhs_val = match lhs { - Some(lhs) => constant(cx, cx.typeck_results(), lhs)?.0.int_value(cx, ty)?, - None => FullInt::U(ty.numeric_min_val(cx.tcx)?), + let lhs_const = match lhs { + Some(lhs) => constant(cx, cx.typeck_results(), lhs)?.0, + None => miri_to_const(ty.numeric_min_val(cx.tcx)?)?, }; - let rhs_val = match rhs { - Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0.int_value(cx, ty)?, - None => FullInt::U(ty.numeric_max_val(cx.tcx)?), + let rhs_const = match rhs { + Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0, + None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?, }; - + let lhs_val = lhs_const.int_value(cx, ty)?; + let rhs_val = rhs_const.int_value(cx, ty)?; let rhs_bound = match range_end { RangeEnd::Included => EndBound::Included(rhs_val), RangeEnd::Excluded => EndBound::Excluded(rhs_val), From 3be987e076ad6b90a3679036ff71f639e9553ffa Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 8 Apr 2022 11:56:21 +0200 Subject: [PATCH 9/9] dont make lit_to_mir_constant a query --- compiler/rustc_middle/src/query/mod.rs | 4 -- .../src/build/expr/as_constant.rs | 57 ++++++++++++++++++- compiler/rustc_mir_build/src/lib.rs | 1 - compiler/rustc_mir_build/src/thir/constant.rs | 51 ----------------- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d382b9c58a27b..14c11187fc5ee 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -960,10 +960,6 @@ rustc_queries! { desc { "converting literal to const" } } - query lit_to_mir_constant(key: LitToConstInput<'tcx>) -> Result, LitToConstError> { - desc { "converting literal to mir constant" } - } - query check_match(key: DefId) { desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 4a2f544970564..8b9b1847e7f0e 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -1,12 +1,16 @@ //! See docs in build/expr/mod.rs use crate::build::Builder; +use crate::thir::constant::parse_float; +use rustc_ast as ast; use rustc_hir::def_id::DefId; +use rustc_middle::mir::interpret::Allocation; use rustc_middle::mir::interpret::{ConstValue, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; +use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that @@ -27,7 +31,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Literal { lit, neg } => { let literal = - match tcx.lit_to_mir_constant(LitToConstInput { lit: &lit.node, ty, neg }) { + match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) { Ok(c) => c, Err(LitToConstError::Reported) => ConstantKind::Ty(tcx.const_error(ty)), Err(LitToConstError::TypeError) => { @@ -84,3 +88,54 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } } + +#[instrument(skip(tcx, lit_input))] +fn lit_to_mir_constant<'tcx>( + tcx: TyCtxt<'tcx>, + lit_input: LitToConstInput<'tcx>, +) -> Result, LitToConstError> { + let LitToConstInput { lit, ty, neg } = lit_input; + let trunc = |n| { + let param_ty = ty::ParamEnv::reveal_all().and(ty); + let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; + trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); + let result = width.truncate(n); + trace!("trunc result: {}", result); + Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) + }; + + let value = match (lit, &ty.kind()) { + (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { + let s = s.as_str(); + let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); + let allocation = tcx.intern_const_alloc(allocation); + ConstValue::Slice { data: allocation, start: 0, end: s.len() } + } + (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) + if matches!(inner_ty.kind(), ty::Slice(_)) => + { + let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); + let allocation = tcx.intern_const_alloc(allocation); + ConstValue::Slice { data: allocation, start: 0, end: data.len() } + } + (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { + let id = tcx.allocate_bytes(data); + ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) + } + (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { + ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) + } + (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { + trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })? + } + (ast::LitKind::Float(n, _), ty::Float(fty)) => { + parse_float(*n, *fty, neg).ok_or(LitToConstError::Reported)? + } + (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), + (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), + (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported), + _ => return Err(LitToConstError::TypeError), + }; + + Ok(ConstantKind::Val(value, ty)) +} diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 10be229f08495..6687e1160ede8 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -27,7 +27,6 @@ use rustc_middle::ty::query::Providers; pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; providers.lit_to_const = thir::constant::lit_to_const; - providers.lit_to_mir_constant = thir::constant::lit_to_mir_constant; providers.mir_built = build::mir_built; providers.thir_check_unsafety = check_unsafety::thir_check_unsafety; providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg; diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 3fc3e7338d85e..30d7fdb7fec36 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -3,7 +3,6 @@ use rustc_ast as ast; use rustc_middle::mir::interpret::{ Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; -use rustc_middle::mir::ConstantKind; use rustc_middle::ty::{self, ParamEnv, TyCtxt}; use rustc_span::symbol::Symbol; use rustc_target::abi::Size; @@ -59,56 +58,6 @@ crate fn lit_to_const<'tcx>( Ok(ty::Const::from_value(tcx, lit, ty)) } -crate fn lit_to_mir_constant<'tcx>( - tcx: TyCtxt<'tcx>, - lit_input: LitToConstInput<'tcx>, -) -> Result, LitToConstError> { - let LitToConstInput { lit, ty, neg } = lit_input; - let trunc = |n| { - let param_ty = ty::ParamEnv::reveal_all().and(ty); - let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; - trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); - let result = width.truncate(n); - trace!("trunc result: {}", result); - Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) - }; - - let value = match (lit, &ty.kind()) { - (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { - let s = s.as_str(); - let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); - let allocation = tcx.intern_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: s.len() } - } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) - if matches!(inner_ty.kind(), ty::Slice(_)) => - { - let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); - let allocation = tcx.intern_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: data.len() } - } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { - let id = tcx.allocate_bytes(data); - ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) - } - (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { - ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) - } - (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { - trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })? - } - (ast::LitKind::Float(n, _), ty::Float(fty)) => { - parse_float(*n, *fty, neg).ok_or(LitToConstError::Reported)? - } - (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), - (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), - (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported), - _ => return Err(LitToConstError::TypeError), - }; - - Ok(ConstantKind::Val(value, ty)) -} - // FIXME move this to rustc_mir_build::build pub(crate) fn parse_float<'tcx>( num: Symbol,