Skip to content

Start using pattern types in libcore#136006

Open
oli-obk wants to merge 1 commit intorust-lang:mainfrom
oli-obk:push-tzonluoyuwkq
Open

Start using pattern types in libcore#136006
oli-obk wants to merge 1 commit intorust-lang:mainfrom
oli-obk:push-tzonluoyuwkq

Conversation

@oli-obk
Copy link
Copy Markdown
Contributor

@oli-obk oli-obk commented Jan 24, 2025

View all comments

cc #135996

Replaces the innards of NonNull with *const T is !null.

This does affect LLVM's optimizations, as now reading the field preserves the metadata that the field is not null, and transmuting to another type (e.g. just a raw pointer), will also preserve that information for optimizations. This can cause LLVM opts to do more work, but it's not guaranteed to produce better machine code.

Once we also remove all uses of rustc_layout_scalar_range_start from rustc itself, we can remove the support for that attribute entirely and handle all such needs via pattern types

@rustbot

This comment was marked as outdated.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jan 24, 2025
@oli-obk oli-obk added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 24, 2025
@rust-log-analyzer

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well r=me when/if it does get unblocked.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Jan 27, 2025

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@Veykril
Copy link
Copy Markdown
Member

Veykril commented Jan 27, 2025

Re rust-analyzer blocker, as it turns out to implement pattern types (to a degree that would unblock this) it comes down to the same architecture changes required as for rust-lang/rust-analyzer#7434 (which I am currently looking into), so that will take a bit.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Jan 27, 2025

Some changes occurred to the CTFE machinery

cc @rust-lang/wg-const-eval

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

@oli-obk
Copy link
Copy Markdown
Contributor Author

oli-obk commented Mar 7, 2026

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 7, 2026

☀️ Try build successful (CI)
Build commit: 72aec09 (72aec09742d9339443f6e63421b7babc09c33c3d, parent: ea5573a6c6e5e932f917ec4a8e6d8efdeb9f394d)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (72aec09): comparison URL.

