Skip to content

Commit 1d83adb

Browse files
committed
Elaborate comments.
1 parent 00225ac commit 1d83adb

File tree

2 files changed

+20
-34
lines changed

2 files changed

+20
-34
lines changed

compiler/rustc_middle/src/mir/consts.rs

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -183,21 +183,16 @@ impl ConstValue {
183183

184184
/// Check if a constant may contain provenance information. This is used by MIR opts.
185185
/// Can return `true` even if there is no provenance.
186-
pub fn may_have_provenance(&self, tcx: TyCtxt<'_>, size: Size) -> bool {
186+
pub fn may_have_provenance(&self, tcx: TyCtxt<'_>, size: Option<Size>) -> bool {
187187
match *self {
188188
ConstValue::ZeroSized | ConstValue::Scalar(Scalar::Int(_)) => return false,
189-
ConstValue::Scalar(Scalar::Ptr(..)) => return true,
190-
// It's hard to find out the part of the allocation we point to;
191-
// just conservatively check everything.
192-
ConstValue::Slice { alloc_id, meta: _ } => {
193-
!tcx.global_alloc(alloc_id).unwrap_memory().inner().provenance().ptrs().is_empty()
189+
ConstValue::Scalar(Scalar::Ptr(..)) | ConstValue::Slice { .. } => return true,
190+
ConstValue::Indirect { alloc_id, offset } => {
191+
let allocation = tcx.global_alloc(alloc_id).unwrap_memory().inner();
192+
let end = if let Some(size) = size { offset + size } else { allocation.size() };
193+
let provenance_map = allocation.provenance();
194+
!provenance_map.range_empty(AllocRange::from(offset..end), &tcx)
194195
}
195-
ConstValue::Indirect { alloc_id, offset } => !tcx
196-
.global_alloc(alloc_id)
197-
.unwrap_memory()
198-
.inner()
199-
.provenance()
200-
.range_empty(AllocRange::from(offset..offset + size), &tcx),
201196
}
202197
}
203198

@@ -490,35 +485,26 @@ impl<'tcx> Const<'tcx> {
490485
Self::Val(val, ty)
491486
}
492487

493-
/// Return true if any evaluation of this constant always returns the same value,
494-
/// taking into account even pointer identity tests.
488+
/// Return true if any evaluation of this constant in the same MIR body
489+
/// always returns the same value, taking into account even pointer identity tests.
490+
///
491+
/// In other words, this answers: is "cloning" the mir::ConstOperand ok?
495492
pub fn is_deterministic(&self) -> bool {
496493
// Primitive types cannot contain provenance and always have the same value.
497494
if self.ty().is_primitive() {
498495
return true;
499496
}
500497

501-
// Some constants may generate fresh allocations for pointers they contain,
502-
// so using the same constant twice can yield two different results.
503-
// Notably, valtrees purposefully generate new allocations.
504498
match self {
505-
Const::Ty(_, c) => match c.kind() {
506-
ty::ConstKind::Param(..) => true,
507-
// A valtree may be a reference. Valtree references correspond to a
508-
// different allocation each time they are evaluated. Valtrees for primitive
509-
// types are fine though.
510-
ty::ConstKind::Value(..)
511-
| ty::ConstKind::Expr(..)
512-
| ty::ConstKind::Unevaluated(..)
513-
// This can happen if evaluation of a constant failed. The result does not matter
514-
// much since compilation is doomed.
515-
| ty::ConstKind::Error(..) => false,
516-
// Should not appear in runtime MIR.
517-
ty::ConstKind::Infer(..)
518-
| ty::ConstKind::Bound(..)
519-
| ty::ConstKind::Placeholder(..) => bug!(),
520-
},
499+
// Some constants may generate fresh allocations for pointers they contain,
500+
// so using the same constant twice can yield two different results.
501+
// Notably, valtrees purposefully generate new allocations.
502+
Const::Ty(..) => false,
503+
// We do not know the contents, so don't attempt to do anything clever.
521504
Const::Unevaluated(..) => false,
505+
// When an evaluated contant contains provenance, it is encoded as an `AllocId`.
506+
// Cloning the constant will reuse the same `AllocId`. If this is in the same MIR
507+
// body, this same `AllocId` will result in the same pointer in codegen.
522508
Const::Val(..) => true,
523509
}
524510
}

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1823,7 +1823,7 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
18231823
// Check that we do not leak a pointer.
18241824
// Those pointers may lose part of their identity in codegen.
18251825
// FIXME: remove this hack once https://github.com/rust-lang/rust/issues/79738 is fixed.
1826-
assert!(!value.may_have_provenance(self.tcx, op.layout.size));
1826+
assert!(!value.may_have_provenance(self.tcx, Some(op.layout.size)));
18271827

18281828
Some(Const::Val(value, op.layout.ty))
18291829
}

0 commit comments

Comments
 (0)