summary refs log tree commit diff
path: root/compiler/rustc_middle/src/mir/interpret
AgeCommit message (Collapse)AuthorLines
2024-01-30Remove the lifetime from `DiagnosticArgValue`.Nicholas Nethercote-7/+4
Because it's almost always static. This makes `impl IntoDiagnosticArg for DiagnosticArgValue` trivial, which is nice. There are a few diagnostics constructed in `compiler/rustc_mir_build/src/check_unsafety.rs` and `compiler/rustc_mir_transform/src/errors.rs` that now need symbols converted to `String` with `to_string` instead of `&str` with `as_str`, but that' no big deal, and worth it for the simplifications elsewhere.
2024-01-25Auto merge of #119627 - oli-obk:const_prop_lint_n̵o̵n̵sense, r=cjgillotbors-2/+0
Remove all ConstPropNonsense We track all locals and projections on them ourselves within the const propagator and only use the InterpCx to actually do some low level operations or read from constants (via `OpTy` we get for said constants). This helps moving the const prop lint out from the normal pipeline and running it just based on borrowck information. This in turn allows us to make progress on https://github.com/rust-lang/rust/pull/108730#issuecomment-1875557745 there are various follow up cleanups that can be done after this PR (e.g. not matching on Rvalue twice and doing binop checks twice), but lets try landing this one first. r? `@RalfJung`
2024-01-23const prop nonsense eliminatedOli Scherer-2/+0
2024-01-23Auto merge of #119044 - RalfJung:intern-without-types, r=oli-obkbors-2/+8
const-eval interning: get rid of type-driven traversal This entirely replaces our const-eval interner, i.e. the code that takes the final result of a constant evaluation from the local memory of the const-eval machine to the global `tcx` memory. The main goal of this change is to ensure that we can detect mutable references that sneak into this final value -- this is something we want to reject for `static` and `const`, and while const-checking performs some static analysis to ensure this, I would be much more comfortable stabilizing const_mut_refs if we had a dynamic check that sanitizes the final value. (This is generally the approach we have been using on const-eval: do a static check to give nice errors upfront, and then do a dynamic check to be really sure that the properties we need for soundness, actually hold.) We can do this now that https://github.com/rust-lang/rust/pull/118324 landed and each pointer comes with a bit (completely independent of its type) storing whether mutation is permitted through this pointer or not. The new interner is a lot simpler than the old one: previously we did a complete type-driven traversal to determine the mutability of all memory we see, and then a second pass to intern any leftover raw pointers. The new interner simply recursively traverses the allocation holding the final result, and all allocations reachable from it (which can be determined from the raw bytes of the result, without knowing anything about types), and ensures they all get interned. The initial allocation is interned as immutable for `const` and pomoted and non-interior-mutable `static`; all other allocations are interned as immutable for `static`, `const`, and promoted. The main subtlety is justifying that those inner allocations may indeed be interned immutably, i.e., that mutating them later would anyway already be UB: - for promoteds, we rely on the analysis that does promotion to ensure that this is sound. - for `const` and `static`, we check that all pointers in the final result that point to things that are new (i.e., part of this const evaluation) are immutable, i.e., were created via `&<expr>` at a non-interior-mutable type. Mutation through immutable pointers is UB so we are free to intern that memory as immutable. Interning raises an error if it encounters a dangling pointer or a mutable pointer that violates the above rules. I also extended our type-driven const validity checks to ensure that `&mut T` in the final value of a const points to mutable memory, at least if `T` is not zero-sized. This catches cases of people turning `&i32` into `&mut i32` (which would still be considered a read-only pointer). Similarly, when these checks encounter an `UnsafeCell`, they are checking that it lives in mutable memory. (Both of these only traverse the newly created values; if those point to other consts/promoteds, the check stops there. But that's okay, we don't have to catch all the UB.) I co-developed this with the stricter interner changes but I can split it out into a separate PR if you prefer. This PR does have the immediate effect of allowing some new code on stable, for instance: ```rust const CONST_RAW: *const Vec<i32> = &Vec::new() as *const _; ``` Previously that code got rejected since the type-based interner didn't know what to do with that pointer. It's a raw pointer, we cannot trust its type. The new interner does not care about types so it sees no issue with this code; there's an immutable pointer pointing to some read-only memory (storing a `Vec<i32>`), all is good. Accepting this code pretty much commits us to non-type-based interning, but I think that's the better strategy anyway. This PR also leads to slightly worse error messages when the final value of a const contains a dangling reference. Previously we would complete interning and then the type-based validation would detect this dangling reference and show a nice error saying where in the value (i.e., in which field) the dangling reference is located. However, the new interner cannot distinguish dangling references from dangling raw pointers, so it must throw an error when it encounters either of them. It doesn't have an understanding of the value structure so all it can say is "somewhere in this constant there's a dangling pointer". (Later parts of the compiler don't like dangling pointers/references so we have to reject them either during interning or during validation.) This could potentially be improved by doing validation before interning, but that's a larger change that I have not attempted yet. (It's also subtle since we do want validation to use the final mutability bits of all involved allocations, and currently it is interning that marks a bunch of allocations as immutable -- that would have to still happen before validation.) `@rust-lang/wg-const-eval` I hope you are okay with this plan. :) `@rust-lang/lang` paging you in since this accepts new code on stable as explained above. Please let me know if you think FCP is necessary.
2024-01-23Rename `TyCtxt::struct_span_lint_hir` as `TyCtxt::node_span_lint`.Nicholas Nethercote-1/+1
2024-01-22const-eval interner: from-scratch rewrite using mutability information from ↵Ralf Jung-2/+8
provenance rather than types
2024-01-20Auto merge of #119821 - oli-obk:reveal_all_const_evals, r=lcnrbors-2/+2
Always use RevealAll for const eval queries implements what is described in https://github.com/rust-lang/rust/pull/116803#discussion_r1364089471 Using `UserFacing` for const eval does not make sense anymore, unless we significantly change things like avoiding revealing opaque types. New tests are copied from https://github.com/rust-lang/rust/pull/101478
2024-01-19Always use RevealAll for const eval queriesOli Scherer-2/+2
2024-01-10Add `DiagCtxt::delayed_bug`.Nicholas Nethercote-4/+1
We have `span_delayed_bug` and often pass it a `DUMMY_SP`. This commit adds `delayed_bug`, which matches pairs like `err`/`span_err` and `warn`/`span_warn`.
2024-01-04Remove unused `struct_error` function.Nicholas Nethercote-15/+6
2023-12-24Remove `Session` methods that duplicate `DiagCtxt` methods.Nicholas Nethercote-3/+3
Also add some `dcx` methods to types that wrap `TyCtxt`, for easier access.
2023-12-23Give `DiagnosticBuilder` a default type.Nicholas Nethercote-4/+1
`IntoDiagnostic` defaults to `ErrorGuaranteed`, because errors are the most common diagnostic level. It makes sense to do likewise for the closely-related (and much more widely used) `DiagnosticBuilder` type, letting us write `DiagnosticBuilder<'a, ErrorGuaranteed>` as just `DiagnosticBuilder<'a>`. This cuts over 200 lines of code due to many multi-line things becoming single line things.
2023-12-15Don't pass lint back out of lint decoratorMichael Goulet-1/+1
2023-12-07also print 'immutable' flagRalf Jung-25/+12
2023-12-07ctfe interpreter: extend provenance so that it can track whether a pointer ↵Ralf Jung-30/+109
is immutable
2023-12-02Rename `HandlerInner::delay_span_bug` as `HandlerInner::span_delayed_bug`.Nicholas Nethercote-2/+2
Because the corresponding `Level` is `DelayedBug` and `span_delayed_bug` follows the pattern used everywhere else: `span_err`, `span_warning`, etc.
2023-11-26rustc: `hir().local_def_id_to_hir_id()` -> `tcx.local_def_id_to_hir_id()` ↵Vadim Petrochenkov-1/+1
cleanup
2023-11-19Expand Miri's BorTag GC to a Provenance GCBen Kimock-7/+0
2023-11-16Let Miri see the AllocId for all TyCtxt allocationsBen Kimock-0/+7
2023-10-16Auto merge of #114330 - RalfJung:dagling-ptr-deref, r=oli-obkbors-10/+25
don't UB on dangling ptr deref, instead check inbounds on projections This implements https://github.com/rust-lang/reference/pull/1387 in Miri. See that PR for what the change is about. Detecting dangling references in `let x = &...;` is now done by validity checking only, so some tests need to have validity checking enabled. There is no longer inherently a "nodangle" check in evaluating the expression `&*ptr` (aside from the aliasing model). r? `@oli-obk` Based on: - https://github.com/rust-lang/reference/pull/1387 - https://github.com/rust-lang/rust/pull/115524
2023-10-16Auto merge of #116724 - RalfJung:alloc-bytes, r=oli-obkbors-13/+5
interpret: clean up AllocBytes Fixes https://github.com/rust-lang/miri/issues/2836 Nothing has moved here in half a year, so let's just remove these unused stubs -- they need a proper re-design anyway. r? `@oli-obk`
2023-10-15more precise error for 'based on misaligned pointer' caseRalf Jung-8/+18
2023-10-15place evaluation: require the original pointer to be aligned if an access ↵Ralf Jung-2/+9
happens
2023-10-15don't UB on dangling ptr deref, instead check inbounds on projectionsRalf Jung-2/+0
2023-10-14interpret: clean up AllocBytesRalf Jung-13/+5
2023-10-13Format all the let chains in compilerMichael Goulet-1/+3
2023-09-30dont call mir.post_mono_checks in codegenRalf Jung-15/+0
2023-09-20Auto merge of #115827 - eduardosm:miri-sse-reduce-code-dup, r=RalfJungbors-4/+18
miri: reduce code duplication in some SSE/SSE2 intrinsics Reduces code duplication in the Miri implementation of some SSE and SSE2 using generics and rustc_const_eval helper functions. There are also some other minor changes. r? `@RalfJung`
2023-09-19move ConstValue into mirRalf Jung-159/+5
this way we have mir::ConstValue and ty::ValTree as reasonably parallel
2023-09-18Auto merge of #115748 - RalfJung:post-mono, r=oli-obkbors-17/+63
move required_consts check to general post-mono-check function This factors some code that is common between the interpreter and the codegen backends into shared helper functions. Also as a side-effect the interpreter now uses the same `eval` functions as everyone else to get the evaluated MIR constants. Also this is in preparation for another post-mono check that will be needed for (the current hackfix for) https://github.com/rust-lang/rust/issues/115709: ensuring that all locals are dynamically sized. I didn't expect this to change diagnostics, but it's just cycle errors that change. r? `@oli-obk`
2023-09-18Remove more unused `Lift` impls.Nicholas Nethercote-1/+1
2023-09-18Remove unused `Lift` derives.Nicholas Nethercote-1/+1
I found these by commenting out all `Lift` derives and then adding back the ones that were necessary to successfully compile.
2023-09-16miri: reduce code duplication in SSE/SSE2 bin_op_* functionsEduardo Sánchez Muñoz-4/+8
2023-09-14don't point at const usage site for resolution-time errorsRalf Jung-13/+40
also share the code that emits the actual error
2023-09-14move required_consts check to general post-mono-check functionRalf Jung-8/+27
2023-09-14fix clippy (and MIR printing) handling of ConstValue::Indirect slicesRalf Jung-1/+52
2023-09-14don't force all slice-typed ConstValue to be ConstValue::SliceRalf Jung-18/+7
2023-09-14make it more clear which functions create fresh AllocIdRalf Jung-7/+8
2023-09-14cleanup op_to_const a bit; rename ConstValue::ByRef → IndirectRalf Jung-6/+8
2023-09-14use AllocId instead of Allocation in ConstValue::ByRefRalf Jung-3/+7
2023-09-13rustc_middle: add `Scalar::from_i8` and `Scalar::from_i16` and use them in MiriEduardo Sánchez Muñoz-0/+10
2023-09-13make the eval() functions on our const types return the resulting valueRalf Jung-0/+2
2023-09-09give extra context to ABI mismatch errorsRalf Jung-7/+12
2023-09-04interpret: make MemPlace, Place, Operand types private to the interpreterRalf Jung-1/+1
2023-08-30move marking-locals-live out of push_stack_frame, so it happens with ↵Ralf Jung-0/+2
argument passing this entirely avoids even creating unsized locals in Immediate::Uninitialized state
2023-08-09Rollup merge of #114587 - ouz-a:smir_allocation, r=oli-obkMatthias Krüger-0/+3
Convert Const to Allocation in smir Continuation of previous pr https://github.com/rust-lang/rust/pull/114466 cc https://github.com/rust-lang/project-stable-mir/issues/15 r? `@oli-obk`
2023-08-09Convert Const to Allocation in smirouz-a-0/+3
2023-08-08interpret: remove incomplete protection against invalid where clausesRalf Jung-2/+0
2023-08-03Rollup merge of #114372 - RalfJung:const-pointer-as-int, r=oli-obkMatthias Krüger-60/+77
const validation: point at where we found a pointer but expected an integer Instead of validation just printing "unable to turn pointer into bytes", make this a regular validation error that says where in the value the bad pointer was found. Also distinguish "expected integer, got pointer" from "expected pointer, got partial pointer or mix of pointers". To avoid duplicating things too much I refactored the diagnostics for validity a bit, so that "got uninit, expected X" and "got pointer, expected X" can share the "X" part. Also all the errors emitted for validation are now grouped under `const_eval_validation` so that they are in a single group in the ftl file. r? `@oli-obk`
2023-08-03Rollup merge of #114363 - RalfJung:interpret-not-miri, r=jackh726Matthias Krüger-2/+2
avoid 'miri' when refering to the shared interpreter This is basically the rustc source code version of https://github.com/rust-lang/rustc-dev-guide/pull/1471.