Overall result: ❌ regressions - please read the text below

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.2% [0.1%, 0.2%] 6
Regressions ❌
(secondary)
0.1% [0.1%, 0.1%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.2% [0.1%, 0.2%] 6

Max RSS (memory usage)

Results (primary 2.4%, secondary 5.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
2.4% [1.7%, 2.9%] 3
Regressions ❌
(secondary)
5.8% [5.8%, 5.8%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.4% [1.7%, 2.9%] 3

Cycles

This benchmark run did not return any relevant results for this metric.

Binary size

Results (primary 0.1%, secondary 0.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.1% [0.1%, 0.1%] 1
Regressions ❌
(secondary)
0.1% [0.1%, 0.1%] 9
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.1% [0.1%, 0.1%] 1

Bootstrap: 480.191s -> 478.416s (-0.37%)
Artifact size: 395.10 MiB -> 395.20 MiB (0.03%)

@oli-obk
Copy link
Copy Markdown
Contributor Author

oli-obk commented Mar 7, 2026

The entire regression is in rustdoc lowering (clean). Unsure why, but it's also very tiny. Likely a more structural issue. Rustdoc clean should not end up seeing any pattern types

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@oli-obk
Copy link
Copy Markdown
Contributor Author

oli-obk commented Mar 12, 2026

cc @BoxyUwU

@oli-obk
Copy link
Copy Markdown
Contributor Author

oli-obk commented Mar 24, 2026

r? compiler

@rust-bors

This comment has been minimized.

// While we can't project into `NonNull<_>` in a basic block
// due to MCP#807, this is debug info where it's fine.
// While we can't project into a pattern type in a basic block,
// this is debug info where it's fine.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"it's fine" because the pattern type is erased in the debug info?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because debug info has no UB, we can just do whatever works instead of having to worry about soundness

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's less about soundness and more that debug info doesn't need to worry about losing the validity restriction information. We don't want to load an i32 from an i32 is 1.. because that loses the !range metadata, but in debug info whatever.

@wesleywiser
Copy link
Copy Markdown
Member

I think this thread from @scottmcm is still open: #136006 (comment)

Should we split the compiler and library changes?

@rustbot

This comment has been minimized.

@oli-obk
Copy link
Copy Markdown
Contributor Author

oli-obk commented Apr 7, 2026

Should we split the compiler and library changes?

I already split everything out that I could. I tried splitting it further but box (and thus NonNull) is just so entangled between the compiler and libcore that it's really hard to do in a way that even some of the compiler changes can be landed and tested

@rust-log-analyzer

This comment has been minimized.

Copy link
Copy Markdown
Member

@wesleywiser wesleywiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one small comment, r=me

View changes since this review

test_abi_compatible!(zst_unit, Zst, ());
test_abi_compatible!(zst_array, Zst, [u8; 0]);
test_abi_compatible!(nonzero_int, NonZero<i32>, i32);
test_abi_compatible!(nonzero_int, pattern_type!(i32 is 1..=0x7FFF_FFFF), i32);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the pattern types be added as new cases rather than changing the test for NonZero?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, yea that was me being lazy. I changed minicore to support i32 for NonZero.

@wesleywiser
Copy link
Copy Markdown
Member

r? wesleywiser

@oli-obk
Copy link
Copy Markdown
Contributor Author

oli-obk commented Apr 8, 2026

@bors r=wesleywiser

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Apr 8, 2026

📌 Commit 2bbf86e has been approved by wesleywiser

It is now in the queue for this repository.

@rust-log-analyzer

This comment has been minimized.

@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors r-
CI failed

@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors r-
github listen please?

@JonathanBrouwer
Copy link
Copy Markdown
Contributor

JonathanBrouwer commented Apr 8, 2026

Oh huh this PR never got S-waiting-on-bors (which I was hoping to see removed) even though it was actually in the queue, github moment I guess

Copy link
Copy Markdown
Member

@scottmcm scottmcm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty good 🎉

I'm glad you found a way to get the change down to something pretty small -- when it's more minicore fixes than "real" changes it makes me happier.

EDIT: wow, I missed this had gotten a review. I should go sleep stop looking at code, apparently.

View changes since this review

let dst_ty = dst.layout.ty;
match (src_ty.kind(), dst_ty.kind()) {
(&ty::Pat(s, sp), &ty::Pat(d, dp))
if let (PatternKind::NotNull, PatternKind::NotNull) = (*sp, *dp) =>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsure: does the specific kind of pattern really matter here? Would just

Suggested change
if let (PatternKind::NotNull, PatternKind::NotNull) = (*sp, *dp) =>
if sp == dp =>

be ok?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if we ever end up with anything but a NotNull, I'm worried, so I like running into the bug! case at the end. Maybe in the future we will support other things, but I'm not sure they should go down the same code path here

// While we can't project into `NonNull<_>` in a basic block
// due to MCP#807, this is debug info where it's fine.
// While we can't project into a pattern type in a basic block,
// this is debug info where it's fine.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's less about soundness and more that debug info doesn't need to worry about losing the validity restriction information. We don't want to load an i32 from an i32 is 1.. because that loses the !range metadata, but in debug info whatever.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 9, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job x86_64-gnu-llvm-21 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
---- [ui] tests/ui/consts/const-eval/raw-bytes.rs stdout ----
Saved the actual 32bit.stderr to `/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/consts/const-eval/raw-bytes/raw-bytes.32bit.stderr`
diff of 32bit.stderr:

53                78 00 00 00 ff ff ff ff                         │ x.......
54            }
55 
- error[E0080]: constructing invalid value of type NonNull<u8> at .pointer: encountered 0, but expected something greater or equal to 1
+ error[E0080]: constructing invalid value of type NonNull<u8>: at .pointer, encountered 0, but expected something greater or equal to 1
57   --> $DIR/raw-bytes.rs:58:1
58    |
59 LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };

108                14 00 00 00                                     │ ....
109            }
110 
- error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1
+ error[E0080]: constructing invalid value of type NonNull<dyn Send>: at .pointer, encountered 0, but expected something greater or equal to 1
112   --> $DIR/raw-bytes.rs:78:1
113    |
114 LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {


The actual 32bit.stderr differed from the expected 32bit.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args consts/const-eval/raw-bytes.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/consts/const-eval/raw-bytes.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=i686-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/consts/const-eval/raw-bytes" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/i686-unknown-linux-gnu/native/rust-test-helpers" "-Clinker=x86_64-linux-gnu-gcc"
stdout: none
--- stderr -------------------------------
error[E0080]: constructing invalid value of type Enum: at .<enum-tag>, encountered 0x00000001, but expected a valid enum tag
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:23:1
   |
LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
   | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               01 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type Enum2: at .<enum-tag>, encountered 0x00000000, but expected a valid enum tag
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:31:1
   |
LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               00 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered an uninhabited enum variant
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:45:1
   |
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 1, align: 1) {
               01                                              │ .
           }

error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered 0x03, but expected a valid enum tag
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:47:1
   |
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 1, align: 1) {
               03                                              │ .
           }

error[E0080]: constructing invalid value of type Option<(char, char)>: at .<enum-variant(Some)>.0.1, encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:53:1
   |
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               78 00 00 00 ff ff ff ff                         │ x.......
           }

