Skip to content

Commit fcaf233

Browse files
committed
Miri engine interning: improve comments, and entirely skip ZST
1 parent 2202653 commit fcaf233

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

compiler/rustc_mir/src/interpret/intern.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> {
3333
/// A list of all encountered allocations. After type-based interning, we traverse this list to
3434
/// also intern allocations that are only referenced by a raw pointer or inside a union.
3535
leftover_allocations: &'rt mut FxHashSet<AllocId>,
36-
/// The root kind of the value that we're looking at. This field is never mutated and only used
37-
/// for sanity assertions that will ICE when `const_qualif` screws up.
36+
/// The root kind of the value that we're looking at. This field is never mutated for a
37+
/// particular allocation. It is primarily used to make as many allocations as possible
38+
/// read-only so LLVM can place them in const memory.
3839
mode: InternMode,
3940
/// This field stores whether we are *currently* inside an `UnsafeCell`. This can affect
4041
/// the intern mode of references we encounter.
@@ -113,8 +114,8 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
113114
// For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume
114115
// no interior mutability.
115116
let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env));
116-
// For statics, allocation mutability is the combination of the place mutability and
117-
// the type mutability.
117+
// For statics, allocation mutability is the combination of place mutability and
118+
// type mutability.
118119
// The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
119120
let immutable = mutability == Mutability::Not && frozen;
120121
if immutable {
@@ -188,8 +189,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
188189
}
189190
}
190191

191-
// ZSTs do not need validation unless they're uninhabited
192-
if mplace.layout.is_zst() && !mplace.layout.abi.is_uninhabited() {
192+
// ZSTs cannot contain pointers, so we can skip them.
193+
if mplace.layout.is_zst() {
193194
return Ok(());
194195
}
195196

@@ -209,13 +210,12 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
209210
if let ty::Dynamic(..) =
210211
tcx.struct_tail_erasing_lifetimes(referenced_ty, self.ecx.param_env).kind()
211212
{
212-
// Validation will error (with a better message) on an invalid vtable pointer
213-
// so we can safely not do anything if this is not a real pointer.
214213
if let Scalar::Ptr(vtable) = mplace.meta.unwrap_meta() {
215214
// Explicitly choose const mode here, since vtables are immutable, even
216215
// if the reference of the fat pointer is mutable.
217216
self.intern_shallow(vtable.alloc_id, InternMode::ConstInner, None);
218217
} else {
218+
// Validation will error (with a better message) on an invalid vtable pointer.
219219
// Let validation show the error message, but make sure it *does* error.
220220
tcx.sess
221221
.delay_span_bug(tcx.span, "vtables pointers cannot be integer pointers");
@@ -224,7 +224,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
224224
// Check if we have encountered this pointer+layout combination before.
225225
// Only recurse for allocation-backed pointers.
226226
if let Scalar::Ptr(ptr) = mplace.ptr {
227-
// Compute the mode with which we intern this.
227+
// Compute the mode with which we intern this. Our goal here is to make as many
228+
// statics as we can immutable so they can be placed in const memory by LLVM.
228229
let ref_mode = match self.mode {
229230
InternMode::Static(mutbl) => {
230231
// In statics, merge outer mutability with reference mutability and
@@ -243,8 +244,13 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
243244
}
244245
Mutability::Not => {
245246
// A shared reference, things become immutable.
246-
// We do *not* consier `freeze` here -- that is done more precisely
247-
// when traversing the referenced data (by tracking `UnsafeCell`).
247+
// We do *not* consider `freeze` here: `intern_shallow` considers
248+
// `freeze` for the actual mutability of this allocation; the intern
249+
// mode for references contained in this allocation is tracked more
250+
// precisely when traversing the referenced data (by tracking
251+
// `UnsafeCell`). This makes sure that `&(&i32, &Cell<i32>)` still
252+
// has the left inner reference interned into a read-only
253+
// allocation.
248254
InternMode::Static(Mutability::Not)
249255
}
250256
Mutability::Mut => {

0 commit comments

Comments
 (0)