Skip to content

Commit 331b93a

Browse files
committed
Auto merge of #2670 - RalfJung:retag, r=RalfJung
recreated by hand
2 parents afab05b + f1a8701 commit 331b93a

File tree

1 file changed

+49
-48
lines changed
  • src/tools/miri/src/stacked_borrows

1 file changed

+49
-48
lines changed

src/tools/miri/src/stacked_borrows/mod.rs

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_middle::mir::RetagKind;
1414
use rustc_middle::ty::{
1515
self,
1616
layout::{HasParamEnv, LayoutOf},
17-
Ty,
1817
};
1918
use rustc_target::abi::Abi;
2019
use rustc_target::abi::Size;
@@ -983,28 +982,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
983982
let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields };
984983
return visitor.visit_value(place);
985984

986-
// Determine mutability and whether to add a protector.
987-
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
988-
// making it useless.
989-
fn qualify(ty: Ty<'_>, kind: RetagKind) -> Option<(RefKind, bool)> {
990-
match ty.kind() {
991-
// References are simple.
992-
ty::Ref(_, _, Mutability::Mut) =>
993-
Some((
994-
RefKind::Unique { two_phase: kind == RetagKind::TwoPhase },
995-
kind == RetagKind::FnEntry,
996-
)),
997-
ty::Ref(_, _, Mutability::Not) =>
998-
Some((RefKind::Shared, kind == RetagKind::FnEntry)),
999-
// Raw pointers need to be enabled.
1000-
ty::RawPtr(tym) if kind == RetagKind::Raw =>
1001-
Some((RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, false)),
1002-
// Boxes are handled separately due to that allocator situation,
1003-
// see the visitor below.
1004-
_ => None,
1005-
}
1006-
}
1007-
1008985
// The actual visitor.
1009986
struct RetagVisitor<'ecx, 'mir, 'tcx> {
1010987
ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>,
@@ -1057,34 +1034,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10571034
return Ok(());
10581035
}
10591036

1060-
let recurse_for_fields = || {
1061-
match self.retag_fields {
1062-
RetagFields::No => false,
1063-
RetagFields::Yes => true,
1064-
RetagFields::OnlyScalar => {
1065-
// Matching `ArgAbi::new` at the time of writing, only fields of
1066-
// `Scalar` and `ScalarPair` ABI are considered.
1067-
matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
1037+
// Check the type of this value to see what to do with it (retag, or recurse).
1038+
match place.layout.ty.kind() {
1039+
ty::Ref(_, _, mutbl) => {
1040+
let ref_kind = match mutbl {
1041+
Mutability::Mut =>
1042+
RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase },
1043+
Mutability::Not => RefKind::Shared,
1044+
};
1045+
self.retag_place(
1046+
place,
1047+
ref_kind,
1048+
self.retag_cause,
1049+
/*protector*/ self.kind == RetagKind::FnEntry,
1050+
)?;
1051+
}
1052+
ty::RawPtr(tym) => {
1053+
// We definitely do *not* want to recurse into raw pointers -- wide raw
1054+
// pointers have fields, and for dyn Trait pointees those can have reference
1055+
// type!
1056+
if self.kind == RetagKind::Raw {
1057+
// Raw pointers need to be enabled.
1058+
self.retag_place(
1059+
place,
1060+
RefKind::Raw { mutable: tym.mutbl == Mutability::Mut },
1061+
self.retag_cause,
1062+
/*protector*/ false,
1063+
)?;
1064+
}
1065+
}
1066+
_ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => {
1067+
// Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
1068+
// (Yes this means we technically also recursively retag the allocator itself
1069+
// even if field retagging is not enabled. *shrug*)
1070+
self.walk_value(place)?;
1071+
}
1072+
_ => {
1073+
// Not a reference/pointer/box. Only recurse if configured appropriately.
1074+
let recurse = match self.retag_fields {
1075+
RetagFields::No => false,
1076+
RetagFields::Yes => true,
1077+
RetagFields::OnlyScalar => {
1078+
// Matching `ArgAbi::new` at the time of writing, only fields of
1079+
// `Scalar` and `ScalarPair` ABI are considered.
1080+
matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
1081+
}
1082+
};
1083+
if recurse {
1084+
self.walk_value(place)?;
10681085
}
10691086
}
1070-
};
1071-
1072-
if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
1073-
self.retag_place(place, ref_kind, self.retag_cause, protector)?;
1074-
} else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
1075-
// Wide raw pointers *do* have fields and their types are strange.
1076-
// vtables have a type like `&[*const (); 3]` or so!
1077-
// Do *not* recurse into them.
1078-
// (No need to worry about wide references, those always "qualify". And Boxes
1079-
// are handles specially by the visitor anyway.)
1080-
} else if recurse_for_fields()
1081-
|| place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box())
1082-
{
1083-
// Recurse deeper. Need to always recurse for `Box` to even hit `visit_box`.
1084-
// (Yes this means we technically also recursively retag the allocator itself
1085-
// even if field retagging is not enabled. *shrug*)
1086-
self.walk_value(place)?;
10871087
}
1088+
10881089
Ok(())
10891090
}
10901091
}

0 commit comments

Comments
 (0)