summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
AgeCommit message (Collapse)AuthorLines
2025-02-15add a doc commentRalf Jung-0/+1
2025-02-15made check_argument_compat publicgeetanshjuneja-1/+1
2025-02-13Auto merge of #136593 - lukas-code:ty-value-perf, r=oli-obkbors-27/+21
valtree performance tuning Summary: This PR makes type checking of code with many type-level constants faster. After https://github.com/rust-lang/rust/pull/136180 was merged, we observed a small perf regression (https://github.com/rust-lang/rust/pull/136318#issuecomment-2635562821). This happened because that PR introduced additional copies in the fast reject code path for consts, which is very hot for certain crates: https://github.com/rust-lang/rust/blob/6c1d960d88dd3755548b3818630acb63fa98187e/compiler/rustc_type_ir/src/fast_reject.rs#L486-L487 This PR improves the performance again by properly interning the valtrees so that copying and comparing them becomes faster. This will become especially useful with `feature(adt_const_params)`, so the fast reject code doesn't have to do a deep compare of the valtrees. Note that we can't just compare the interned consts themselves in the fast reject, because sometimes `'static` lifetimes in the type are be replaced with inference variables (due to canonicalization) on one side but not the other. A less invasive alternative that I considered is simply avoiding copies introduced by https://github.com/rust-lang/rust/pull/136180 and comparing the valtrees it in-place (see commit: https://github.com/rust-lang/rust/commit/9e91e50ac5920f0b9b4a3b1e0880c85336ba5c64 / perf results: https://github.com/rust-lang/rust/pull/136593#issuecomment-2642303245), however that was still measurably slower than interning. There are some minor regressions in secondary benchmarks: These happen due to changes in memory allocations and seem acceptable to me. The crates that make heavy use of valtrees show no significant changes in memory usage.
2025-02-13simplify valtree branches constructionLukas Markeffsky-15/+12
2025-02-13intern valtreesLukas Markeffsky-14/+11
2025-02-12Auto merge of #135994 - 1c3t3a:rename-unsafe-ptr, r=oli-obkbors-4/+4
Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptr The wording unsafe pointer is less common and not mentioned in a lot of places, instead this is usually called a "raw pointer". For the sake of uniformity, we rename this method. This came up during the review of https://github.com/rust-lang/rust/pull/134424. r? `@Noratrieb`
2025-02-11Rollup merge of #136833 - workingjubilee:let-the-impossible-be-impossible, ↵Matthias Krüger-13/+0
r=compiler-errors compiler: die immediately instead of handling unknown target codegen We cannot produce anything useful if asked to compile unknown targets. We should handle the error immediately at the point of discovery instead of propagating it upward, and preferably in the simplest way: Die. This allows cleaning up our "error-handling" spread across 5 crates.
2025-02-11fix ensure_monomorphic_enoughLukas Markeffsky-41/+3
2025-02-10compiler: die immediately instead of handling unknown target codegenJubilee Young-13/+0
We cannot produce anything useful if asked to compile unknown targets. We should handle the error immediately at the point of discovery instead of propagating it upward, and preferably in the simplest way: Die. This allows cleaning up our "error-handling" spread across 5 crates.
2025-02-10Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptrBastian Kersting-4/+4
The wording unsafe pointer is less common and not mentioned in a lot of places, instead this is usually called a "raw pointer". For the sake of uniformity, we rename this method. This came up during the review of https://github.com/rust-lang/rust/pull/134424.
2025-02-08Rustfmtbjorn3-36/+46
2025-02-06Rollup merge of #136235 - oli-obk:transmuty-pat-tys, r=RalfJungMatthias Krüger-13/+44
Pretty print pattern type values with transmute if they don't satisfy their pattern Instead of printing `0_u32 is 1..`, we now print the default fallback rendering that we also use for invalid bools, chars, ...: `{transmute(0x00000000): (u32) is 1..=}`. These cases can occur in mir dumps when const prop propagates a constant across a safety check that would prevent the actually UB value from existing. That's fine though, as it's dead code and we always need to allow UB in dead code. follow-up to https://github.com/rust-lang/rust/pull/136176 cc ``@compiler-errors`` ``@scottmcm`` r? ``@RalfJung`` because of the interpreter changes
2025-02-05Pretty print pattern type values with `transmute` if they don't satisfy ↵Oli Scherer-13/+44
their pattern
2025-02-05Rollup merge of #128045 - pnkfelix:rustc-contracts, r=oli-obkLeón Orell Valerian Liehr-1/+16
#[contracts::requires(...)] + #[contracts::ensures(...)] cc https://github.com/rust-lang/rust/issues/128044 Updated contract support: attribute syntax for preconditions and postconditions, implemented via a series of desugarings that culminates in: 1. a compile-time flag (`-Z contract-checks`) that, similar to `-Z ub-checks`, attempts to ensure that the decision of enabling/disabling contract checks is delayed until the end user program is compiled, 2. invocations of lang-items that handle invoking the precondition, building a checker for the post-condition, and invoking that post-condition checker at the return sites for the function, and 3. intrinsics for the actual evaluation of pre- and post-condition predicates that third-party verification tools can intercept and reinterpret for their own purposes (e.g. creating shims of behavior that abstract away the function body and replace it solely with the pre- and post-conditions). Known issues: * My original intent, as described in the MCP (https://github.com/rust-lang/compiler-team/issues/759) was to have a rustc-prefixed attribute namespace (like rustc_contracts::requires). But I could not get things working when I tried to do rewriting via a rustc-prefixed builtin attribute-macro. So for now it is called `contracts::requires`. * Our attribute macro machinery does not provide direct support for attribute arguments that are parsed like rust expressions. I spent some time trying to add that (e.g. something that would parse the attribute arguments as an AST while treating the remainder of the items as a token-tree), but its too big a lift for me to undertake. So instead I hacked in something approximating that goal, by semi-trivially desugaring the token-tree attribute contents into internal AST constucts. This may be too fragile for the long-term. * (In particular, it *definitely* breaks when you try to add a contract to a function like this: `fn foo1(x: i32) -> S<{ 23 }> { ... }`, because its token-tree based search for where to inject the internal AST constructs cannot immediately see that the `{ 23 }` is within a generics list. I think we can live for this for the short-term, i.e. land the work, and continue working on it while in parallel adding a new attribute variant that takes a token-tree attribute alongside an AST annotation, which would completely resolve the issue here.) * the *intent* of `-Z contract-checks` is that it behaves like `-Z ub-checks`, in that we do not prematurely commit to including or excluding the contract evaluation in upstream crates (most notably, `core` and `std`). But the current test suite does not actually *check* that this is the case. Ideally the test suite would be extended with a multi-crate test that explores the matrix of enabling/disabling contracts on both the upstream lib and final ("leaf") bin crates.
2025-02-03Contracts core intrinsics.Felix S. Klock II-1/+16
These are hooks to: 1. control whether contract checks are run 2. allow 3rd party tools to intercept and reintepret the results of running contracts.
2025-02-03Rollup merge of #136430 - FedericoBruzzone:follow-up-136180, r=oli-obkMatthias Krüger-27/+25
Use the type-level constant value `ty::Value` where needed **Follow-up to #136180** ### Summary This PR refactors functions to accept a single type-level constant value `ty::Value` instead of separate `ty::ValTree` and `ty::Ty` parameters: - `valtree_to_const_value`: now takes `ty::Value` - `pretty_print_const_valtree`: now takes `ty::Value` - Uses `pretty_print_const_valtree` for formatting valtrees when `visit_const_operand` - Moves `try_to_raw_bytes` from `ty::Valtree` to `ty::Value` --- r? ``@lukas-code`` ``@oli-obk``
2025-02-03Refactor using the type-level constant value `ty::Value`FedericoBruzzone-27/+25
Signed-off-by: FedericoBruzzone <federico.bruzzone.i@gmail.com>
2025-02-03Rollup merge of #136464 - nnethercote:rm-TyCtxtAt-for-hooks, r=oli-obk许杰友 Jieyou Xu (Joe)-9/+9
Remove hook calling via `TyCtxtAt`. All hooks receive a `TyCtxtAt` argument. Currently hooks can be called through `TyCtxtAt` or `TyCtxt`. In the latter case, a `TyCtxtAt` is constructed with a dummy span and passed to the hook. However, in practice hooks are never called through `TyCtxtAt`, and always receive a dummy span. (I confirmed this via code inspection, and double-checked it by temporarily making the `TyCtxtAt` code path panic and running all the tests.) This commit removes all the `TyCtxtAt` machinery for hooks. All hooks now receive `TyCtxt` instead of `TyCtxtAt`. There are two existing hooks that use `TyCtxtAt::span`: `const_caller_location_provider` and `try_destructure_mir_constant_for_user_output`. For both hooks the span is always a dummy span, probably unintentionally. This dummy span use is now explicit. If a non-dummy span is needed for these two hooks it would be easy to add it as an extra argument because hooks are less constrained than queries. r? `@oli-obk`
2025-02-03Rollup merge of #136438 - RalfJung:offset_from_ub_errors, r=oli-obk许杰友 Jieyou Xu (Joe)-1/+19
miri: improve error when offset_from preconditions are violated Fixes https://github.com/rust-lang/miri/issues/4143
2025-02-03Remove hook calling via `TyCtxtAt`.Nicholas Nethercote-9/+9
All hooks receive a `TyCtxtAt` argument. Currently hooks can be called through `TyCtxtAt` or `TyCtxt`. In the latter case, a `TyCtxtAt` is constructed with a dummy span and passed to the hook. However, in practice hooks are never called through `TyCtxtAt`, and always receive a dummy span. (I confirmed this via code inspection, and double-checked it by temporarily making the `TyCtxtAt` code path panic and running all the tests.) This commit removes all the `TyCtxtAt` machinery for hooks. All hooks now receive `TyCtxt` instead of `TyCtxtAt`. There are two existing hooks that use `TyCtxtAt::span`: `const_caller_location_provider` and `try_destructure_mir_constant_for_user_output`. For both hooks the span is always a dummy span, probably unintentionally. This dummy span use is now explicit. If a non-dummy span is needed for these two hooks it would be easy to add it as an extra argument because hooks are less constrained than queries.
2025-02-02Check the base type of pattern types for validity firstOli Scherer-5/+4
2025-02-02Test validity of pattern typesOli Scherer-0/+12
2025-02-02miri: improve error when offset_from preconditions are violatedRalf Jung-1/+19
2025-02-01Rollup merge of #130514 - compiler-errors:unsafe-binders, r=oli-obkMatthias Krüger-2/+18
Implement MIR lowering for unsafe binders This is the final bit of the unsafe binders puzzle. It implements MIR, CTFE, and codegen for unsafe binders, and enforces that (for now) they are `Copy`. Later on, I'll introduce a new trait that relaxes this requirement to being "is `Copy` or `ManuallyDrop<T>`" which more closely models how we treat union fields. Namely, wrapping unsafe binders is now `Rvalue::WrapUnsafeBinder`, which acts much like an `Rvalue::Aggregate`. Unwrapping unsafe binders are implemented as a MIR projection `ProjectionElem::UnwrapUnsafeBinder`, which acts much like `ProjectionElem::Field`. Tracking: - https://github.com/rust-lang/rust/issues/130516
2025-02-01Rollup merge of #136348 - RalfJung:miri-float-min-max, r=oli-obkMatthias Krüger-2/+20
miri: make float min/max non-deterministic This makes Miri match the documentation that landed in https://github.com/rust-lang/rust/pull/136296. r? ``@oli-obk``
2025-01-31Auto merge of #136350 - matthiaskrgr:rollup-6eqfyvh, r=matthiaskrgrbors-1/+6
Rollup of 9 pull requests Successful merges: - #134531 ([rustdoc] Add `--extract-doctests` command-line flag) - #135860 (Compiler: Finalize dyn compatibility renaming) - #135992 (Improve documentation when adding a new target) - #136194 (Support clobber_abi in BPF inline assembly) - #136325 (Delay a bug when indexing unsized slices) - #136326 (Replace our `LLVMRustDIBuilderRef` with LLVM-C's `LLVMDIBuilderRef`) - #136330 (Remove unnecessary hooks) - #136336 (Overhaul `rustc_middle::util`) - #136341 (Remove myself from vacation) r? `@ghost` `@rustbot` modify labels: rollup
2025-01-31ValidationMichael Goulet-0/+2
2025-01-31Implement MIR, CTFE, and codegen for unsafe bindersMichael Goulet-2/+16
2025-01-31Auto merge of #134424 - 1c3t3a:null-checks, r=saethlinbors-0/+1
Insert null checks for pointer dereferences when debug assertions are enabled Similar to how the alignment is already checked, this adds a check for null pointer dereferences in debug mode. It is implemented similarly to the alignment check as a `MirPass`. This inserts checks in the same places as the `CheckAlignment` pass and additionally also inserts checks for `Borrows`, so code like ```rust let ptr: *const u32 = std::ptr::null(); let val: &u32 = unsafe { &*ptr }; ``` will have a check inserted on dereference. This is done because null references are UB. The alignment check doesn't cover these places, because in `&(*ptr).field`, the exact requirement is that the final reference must be aligned. This is something to consider further enhancements of the alignment check. For now this is implemented as a separate `MirPass`, to make it easy to disable this check if necessary. This is related to a 2025H1 project goal for better UB checks in debug mode: https://github.com/rust-lang/rust-project-goals/pull/177. r? `@saethlin`
2025-01-31Rollup merge of #136325 - compiler-errors:indirectly, r=RalfJungMatthias Krüger-1/+6
Delay a bug when indexing unsized slices Fixes #136298 r? RalfJung or reassign
2025-01-31Insert null checks for pointer dereferences when debug assertions are enabledBastian Kersting-0/+1
Similar to how the alignment is already checked, this adds a check for null pointer dereferences in debug mode. It is implemented similarly to the alignment check as a MirPass. This is related to a 2025H1 project goal for better UB checks in debug mode: https://github.com/rust-lang/rust-project-goals/pull/177.
2025-01-31miri: make float min/max non-deterministicRalf Jung-2/+20
2025-01-31Auto merge of #135318 - compiler-errors:vtable-fixes, r=lcnrbors-48/+53
Fix deduplication mismatches in vtables leading to upcasting unsoundness We currently have two cases where subtleties in supertraits can trigger disagreements in the vtable layout, e.g. leading to a different vtable layout being accessed at a callsite compared to what was prepared during unsizing. Namely: ### #135315 In this example, we were not normalizing supertraits when preparing vtables. In the example, ``` trait Supertrait<T> { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); } } impl<T> Supertrait<T> for () {} trait Identity { type Selff; } impl<Selff> Identity for Selff { type Selff = Selff; } trait Middle<T>: Supertrait<()> + Supertrait<T> { fn say_hello(&self, _: &usize) { println!("Hello!"); } } impl<T> Middle<T> for () {} trait Trait: Middle<<() as Identity>::Selff> {} impl Trait for () {} fn main() { (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); } ``` When we prepare `dyn Trait`, we see a supertrait of `Middle<<() as Identity>::Selff>`, which itself has two supertraits `Supertrait<()>` and `Supertrait<<() as Identity>::Selff>`. These two supertraits are identical, but they are not duplicated because we were using structural equality and *not* considering normalization. This leads to a vtable layout with two trait pointers. When we upcast to `dyn Middle<()>`, those two supertraits are now the same, leading to a vtable layout with only one trait pointer. This leads to an offset error, and we call the wrong method. ### #135316 This one is a bit more interesting, and is the bulk of the changes in this PR. It's a bit similar, except it uses binder equality instead of normalization to make the compiler get confused about two vtable layouts. In the example, ``` trait Supertrait<T> { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); } } impl<T> Supertrait<T> for () {} trait Trait<T, U>: Supertrait<T> + Supertrait<U> { fn say_hello(&self, _: &usize) { println!("Hello!"); } } impl<T, U> Trait<T, U> for () {} fn main() { (&() as &'static dyn for<'a> Trait<&'static (), &'a ()> as &'static dyn Trait<&'static (), &'static ()>) .say_hello(&0); } ``` When we prepare the vtable for `dyn for<'a> Trait<&'static (), &'a ()>`, we currently consider the PolyTraitRef of the vtable as the key for a supertrait. This leads two two supertraits -- `Supertrait<&'static ()>` and `for<'a> Supertrait<&'a ()>`. However, we can upcast[^up] without offsetting the vtable from `dyn for<'a> Trait<&'static (), &'a ()>` to `dyn Trait<&'static (), &'static ()>`. This is just instantiating the principal trait ref for a specific `'a = 'static`. However, when considering those supertraits, we now have only one distinct supertrait -- `Supertrait<&'static ()>` (which is deduplicated since there are two supertraits with the same substitutions). This leads to similar offsetting issues, leading to the wrong method being called. [^up]: I say upcast but this is a cast that is allowed on stable, since it's not changing the vtable at all, just instantiating the binder of the principal trait ref for some lifetime. The solution here is to recognize that a vtable isn't really meaningfully higher ranked, and to just treat a vtable as corresponding to a `TraitRef` so we can do this deduplication more faithfully. That is to say, the vtable for `dyn for<'a> Tr<'a>` and `dyn Tr<'x>` are always identical, since they both would correspond to a set of free regions on an impl... Do note that `Tr<for<'a> fn(&'a ())>` and `Tr<fn(&'static ())>` are still distinct. ---- There's a bit more that can be cleaned up. In codegen, we can stop using `PolyExistentialTraitRef` basically everywhere. We can also fix SMIR to stop storing `PolyExistentialTraitRef` in its vtable allocations. As for testing, it's difficult to actually turn this into something that can be tested with `rustc_dump_vtable`, since having multiple supertraits that are identical is a recipe for ambiguity errors. Maybe someone else is more creative with getting that attr to work, since the tests I added being run-pass tests is a bit unsatisfying. Miri also doesn't help here, since it doesn't really generate vtables that are offset by an index in the same way as codegen. r? `@lcnr` for the vibe check? Or reassign, idk. Maybe let's talk about whether this makes sense. <sup>(I guess an alternative would also be to not do any deduplication of vtable supertraits (or only a really conservative subset) rather than trying to normalize and deduplicate more faithfully here. Not sure if that works and is sufficient tho.)</sup> cc `@steffahn` -- ty for the minimizations cc `@WaffleLapkin` -- since you're overseeing the feature stabilization :3 Fixes #135315 Fixes #135316
2025-01-31Delay a bug when indexing unsized slicesMichael Goulet-1/+6
2025-01-30More assertions, tests, and miri coverageMichael Goulet-47/+52
2025-01-30add commentsLukas Markeffsky-1/+2
2025-01-30introduce `ty::Value`Lukas Markeffsky-3/+8
Co-authored-by: FedericoBruzzone <federico.bruzzone.i@gmail.com>
2025-01-30Normalize vtable entries before walking and deduplicating themMichael Goulet-1/+8
2025-01-30Do not treat vtable supertraits as distinct when bound with different bound varsMichael Goulet-10/+3
2025-01-30Auto merge of #136035 - SpecificProtagonist:miri-zeroed-alloc, r=oli-obkbors-16/+25
miri: optimize zeroed alloc When allocating zero-initialized memory in MIR interpretation, rustc allocates zeroed memory, marks it as initialized and then re-zeroes it. Remove the last step. I don't expect this to have much of an effect on performance normally, but in my case in which I'm creating a large allocation via mmap it gets in the way.
2025-01-29Rollup merge of #136166 - RalfJung:interpet-is-alloc-live, r=compiler-errorsLeón Orell Valerian Liehr-2/+4
interpret: is_alloc_live: check global allocs last See https://github.com/rust-lang/rust/pull/136105#discussion_r1930609553. (A perf run makes no sense as this is only used by Miri.)
2025-01-28Auto merge of #136203 - matthiaskrgr:rollup-1k0f44l, r=matthiaskrgrbors-109/+118
Rollup of 9 pull requests Successful merges: - #135869 (Make docs for AtomicUsize::from_mut platform-independent) - #135892 (-Znext-solver: "normalize" signature before checking it mentions self in `deduce_closure_signature`) - #136055 (Implement MIR const trait stability checks) - #136066 (Pass spans to `perform_locally_in_new_solver`) - #136071 ([Clippy] Add vec_reserve & vecdeque_reserve diagnostic items) - #136124 (Arbitrary self types v2: explain test.) - #136149 (Flip the `rustc-rayon`/`indexmap` dependency order) - #136173 (Update comments and sort target_arch in c_char_definition) - #136178 (Update username in build helper example) r? `@ghost` `@rustbot` modify labels: rollup
2025-01-28Rollup merge of #136055 - fee1-dead-contrib:push-ovmyztlkptmk, r=RalfJungMatthias Krüger-109/+118
Implement MIR const trait stability checks Addresses https://github.com/rust-lang/project-const-traits/issues/16 cc ``@rust-lang/project-const-traits`` r? ``@RalfJung``
2025-01-28miri: optimize zeroed allocSpecificProtagonist-16/+25
Co-authored-by: Ralf Jung <post@ralfj.de>
2025-01-28Implement MIR const trait stability checksDeadbeef-109/+118
2025-01-28interpret: is_alloc_live: check global allocs lastRalf Jung-2/+4
2025-01-28Represent the raw pointer for a array length check as a new kind of fake borrowMichael Goulet-21/+15
2025-01-27Reapply "Auto merge of #133734 - scottmcm:lower-indexing-to-ptrmetadata, ↵Michael Goulet-7/+31
r=davidtwco,RalfJung" This reverts commit 122a55bb442bd1995df9cf9b36e6f65ed3ef4a1d.
2025-01-27Add `TooGeneric` variant to `LayoutError` and emit `Unknown` oneFedericoBruzzone-1/+1
- `check-pass` test for a MRE of #135020 - fail test for #135138 - switch to `TooGeneric` for checking CMSE fn signatures - switch to `TooGeneric` for compute `SizeSkeleton` (for transmute) - fix broken tests
2025-01-19Rollup merge of #134858 - estebank:issue-81370, r=NoratriebGuillaume Gomez-4/+33
Provide structured suggestion for `#![feature(..)]` in more cases Fix #81370.