error[E0080]: constructing invalid value of type NonNull<u8>: at .pointer, encountered 0, but expected something greater or equal to 1
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:58:1
   |
LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               00 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type NonZero<u8>: at .0.0, encountered 0, but expected something greater or equal to 1
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:61:1
   |
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 1, align: 1) {
               00                                              │ .
           }

error[E0080]: constructing invalid value of type NonZero<usize>: at .0.0, encountered 0, but expected something greater or equal to 1
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:63:1
   |
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               00 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type RestrictedRange1: encountered 42, but expected something in the range 10..=30
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:69:1
   |
LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               2a 00 00 00                                     │ *...
           }

error[E0080]: constructing invalid value of type RestrictedRange2: encountered 20, but expected something less or equal to 10, or greater or equal to 30
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:75:1
   |
LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               14 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type NonNull<dyn Send>: at .pointer, encountered 0, but expected something greater or equal to 1
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:78:1
   |
LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               00 00 00 00 ╾─alloc32─╼                         │ ....╾──╼
           }

error[E0080]: constructing invalid value of type &u16: encountered an unaligned reference (required 2 byte alignment but found 1)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:85:1
   |
LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
   | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               ╾a38<imm>─╼                                     │ ╾──╼
           }

error[E0080]: constructing invalid value of type Box<u16>: encountered an unaligned box (required 2 byte alignment but found 1)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:88:1
   |
LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               ╾a42<imm>─╼                                     │ ╾──╼
           }

error[E0080]: constructing invalid value of type &u16: encountered a null reference
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:91:1
   |
LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
   | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               00 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type Box<u16>: encountered a null box
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:94:1
   |
LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               00 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type &u8: encountered a dangling reference (0x539[noalloc] has no provenance)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:97:1
   |
LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               39 05 00 00                                     │ 9...
           }

error[E0080]: constructing invalid value of type Box<u8>: encountered a dangling box (0x539[noalloc] has no provenance)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:100:1
   |
LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               39 05 00 00                                     │ 9...
           }

error[E0080]: constructing invalid value of type fn(): encountered null pointer, but expected a function pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:103:1
   |
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               00 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type fn(): encountered 0xd[noalloc], but expected a function pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:105:1
   |
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               0d 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type fn(): encountered alloc58<imm>, but expected a function pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:107:1
   |
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
   | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               ╾a58<imm>─╼                                     │ ╾──╼
           }

error[E0080]: constructing invalid value of type &Bar: encountered a reference pointing to uninhabited type Bar
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:113:1
   |
LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
   | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               01 00 00 00                                     │ ....
           }

