diff options
| author | bors <bors@rust-lang.org> | 2023-07-25 14:18:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-07-25 14:18:08 +0000 |
| commit | 4fc6b33474680ba57e10d56371c2c3df91788e26 (patch) | |
| tree | 0c6d67919cf5084bb45c315b2d5c74b714f82fe6 /compiler/rustc_const_eval/src/interpret/mod.rs | |
| parent | 23405bb123681399c912552fa1c09264c0d4930d (diff) | |
| parent | d1276005119341f381ce1ec04894b24a9275d5f0 (diff) | |
| download | rust-4fc6b33474680ba57e10d56371c2c3df91788e26.tar.gz rust-4fc6b33474680ba57e10d56371c2c3df91788e26.zip | |
Auto merge of #114011 - RalfJung:place-projection, r=oli-obk
interpret: Unify projections for MPlaceTy, PlaceTy, OpTy For ~forever, we didn't really have proper shared code for handling projections into those three types. This is mostly because `PlaceTy` projections require `&mut self`: they might have to `force_allocate` to be able to represent a project part-way into a local. This PR finally fixes that, by enhancing `Place::Local` with an `offset` so that such an optimized place can point into a part of a place without having requiring an in-memory representation. If we later write to that place, we will still do `force_allocate` -- for now we don't have an optimized path in `write_immediate` that would avoid allocation for partial overwrites of immediately stored locals. But in `write_immediate` we have `&mut self` so at least this no longer pollutes all our type signatures. (Ironically, I seem to distantly remember that many years ago, `Place::Local` *did* have an `offset`, and I removed it to simplify things. I guess I didn't realize why it was so useful... I am also not sure if this was actually used to achieve place projection on `&self` back then.) The `offset` had type `Option<Size>`, where `None` represent "no projection was applied". This is needed because locals *can* be unsized (when they are arguments) but `Place::Local` cannot store metadata: if the offset is `None`, this refers to the entire local, so we can use the metadata of the local itself (which must be indirect); if a projection gets applied, since the local is indirect, it will turn into a `Place::Ptr`. (Note that even for indirect locals we can have `Place::Local`: when the local appears in MIR, we always start with `Place::Local`, and only check `frame.locals` later. We could eagerly normalize to `Place::Ptr` but I don't think that would actually simplify things much.) Having done all that, we can finally properly abstract projections: we have a new `Projectable` trait that has the basic methods required for projecting, and then all projection methods are implemented for anything that implements that trait. We can even implement it for `ImmTy`! (Not that we need that, but it seems neat.) The visitor can be greatly simplified; it doesn't need its own trait any more but it can use the `Projectable` trait. We also don't need the separate `Mut` visitor any more; that was required only to reflect that projections on `PlaceTy` needed `&mut self`. It is possible that there are some more `&mut self` that can now become `&self`... I guess we'll notice that over time. r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret/mod.rs')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/mod.rs | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index f657f954f9c..7974920bc14 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -26,9 +26,10 @@ pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackP pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind}; pub use self::operand::{ImmTy, Immediate, OpTy, Operand}; pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy}; +pub use self::projection::Projectable; pub use self::terminator::FnArg; pub use self::validity::{CtfeValidationMode, RefTracking}; -pub use self::visitor::{MutValueVisitor, Value, ValueVisitor}; +pub use self::visitor::ValueVisitor; pub(crate) use self::intrinsics::eval_nullary_intrinsic; use eval_context::{from_known_layout, mir_assign_valid_types}; |
