about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
AgeCommit message (Collapse)AuthorLines
2024-08-07Auto merge of #128761 - matthiaskrgr:rollup-5p1mlqq, r=matthiaskrgrbors-1230/+1269
Rollup of 9 pull requests Successful merges: - #124944 (On trait bound mismatch, detect multiple crate versions in dep tree) - #125048 (PinCoerceUnsized trait into core) - #128406 (implement BufReader::peek) - #128539 (Forbid unused unsafe in vxworks-specific std modules) - #128687 (interpret: refactor function call handling to be better-abstracted) - #128692 (Add a triagebot mention for `library/Cargo.lock`) - #128710 (Don't ICE when getting an input file name's stem fails) - #128718 (Consider `cfg_attr` checked by `CheckAttrVisitor`) - #128751 (std::thread: set_name implementation proposal for vxWorks.) r? `@ghost` `@rustbot` modify labels: rollup
2024-08-06Rollup merge of #128720 - y21:issue119620, r=compiler-errorsMatthias Krüger-5/+5
Pass the right `ParamEnv` to `might_permit_raw_init_strict` Fixes #119620 `might_permit_raw_init_strict` currently passes an empty `ParamEnv` to the `InterpCx`, instead of the actual `ParamEnv` that was passed in to `check_validity_requirement` at callsite. This leads to ICEs such as the linked issue where for `UnsafeCell<*mut T>` we initially get the layout with the right `ParamEnv` (which suceeds because it can prove that `T: Sized` and therefore `UnsafeCell<*mut T>` has a known layout) but then do the rest with an empty `ParamEnv` where `T: Sized` is not known to hold so getting the layout for `*mut T` later fails. This runs into an assertion in other layout code where it's making the (valid) assumption that, when we already have a layout for a struct (`UnsafeCell<*mut T>`), getting the layout of one of its fields (`*mut T`) should also succeed, which wasn't the case here due to using the wrong `ParamEnv`. So, this PR changes it to just use the same `ParamEnv` all the way throughout.
2024-08-06miri: make vtable addresses not globally uniqueRalf Jung-4/+26
2024-08-06various cleanups based on reviewRalf Jung-55/+54
2024-08-06make some Frame fields more privateRalf Jung-4/+12
2024-08-06interpret: refactor function call handling to be better-abstractedRalf Jung-1230/+1262
2024-08-06pass the right `ParamEnv` to `might_permit_raw_init_strict`y21-5/+5
2024-08-05interpret: move nullary-op evaluation into operator.rsRalf Jung-39/+47
2024-08-03Miri: add a flag to do recursive validity checkingRalf Jung-78/+129
2024-08-02Rollup merge of #128494 - RalfJung:mir-lazy-lists, r=compiler-errorsMatthias Krüger-1/+1
MIR required_consts, mentioned_items: ensure we do not forget to fill these lists Bodies initially get created with empty required_consts and mentioned_items, but at some point those should be filled. Make sure we notice when that is forgotten.
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-01MIR required_consts, mentioned_items: ensure we do not forget to fill these ↵Ralf Jung-1/+1
lists
2024-08-01fix the way we detect overflow for inbounds arithmetic (and tweak the error ↵Ralf Jung-8/+14
message)
2024-08-01interpret: simplify pointer arithmetic logicRalf Jung-23/+7
2024-08-01on a signed deref check, mention the right pointer in the errorRalf Jung-61/+89
2024-07-31raw_eq: using it on bytes with provenance is not UB (outside const-eval)Ralf Jung-3/+0
2024-07-30Auto merge of #128083 - Mark-Simulacrum:bump-bootstrap, r=albertlarsan68bors-11/+3
Bump bootstrap compiler to new beta https://forge.rust-lang.org/release/process.html#master-bootstrap-update-t-2-day-tuesday
2024-07-29Rollup merge of #128277 - RalfJung:offset_from_wildcard, r=oli-obkMatthias Krüger-68/+96
miri: fix offset_from behavior on wildcard pointers offset_from wouldn't behave correctly when the "end" pointer was a wildcard pointer (result of an int2ptr cast) just at the end of the allocation. Fix that by expressing the "same allocation" check in terms of two `check_ptr_access_signed` instead of something specific to offset_from, which is both more canonical and works better with wildcard pointers. The second commit just improves diagnostics: I wanted the "pointer is dangling (has no provenance)" message to say how many bytes of memory it expected to see (since if it were 0 bytes, this would actually be legal, so it's good to tell the user that it's not 0 bytes). And then I was annoying that the error looks so different for when you deref a dangling pointer vs an out-of-bounds pointer so I made them more similar. Fixes https://github.com/rust-lang/miri/issues/3767
2024-07-29Reformat `use` declarations.Nicholas Nethercote-177/+130
The previous commit updated `rustfmt.toml` appropriately. This commit is the outcome of running `x fmt --all` with the new formatting options.
2024-07-28step cfg(bootstrap)Mark Rousskov-11/+3
2024-07-27improve dangling/oob errors and make them more uniformRalf Jung-21/+41
2024-07-27miri: fix offset_from behavior on wildcard pointersRalf Jung-47/+55
2024-07-26Rollup merge of #127950 - nnethercote:rustfmt-skip-on-use-decls, r=cuviperMatthias Krüger-0/+2
Use `#[rustfmt::skip]` on some `use` groups to prevent reordering. `use` declarations will be reformatted in #125443. Very rarely, there is a desire to force a group of `use` declarations together in a way that auto-formatting will break up. E.g. when you want a single comment to apply to a group. #126776 dealt with all of these in the codebase, ensuring that no comments intended for multiple `use` declarations would end up in the wrong place. But some people were unhappy with it. This commit uses `#[rustfmt::skip]` to create these custom `use` groups in an idiomatic way for a few of the cases changed in #126776. This works because rustfmt treats any `use` item annotated with `#[rustfmt::skip]` as a barrier and won't reorder other `use` items around it. r? `@cuviper`
2024-07-24Do not try to reveal hidden types when trying to prove Freeze in the ↵Oli Scherer-1/+27
defining scope
2024-07-21Move all error reporting into rustc_trait_selectionMichael Goulet-1/+1
2024-07-19Rollup merge of #127856 - RalfJung:interpret-cast-sanity, r=oli-obkMatthias Krüger-41/+95
interpret: add sanity check in dyn upcast to double-check what codegen does For dyn receiver calls, we already have two codepaths: look up the function to call by indexing into the vtable, or alternatively resolve the DefId given the dynamic type of the receiver. With debug assertions enabled, the interpreter does both and compares the results. (Without debug assertions we always use the vtable as it is simpler.) This PR does the same for dyn trait upcasts. However, for casts *not* using the vtable is the easier thing to do, so now the vtable path is the debug-assertion-only path. In particular, there are cases where the vtable does not contain a pointer for upcasts but instead reuses the old pointer: when the supertrait vtable is a prefix of the larger vtable. We don't want to expose this optimization and detect UB if people do a transmute assuming this optimization, so we cannot in general use the vtable indexing path. r? ``@oli-obk``
2024-07-19Use `#[rustfmt::skip]` on some `use` groups to prevent reordering.Nicholas Nethercote-0/+2
`use` declarations will be reformatted in #125443. Very rarely, there is a desire to force a group of `use` declarations together in a way that auto-formatting will break up. E.g. when you want a single comment to apply to a group. #126776 dealt with all of these in the codebase, ensuring that no comments intended for multiple `use` declarations would end up in the wrong place. But some people were unhappy with it. This commit uses `#[rustfmt::skip]` to create these custom `use` groups in an idiomatic way for a few of the cases changed in #126776. This works because rustfmt treats any `use` item annotated with `#[rustfmt::skip]` as a barrier and won't reorder other `use` items around it.
2024-07-18valtree construction: keep track of which type was valtree-incompatibleRalf Jung-13/+13
2024-07-18interpret: add sanity check in dyn upcast to double-check what codegen doesRalf Jung-41/+95
2024-07-16Rollup merge of #126776 - nnethercote:rustfmt-use-pre-cleanups-2, r=cuviperTrevor Gross-1/+0
Clean up more comments near use declarations #125443 will reformat all use declarations in the repository. There are a few edge cases involving comments on use declarations that require care. This PR fixes them up so #125443 can go ahead with a simple `x fmt --all`. A follow-up to #126717. r? ``@cuviper``
2024-07-17Avoid comments that describe multiple `use` items.Nicholas Nethercote-1/+0
There are some comments describing multiple subsequent `use` items. When the big `use` reformatting happens some of these `use` items will be reordered, possibly moving them away from the comment. With this additional level of formatting it's not really feasible to have comments of this type. This commit removes them in various ways: - merging separate `use` items when appropriate; - inserting blank lines between the comment and the first `use` item; - outright deletion (for comments that are relatively low-value); - adding a separate "top-level" comment. We also entirely skip formatting for four library files that contain nothing but `pub use` re-exports, where reordering would be painful.
2024-07-16Auto merge of #127638 - adwinwhite:cache_string, r=oli-obkbors-1/+13
Add cache for `allocate_str` Best effort cache for string allocation in const eval. Fixes [rust-lang/miri#3470](https://github.com/rust-lang/miri/issues/3470).
2024-07-15Rollup merge of #124921 - RalfJung:offset-from-same-addr, r=oli-obkMatthias Krüger-15/+18
offset_from: always allow pointers to point to the same address This PR implements the last remaining part of the t-opsem consensus in https://github.com/rust-lang/unsafe-code-guidelines/issues/472: always permits offset_from when both pointers have the same address, no matter how they are computed. This is required to achieve *provenance monotonicity*. Tracking issue: https://github.com/rust-lang/rust/issues/117945 ### What is provenance monotonicity and why does it matter? Provenance monotonicity is the property that adding arbitrary provenance to any no-provenance pointer must never make the program UB. More specifically, in the program state, data in memory is stored as a sequence of [abstract bytes](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#abstract-byte), where each byte can optionally carry provenance. When a pointer is stored in memory, all of the bytes it is stored in carry that provenance. Provenance monotonicity means: if we take some byte that does not have provenance, and give it some arbitrary provenance, then that cannot change program behavior or introduce UB into a UB-free program. We care about provenance monotonicity because we want to allow the optimizer to remove provenance-stripping operations. Removing a provenance-stripping operation effectively means the program after the optimization has provenance where the program before the optimization did not -- since the provenance removal does not happen in the optimized program. IOW, the compiler transformation added provenance to previously provenance-free bytes. This is exactly what provenance monotonicity lets us do. We care about removing provenance-stripping operations because `*ptr = *ptr` is, in general, (likely) a provenance-stripping operation. Specifically, consider `ptr: *mut usize` (or any integer type), and imagine the data at `*ptr` is actually a pointer (i.e., we are type-punning between pointers and integers). Then `*ptr` on the right-hand side evaluates to the data in memory *without* any provenance (because [integers do not have provenance](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html#integers-do-not-have-provenance)). Storing that back to `*ptr` means that the abstract bytes `ptr` points to are the same as before, except their provenance is now gone. This makes `*ptr = *ptr` a provenance-stripping operation (Here we assume `*ptr` is fully initialized. If it is not initialized, evaluating `*ptr` to a value is UB, so removing `*ptr = *ptr` is trivially correct.) ### What does `offset_from` have to do with provenance monotonicity? With `ptr = without_provenance(N)`, `ptr.offset_from(ptr)` is always well-defined and returns 0. By provenance monotonicity, I can now add provenance to the two arguments of `offset_from` and it must still be well-defined. Crucially, I can add *different* provenance to the two arguments, and it must still be well-defined. In other words, this must always be allowed: `ptr1.with_addr(N).offset_from(ptr2.with_addr(N))` (and it returns 0). But the current spec for `offset_from` says that the two pointers must either both be derived from an integer or both be derived from the same allocation, which is not in general true for arbitrary `ptr1`, `ptr2`. To obtain provenance monotonicity, this PR hence changes the spec for offset_from to say that if both pointers have the same address, the function is always well-defined. ### What further consequences does this have? It means the compiler can no longer transform `end2 = begin.offset(end.offset_from(begin))` into `end2 = end`. However, it can still be transformed into `end2 = begin.with_addr(end.addr())`, which later parts of the backend (when provenance has been erased) can trivially turn into `end2 = end`. The only alternative I am aware of is a fundamentally different handling of zero-sized accesses, where a "no provenance" pointer is not allowed to do zero-sized accesses and instead we have a special provenance that indicates "may be used for zero-sized accesses (and nothing else)". `offset` and `offset_from` would then always be UB on a "no provenance" pointer, and permit zero-sized offsets on a "zero-sized provenance" pointer. This achieves provenance monotonicity. That is, however, a breaking change as it contradicts what we landed in https://github.com/rust-lang/rust/pull/117329. It's also a whole bunch of extra UB, which doesn't seem worth it just to achieve that transformation. ### What about the backend? LLVM currently doesn't have an intrinsic for pointer difference, so we anyway cast to integer and subtract there. That's never UB so it is compatible with any relaxation we may want to apply. If LLVM gets a `ptrsub` in the future, then plausibly it will be consistent with `ptradd` and [consider two equal pointers to be inbounds](https://github.com/rust-lang/rust/pull/124921#issuecomment-2205795829).
2024-07-14Add cache for `allocate_str`Adwin White-1/+13
2024-07-08Move trait selection error reporting to its own top-level moduleMichael Goulet-1/+1
2024-07-08Auto merge of #113128 - WaffleLapkin:become_trully_unuwuable, r=oli-obk,RalfJungbors-83/+262
Support tail calls in mir via `TerminatorKind::TailCall` This is one of the interesting bits in tail call implementation — MIR support. This adds a new `TerminatorKind` which represents a tail call: ```rust TailCall { func: Operand<'tcx>, args: Vec<Operand<'tcx>>, fn_span: Span, }, ``` *Structurally* this is very similar to a normal `Call` but is missing a few fields: - `destination` — tail calls don't write to destination, instead they pass caller's destination to the callee (such that eventual `return` will write to the caller of the function that used tail call) - `target` — similarly to `destination` tail calls pass the caller's return address to the callee, so there is nothing to do - `unwind` — I _think_ this is applicable too, although it's a bit confusing - `call_source` — `become` forbids operators and is not created as a lowering of something else; tail calls always come from HIR (at least for now) It might be helpful to read the interpreter implementation to understand what `TailCall` means exactly, although I've tried documenting it too. ----- There are a few `FIXME`-questions still left, ideally we'd be able to answer them during review ':) ----- r? `@oli-obk` cc `@scottmcm` `@DrMeepster` `@JakobDegen`
2024-07-07Fixup conflict with r-l/r/126567Maybe Lapkin-1/+1
2024-07-07add an assertion that machine hook doesn't return NoCleanupMaybe Lapkin-3/+5
2024-07-07Do renames proposed by reviewMaybe Waffle-9/+9
2024-07-07make `StackPop` field names less confusingMaybe Waffle-27/+35
2024-07-07doc fixups from reviewMaybe Waffle-8/+6
2024-07-07add miri tests and a fixmeMaybe Waffle-0/+4
2024-07-07Refactor & fixup interpreter implementation of tail callsMaybe Waffle-70/+162
2024-07-07Refactor common part of evaluating `Call`&`TailCall` in the interpreterMaybe Waffle-63/+56
2024-07-07Support tail calls in the interpreterMaybe Waffle-1/+71
2024-07-07Support tail calls in mir via `TerminatorKind::TailCall`Maybe Waffle-3/+15
2024-07-06offset_from intrinsic: always allow pointers to point to the same addressRalf Jung-15/+18
2024-07-06Rollup merge of #127275 - RalfJung:offset-from-isize-min, r=AmanieuMatthias Krüger-2/+2
offset_from, offset: clearly separate safety requirements the user needs to prove from corollaries that automatically follow By landing https://github.com/rust-lang/rust/pull/116675 we decided that objects larger than `isize::MAX` cannot exist in the address space of a Rust program, which lets us simplify these rules. For `offset_from`, we can even state that the *absolute* distance fits into an `isize`, and therefore exclude `isize::MIN`. This PR also changes Miri to treat an `isize::MIN` difference like the other isize-overflowing cases.
2024-07-04Auto merge of #123781 - RalfJung:miri-fn-identity, r=oli-obkbors-7/+9
Miri function identity hack: account for possible inlining Having a non-lifetime generic is not the only reason a function can be duplicated. Another possibility is that the function may be eligible for cross-crate inlining. So also take into account the inlining attribute in this Miri hack for function pointer identity. That said, `cross_crate_inlinable` will still sometimes return true even for `inline(never)` functions: - when they are `DefKind::Ctor(..) | DefKind::Closure` -- I assume those cannot be `InlineAttr::Never` anyway? - when `cross_crate_inline_threshold == InliningThreshold::Always` so maybe this is still not quite the right criterion to use for function pointer identity.
2024-07-04offset_from: "the difference must fit in an isize" is a corollaryRalf Jung-2/+2
also, isize::MIN is an impossible distance