error[E0080]: constructing invalid value of type &str: encountered a dangling reference (going beyond the bounds of its allocation)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:137:1
   |
LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a64<imm>─╼ e7 03 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type (&str,): at .0, encountered invalid reference metadata: slice is bigger than largest supported object
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:139:1
   |
LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a69<imm>─╼ ff ff ff ff                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &MyStr: encountered invalid reference metadata: slice is bigger than largest supported object
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:141:1
   |
LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a75<imm>─╼ ff ff ff ff                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &str: at .<deref>, encountered uninitialized memory, but expected a string
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:144:1
   |
LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
   | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a81<imm>─╼ 01 00 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered uninitialized memory, but expected a string
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:146:1
   |
LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a86<imm>─╼ 01 00 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered a pointer, but expected a string
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:148:1
   |
LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = help: this code performed an operation that depends on the underlying bytes representing a pointer
   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
   = 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: 4) {
               ╾a91<imm>─╼ 01 00 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &[u8]: encountered a dangling reference (going beyond the bounds of its allocation)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:152:1
   |
LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a95<imm>─╼ e7 03 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &[u32]: encountered invalid reference metadata: slice is bigger than largest supported object
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:154:1
   |
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a101<imm>╼ ff ff ff 7f                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type Box<[u8]>: encountered a dangling box (going beyond the bounds of its allocation)
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:157:1
   |
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a106<imm>╼ e7 03 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type &[bool; 1]: at .<deref>[0], encountered 0x03, but expected a boolean
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:160:1
   |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               ╾a112<imm>╼                                     │ ╾──╼
           }

note: erroneous constant encountered
  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:160:40
   |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.0, encountered 0x03, but expected a boolean
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:164:1
   |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               ╾a117<imm>╼                                     │ ╾──╼
           }

note: erroneous constant encountered
  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:164:42
   |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.1[0], encountered 0x03, but expected a boolean
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:167:1
   |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {
               ╾a122<imm>╼                                     │ ╾──╼
           }

note: erroneous constant encountered
  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:167:42
   |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered alloc127<imm>, but expected a vtable pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:171:1
   |
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a125<imm>╼ ╾a127<imm>╼                         │ ╾──╼╾──╼
           }

error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered alloc135<imm>, but expected a vtable pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:174:1
   |
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a133<imm>╼ ╾a135<imm>╼                         │ ╾──╼╾──╼
           }

error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered 0x4[noalloc], but expected a vtable pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:177:1
   |
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a141<imm>╼ 04 00 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered alloc150<imm>, but expected a vtable pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:179:1
   |
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a147<imm>╼ ╾a150<imm>╼                         │ ╾──╼╾──╼
           }

error[E0080]: constructing invalid value of type &dyn Trait: at .<deref>.<dyn-downcast(bool)>, encountered 0x03, but expected a boolean
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:182:1
   |
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a156<imm>╼ ╾alloc158─╼                         │ ╾──╼╾──╼
           }

error[E0080]: constructing invalid value of type *const dyn Trait: encountered null pointer, but expected a vtable pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:185:1
   |
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a161<imm>╼ 00 00 00 00                         │ ╾──╼....
           }

error[E0080]: constructing invalid value of type *const dyn Trait: encountered alloc168<imm>, but expected a vtable pointer
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:187:1
   |
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4) {
               ╾a166<imm>╼ ╾a168<imm>╼                         │ ╾──╼╾──╼
           }

error[E0080]: constructing invalid value of type &[!; 1]: encountered a reference pointing to uninhabited type [!; 1]
##[error]  --> /checkout/tests/ui/consts/const-eval/raw-bytes.rs:191:1
   |
LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR constructing invalid value
   | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
   |
   = 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: 4, align: 4) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-test-infra-minicore Area: `minicore` test auxiliary and `//@ add-core-stubs` A-testsuite Area: The testsuite used to check the correctness of rustc O-unix Operating system: Unix-like O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.