about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/messages.ftl
AgeCommit message (Collapse)AuthorLines
2025-08-17Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obkbors-5/+6
const-eval: full support for pointer fragments This fixes https://github.com/rust-lang/const-eval/issues/72 and makes `swap_nonoverlapping` fully work in const-eval by enhancing per-byte provenance tracking with tracking of *which* of the bytes of the pointer this one is. Later, if we see all the same bytes in the exact same order, we can treat it like a whole pointer again without ever risking a leak of the data bytes (that encode the offset into the allocation). This lifts the limitation that was discussed quite a bit in https://github.com/rust-lang/rust/pull/137280. For a concrete piece of code that used to fail and now works properly consider this example doing a byte-for-byte memcpy in const without using intrinsics: ```rust use std::{mem::{self, MaybeUninit}, ptr}; type Byte = MaybeUninit<u8>; const unsafe fn memcpy(dst: *mut Byte, src: *const Byte, n: usize) { let mut i = 0; while i < n { *dst.add(i) = *src.add(i); i += 1; } } const _MEMCPY: () = unsafe { let ptr = &42; let mut ptr2 = ptr::null::<i32>(); // Copy from ptr to ptr2. memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>()); assert!(*ptr2 == 42); }; ``` What makes this code tricky is that pointers are "opaque blobs" in const-eval, we cannot just let people look at the individual bytes since *we don't know what those bytes look like* -- that depends on the absolute address the pointed-to object will be placed at. The code above "breaks apart" a pointer into individual bytes, and then puts them back together in the same order elsewhere. This PR implements the logic to properly track how those individual bytes relate to the original pointer, and to recognize when they are in the right order again. We still reject constants where the final value contains a not-fully-put-together pointer: I have no idea how one could construct an LLVM global where one byte is defined as "the 3rd byte of a pointer to that other global over there" -- and even if LLVM supports this somehow, we can leave implementing that to a future PR. It seems unlikely to me anyone would even want this, but who knows.^^ This also changes the behavior of Miri, by tracking the order of bytes with provenance and only considering a pointer to have valid provenance if all bytes are in the original order again. This is related to https://github.com/rust-lang/unsafe-code-guidelines/issues/558. It means one cannot implement XOR linked lists with strict provenance any more, which is however only of theoretical interest. Practically I am curious if anyone will show up with any code that Miri now complains about - that would be interesting data. Cc `@rust-lang/opsem`
2025-07-30const-eval: full support for pointer fragmentsRalf Jung-5/+6
2025-07-27miri: for ABI mismatch errors, say which argument is the problemRalf Jung-3/+3
2025-07-17Rollup merge of #143595 - fee1-dead-contrib:push-sylpykzkmynr, ↵León Orell Valerian Liehr-0/+11
r=RalfJung,fee1-dead add `const_make_global`; err for `const_allocate` ptrs if didn't call Implements as discussed on Zulip: [#t-compiler/const-eval > const heap](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/const.20heap/with/527125421) r? ```@rust-lang/wg-const-eval``` Fixes https://github.com/rust-lang/rust/issues/129233
2025-07-16Rollup merge of #143692 - RalfJung:miri-oob, r=oli-obkSamuel Tardieu-12/+15
miri: fix out-of-bounds error for ptrs with negative offsets r? ```````@oli-obk```````
2025-07-16add `const_make_global`; err for `const_allocate` ptrs if didn't callDeadbeef-0/+11
Co-Authored-By: Ralf Jung <post@ralfj.de> Co-Authored-By: Oli Scherer <github333195615777966@oli-obk.de>
2025-07-09miri: fix out-of-bounds error for ptrs with negative offsetsRalf Jung-12/+15
2025-07-09Add opaque TypeId handles for CTFEOli Scherer-0/+2
2025-06-30Remove the nullary intrinsic const eval logic and treat them like other ↵Oli Scherer-3/+0
intrinsics
2025-06-27Rollup merge of #143092 - RalfJung:const-check-lifetime-ext, r=oli-obkMatthias Krüger-18/+10
const checks for lifetime-extended temporaries: avoid 'top-level scope' terminology This error recently got changed in https://github.com/rust-lang/rust/pull/140942 to use the terminology of "top-level scope", but after further discussion in https://github.com/rust-lang/reference/pull/1865 it seems the reference will not be using that terminology after all. So let's also remove it from the compiler again, and let's focus on what actually happens with these temporaries: their lifetime is extended until the end of the program. r? ``@oli-obk`` ``@traviscross``
2025-06-27const checks: avoid 'top-level scope' terminologyRalf Jung-18/+10
2025-06-27const-eval: error when initializing a static writes to that staticRalf Jung-1/+1
2025-06-26clarify and unify 'transient mutable borrow' errorsRalf Jung-17/+10
2025-06-26const-eval: allow constants to refer to mutable/external memory, but reject ↵Ralf Jung-5/+1
such constants as patterns
2025-06-07const-eval error: always say in which item the error occurredRalf Jung-5/+3
also adjust the wording a little so that we don't say "the error occurred here" for two different spans
2025-06-03Rollup merge of #141698 - oli-obk:ctfe-err-flip, r=RalfJungMatthias Krüger-3/+3
Use the informative error as the main const eval error message r? `@RalfJung` I only did the minimal changes necessary to the const eval error machinery. I'd prefer not to mix test changes with refactorings 😆
2025-06-03Rollup merge of #141569 - workingjubilee:canonicalize-abi, r=bjorn3Matthias Krüger-1/+1
Replace ad-hoc ABI "adjustments" with an `AbiMap` to `CanonAbi` Our `conv_from_spec_abi`, `adjust_abi`, and `is_abi_supported` combine to give us a very confusing way of reasoning about what _actual_ calling convention we want to lower our code to and whether we want to compile the resulting code at all. Instead of leaving this code as a miniature adventure game in which someone tries to combine stateful mutations into a Rube Goldberg machine that will let them escape the maze and arrive at the promised land of codegen, we let `AbiMap` devour this complexity. Once you have an `AbiMap`, you can answer which `ExternAbi`s will lower to what `CanonAbi`s (and whether they will lower at all). Removed: - `conv_from_spec_abi` replaced by `AbiMap::canonize_abi` - `adjust_abi` replaced by same - `Conv::PreserveAll` as unused - `Conv::Cold` as unused - `enum Conv` replaced by `enum CanonAbi` target-spec.json changes: - If you have a target-spec.json then now your "entry-abi" key will be specified in terms of one of the `"{abi}"` strings Rust recognizes, e.g. ```json "entry-abi": "C", "entry-abi": "win64", "entry-abi": "aapcs", ```
2025-06-03compiler: change Conv to CanonAbiJubilee Young-1/+1
2025-06-02Clarify why we are talking about a failed const eval at a random placeOli Scherer-3/+3
2025-05-25const-check: stop recommending the use of rustc_allow_const_fn_unstableRalf Jung-2/+1
2025-04-30interpret: better error message for out-of-bounds pointer arithmetic and ↵Ralf Jung-35/+35
accesses
2025-03-20Use def_path_str for def id arg in UnsupportedOpInfoMichael Goulet-2/+2
2025-02-28Shorten span of panic failures in const contextEsteban Küber-2/+3
Previously, we included a redundant prefix on the panic message and a postfix of the location of the panic. The prefix didn't carry any additional information beyond "something failed", and the location of the panic is redundant with the diagnostic's span, which gets printed out even if its code is not shown. ``` error[E0080]: evaluation of constant value failed --> $DIR/assert-type-intrinsics.rs:11:9 | LL | MaybeUninit::<!>::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: aborted execution: attempted to instantiate uninhabited type `!` ``` ``` error[E0080]: evaluation of `Fail::<i32>::C` failed --> $DIR/collect-in-dead-closure.rs:9:19 | LL | const C: () = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` ``` error[E0080]: evaluation of constant value failed --> $DIR/uninhabited.rs:41:9 | LL | assert!(false); | ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- When the primary span for a const error is the same as the first frame in the const error report, skip it. ``` error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>` --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` instead of ``` error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() | ^^^^^^^^ explicit panic | note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>` --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() | ^^^^^^^^ note: inside `_CONST` --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- Revert order of constant evaluation errors Point at the code the user wrote first and std functions last. ``` error[E0080]: evaluation of constant value failed --> $DIR/const-errs-dont-conflict-103369.rs:5:25 | LL | impl ConstGenericTrait<{my_fn(1)}> for () {} | ^^^^^^^^ evaluation panicked: Some error occurred | note: called from `my_fn` --> $DIR/const-errs-dont-conflict-103369.rs:10:5 | LL | panic!("Some error occurred"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` instead of ``` error[E0080]: evaluation of constant value failed --> $DIR/const-errs-dont-conflict-103369.rs:10:5 | LL | panic!("Some error occurred"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some error occurred | note: called from `<() as ConstGenericTrait<{my_fn(1)}>>::{constant#0}` --> $DIR/const-errs-dont-conflict-103369.rs:5:25 | LL | impl ConstGenericTrait<{my_fn(1)}> for () {} | ^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ```
2025-02-02miri: improve error when offset_from preconditions are violatedRalf Jung-1/+3
2025-01-28Implement MIR const trait stability checksDeadbeef-1/+2
2025-01-25Fix typo in const stability error messageDeadbeef-1/+1
2025-01-18Structured suggestion for "missing `feature` intrinsic"Esteban Küber-1/+1
``` error: `size_of_val` is not yet stable as a const intrinsic --> $DIR/const-unstable-intrinsic.rs:17:9 | LL | unstable_intrinsic::size_of_val(&x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unstable)]` to the crate attributes to enable help: add `#![feature(unstable)]` to the crate attributes to enable | LL + #![feature("unstable")] | ```
2025-01-09Unify conditional and non const call error reportingMichael Goulet-8/+6
2025-01-09Make the non-const part swappable in the diagnosticMichael Goulet-27/+32
2024-12-23Note def descr in NonConstFunctionCallMichael Goulet-1/+1
2024-11-22Get rid of HIR const checkerMichael Goulet-4/+4
2024-11-18rename rustc_const_stable_intrinsic -> rustc_intrinsic_const_stable_indirectRalf Jung-1/+1
2024-11-09require const_impl_trait gate for all conditional and trait const callsRalf Jung-0/+4
2024-11-04add new rustc_const_stable_intrinsic attribute for const-stable intrinsicsRalf Jung-1/+1
2024-11-03remove const-support for align_offsetRalf Jung-3/+0
Operations like is_aligned would return actively wrong results at compile-time, i.e. calling it on the same pointer at compiletime and runtime could yield different results. That's no good. Instead of having hacks to make align_offset kind-of work in const-eval, just use const_eval_select in the few places where it makes sense, which also ensures those places are all aware they need to make sure the fallback behavior is consistent.
2024-10-25Re-do recursive const stability checksRalf Jung-7/+20
Fundamentally, we have *three* disjoint categories of functions: 1. const-stable functions 2. private/unstable functions that are meant to be callable from const-stable functions 3. functions that can make use of unstable const features This PR implements the following system: - `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions. - `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category. - `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls. Also, several holes in recursive const stability checking are being closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to *not* be `rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine. The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability. Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
2024-10-08fix/update teach_note from 'escaping mutable ref/ptr' const-checkRalf Jung-25/+26
2024-09-23Check vtable projections for validity in miriMichael Goulet-2/+2
2024-09-15also stabilize const_refs_to_cellRalf Jung-3/+0
2024-09-15stabilize const_mut_refsRalf Jung-7/+0
2024-08-31make the const-unstable-in-stable error more clearRalf Jung-2/+2
2024-08-26interpret: do not make const-eval query result depend on tcx.sessRalf Jung-3/+0
2024-08-25tweak rustc_allow_const_fn_unstable hint, and add back test for ↵Ralf Jung-1/+1
stable-const-can-only-call-stable-const
2024-08-10rustc_const_eval: make LazyLock suggestion translatablePavel Grigorenko-0/+3
2024-08-10rustc_const_eval: make message about "const stable" translatablePavel Grigorenko-0/+2
2024-08-02Rollup merge of #128453 - RalfJung:raw_eq, r=saethlinMatthias Krüger-3/+0
raw_eq: using it on bytes with provenance is not UB (outside const-eval) The current behavior of raw_eq violates provenance monotonicity. See https://github.com/rust-lang/rust/pull/124921 for an explanation of provenance monotonicity. It is violated in raw_eq because comparing bytes without provenance is well-defined, but adding provenance makes the operation UB. So remove the no-provenance requirement from raw_eq. However, the requirement stays in-place for compile-time invocations of raw_eq, that indeed cannot deal with provenance. Cc `@rust-lang/opsem`
2024-08-01fix the way we detect overflow for inbounds arithmetic (and tweak the error ↵Ralf Jung-1/+1
message)
2024-08-01on a signed deref check, mention the right pointer in the errorRalf Jung-10/+25
2024-07-31raw_eq: using it on bytes with provenance is not UB (outside const-eval)Ralf Jung-3/+0
2024-07-27improve dangling/oob errors and make them more uniformRalf Jung-8/+19