rename BorrowKind::Shallow
to Fake
also adds some comments
This commit is contained in:
parent
a42eca42df
commit
992d93f687
30 changed files with 75 additions and 68 deletions
|
@ -71,7 +71,7 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
|
||||||
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let kind = match self.kind {
|
let kind = match self.kind {
|
||||||
mir::BorrowKind::Shared => "",
|
mir::BorrowKind::Shared => "",
|
||||||
mir::BorrowKind::Shallow => "shallow ",
|
mir::BorrowKind::Fake => "fake ",
|
||||||
mir::BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture } => "uniq ",
|
mir::BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture } => "uniq ",
|
||||||
// FIXME: differentiate `TwoPhaseBorrow`
|
// FIXME: differentiate `TwoPhaseBorrow`
|
||||||
mir::BorrowKind::Mut {
|
mir::BorrowKind::Mut {
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||||
// cross suspension points so this behavior is unproblematic.
|
// cross suspension points so this behavior is unproblematic.
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
|
PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::FakeBorrow) |
|
||||||
|
|
||||||
// `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
|
// `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
|
||||||
// contain dangling references.
|
// contain dangling references.
|
||||||
|
|
|
@ -1022,7 +1022,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
|
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
(BorrowKind::Mut { .. }, BorrowKind::Shallow) => {
|
(BorrowKind::Mut { .. }, BorrowKind::Fake) => {
|
||||||
if let Some(immutable_section_description) =
|
if let Some(immutable_section_description) =
|
||||||
self.classify_immutable_section(issued_borrow.assigned_place)
|
self.classify_immutable_section(issued_borrow.assigned_place)
|
||||||
{
|
{
|
||||||
|
@ -1114,11 +1114,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
(BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Shallow)
|
(BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Fake)
|
||||||
| (
|
| (BorrowKind::Fake, BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake) => {
|
||||||
BorrowKind::Shallow,
|
unreachable!()
|
||||||
BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow,
|
}
|
||||||
) => unreachable!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if issued_spans == borrow_spans {
|
if issued_spans == borrow_spans {
|
||||||
|
@ -2806,7 +2805,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let loan_span = loan_spans.args_or_use();
|
let loan_span = loan_spans.args_or_use();
|
||||||
|
|
||||||
let descr_place = self.describe_any_place(place.as_ref());
|
let descr_place = self.describe_any_place(place.as_ref());
|
||||||
if loan.kind == BorrowKind::Shallow {
|
if loan.kind == BorrowKind::Fake {
|
||||||
if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
|
if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
|
||||||
let mut err = self.cannot_mutate_in_immutable_section(
|
let mut err = self.cannot_mutate_in_immutable_section(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -634,7 +634,7 @@ impl UseSpans<'_> {
|
||||||
err.subdiagnostic(match kind {
|
err.subdiagnostic(match kind {
|
||||||
Some(kd) => match kd {
|
Some(kd) => match kd {
|
||||||
rustc_middle::mir::BorrowKind::Shared
|
rustc_middle::mir::BorrowKind::Shared
|
||||||
| rustc_middle::mir::BorrowKind::Shallow => {
|
| rustc_middle::mir::BorrowKind::Fake => {
|
||||||
CaptureVarKind::Immut { kind_span: capture_kind_span }
|
CaptureVarKind::Immut { kind_span: capture_kind_span }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,8 +253,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
match rvalue {
|
match rvalue {
|
||||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||||
let access_kind = match bk {
|
let access_kind = match bk {
|
||||||
BorrowKind::Shallow => {
|
BorrowKind::Fake => {
|
||||||
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
(Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
|
||||||
}
|
}
|
||||||
BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))),
|
BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))),
|
||||||
BorrowKind::Mut { .. } => {
|
BorrowKind::Mut { .. } => {
|
||||||
|
@ -376,8 +376,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
// have already taken the reservation
|
// have already taken the reservation
|
||||||
}
|
}
|
||||||
|
|
||||||
(Read(_), BorrowKind::Shallow | BorrowKind::Shared)
|
(Read(_), BorrowKind::Fake | BorrowKind::Shared)
|
||||||
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => {
|
| (Read(ReadKind::Borrow(BorrowKind::Fake)), BorrowKind::Mut { .. }) => {
|
||||||
// Reads don't invalidate shared or shallow borrows
|
// Reads don't invalidate shared or shallow borrows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
|
|
||||||
// only mutable borrows should be 2-phase
|
// only mutable borrows should be 2-phase
|
||||||
assert!(match borrow.kind {
|
assert!(match borrow.kind {
|
||||||
BorrowKind::Shared | BorrowKind::Shallow => false,
|
BorrowKind::Shared | BorrowKind::Fake => false,
|
||||||
BorrowKind::Mut { .. } => true,
|
BorrowKind::Mut { .. } => true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -846,7 +846,7 @@ use self::ReadOrWrite::{Activation, Read, Reservation, Write};
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
enum ArtificialField {
|
enum ArtificialField {
|
||||||
ArrayLength,
|
ArrayLength,
|
||||||
ShallowBorrow,
|
FakeBorrow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
@ -1085,18 +1085,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
Control::Continue
|
Control::Continue
|
||||||
}
|
}
|
||||||
|
|
||||||
(Read(_), BorrowKind::Shared | BorrowKind::Shallow)
|
(Read(_), BorrowKind::Shared | BorrowKind::Fake)
|
||||||
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => {
|
| (Read(ReadKind::Borrow(BorrowKind::Fake)), BorrowKind::Mut { .. }) => {
|
||||||
Control::Continue
|
Control::Continue
|
||||||
}
|
}
|
||||||
|
|
||||||
(Reservation(_), BorrowKind::Shallow | BorrowKind::Shared) => {
|
(Reservation(_), BorrowKind::Fake | BorrowKind::Shared) => {
|
||||||
// This used to be a future compatibility warning (to be
|
// This used to be a future compatibility warning (to be
|
||||||
// disallowed on NLL). See rust-lang/rust#56254
|
// disallowed on NLL). See rust-lang/rust#56254
|
||||||
Control::Continue
|
Control::Continue
|
||||||
}
|
}
|
||||||
|
|
||||||
(Write(WriteKind::Move), BorrowKind::Shallow) => {
|
(Write(WriteKind::Move), BorrowKind::Fake) => {
|
||||||
// Handled by initialization checks.
|
// Handled by initialization checks.
|
||||||
Control::Continue
|
Control::Continue
|
||||||
}
|
}
|
||||||
|
@ -1204,8 +1204,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
match rvalue {
|
match rvalue {
|
||||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||||
let access_kind = match bk {
|
let access_kind = match bk {
|
||||||
BorrowKind::Shallow => {
|
BorrowKind::Fake => {
|
||||||
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
(Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
|
||||||
}
|
}
|
||||||
BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))),
|
BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))),
|
||||||
BorrowKind::Mut { .. } => {
|
BorrowKind::Mut { .. } => {
|
||||||
|
@ -1226,7 +1226,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
|
|
||||||
let action = if bk == BorrowKind::Shallow {
|
let action = if bk == BorrowKind::Fake {
|
||||||
InitializationRequiringAction::MatchOn
|
InitializationRequiringAction::MatchOn
|
||||||
} else {
|
} else {
|
||||||
InitializationRequiringAction::Borrow
|
InitializationRequiringAction::Borrow
|
||||||
|
@ -1583,7 +1583,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
// only mutable borrows should be 2-phase
|
// only mutable borrows should be 2-phase
|
||||||
assert!(match borrow.kind {
|
assert!(match borrow.kind {
|
||||||
BorrowKind::Shared | BorrowKind::Shallow => false,
|
BorrowKind::Shared | BorrowKind::Fake => false,
|
||||||
BorrowKind::Mut { .. } => true,
|
BorrowKind::Mut { .. } => true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2142,14 +2142,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
| WriteKind::Replace
|
| WriteKind::Replace
|
||||||
| WriteKind::StorageDeadOrDrop
|
| WriteKind::StorageDeadOrDrop
|
||||||
| WriteKind::MutableBorrow(BorrowKind::Shared)
|
| WriteKind::MutableBorrow(BorrowKind::Shared)
|
||||||
| WriteKind::MutableBorrow(BorrowKind::Shallow),
|
| WriteKind::MutableBorrow(BorrowKind::Fake),
|
||||||
)
|
)
|
||||||
| Write(
|
| Write(
|
||||||
WriteKind::Move
|
WriteKind::Move
|
||||||
| WriteKind::Replace
|
| WriteKind::Replace
|
||||||
| WriteKind::StorageDeadOrDrop
|
| WriteKind::StorageDeadOrDrop
|
||||||
| WriteKind::MutableBorrow(BorrowKind::Shared)
|
| WriteKind::MutableBorrow(BorrowKind::Shared)
|
||||||
| WriteKind::MutableBorrow(BorrowKind::Shallow),
|
| WriteKind::MutableBorrow(BorrowKind::Fake),
|
||||||
) => {
|
) => {
|
||||||
if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
|
if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
|
||||||
&& !self.has_buffered_errors()
|
&& !self.has_buffered_errors()
|
||||||
|
@ -2173,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Read(
|
Read(
|
||||||
ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow)
|
ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake)
|
||||||
| ReadKind::Copy,
|
| ReadKind::Copy,
|
||||||
) => {
|
) => {
|
||||||
// Access authorized
|
// Access authorized
|
||||||
|
|
|
@ -204,7 +204,7 @@ fn place_components_conflict<'tcx>(
|
||||||
|
|
||||||
match (elem, &base_ty.kind(), access) {
|
match (elem, &base_ty.kind(), access) {
|
||||||
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
|
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
|
||||||
| (_, _, Shallow(Some(ArtificialField::ShallowBorrow))) => {
|
| (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
|
||||||
// The array length is like additional fields on the
|
// The array length is like additional fields on the
|
||||||
// type; it does not overlap any existing data there.
|
// type; it does not overlap any existing data there.
|
||||||
// Furthermore, if cannot actually be a prefix of any
|
// Furthermore, if cannot actually be a prefix of any
|
||||||
|
@ -273,10 +273,10 @@ fn place_components_conflict<'tcx>(
|
||||||
// If the second example, where we did, then we still know
|
// If the second example, where we did, then we still know
|
||||||
// that the borrow can access a *part* of our place that
|
// that the borrow can access a *part* of our place that
|
||||||
// our access cares about, so we still have a conflict.
|
// our access cares about, so we still have a conflict.
|
||||||
if borrow_kind == BorrowKind::Shallow
|
if borrow_kind == BorrowKind::Fake
|
||||||
&& borrow_place.projection.len() < access_place.projection.len()
|
&& borrow_place.projection.len() < access_place.projection.len()
|
||||||
{
|
{
|
||||||
debug!("borrow_conflicts_with_place: shallow borrow");
|
debug!("borrow_conflicts_with_place: fake borrow");
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
debug!("borrow_conflicts_with_place: full borrow, CONFLICT");
|
debug!("borrow_conflicts_with_place: full borrow, CONFLICT");
|
||||||
|
|
|
@ -751,7 +751,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
PlaceContext::MutatingUse(_) => ty::Invariant,
|
PlaceContext::MutatingUse(_) => ty::Invariant,
|
||||||
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
|
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
|
||||||
PlaceContext::NonMutatingUse(
|
PlaceContext::NonMutatingUse(
|
||||||
Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | AddressOf
|
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | AddressOf
|
||||||
| Projection,
|
| Projection,
|
||||||
) => ty::Covariant,
|
) => ty::Covariant,
|
||||||
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
|
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
|
||||||
|
|
|
@ -219,7 +219,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||||
| PlaceContext::NonMutatingUse(
|
| PlaceContext::NonMutatingUse(
|
||||||
NonMutatingUseContext::Inspect
|
NonMutatingUseContext::Inspect
|
||||||
| NonMutatingUseContext::SharedBorrow
|
| NonMutatingUseContext::SharedBorrow
|
||||||
| NonMutatingUseContext::ShallowBorrow
|
| NonMutatingUseContext::FakeBorrow
|
||||||
| NonMutatingUseContext::AddressOf
|
| NonMutatingUseContext::AddressOf
|
||||||
| NonMutatingUseContext::Projection,
|
| NonMutatingUseContext::Projection,
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -423,8 +423,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
BorrowKind::Shared => {
|
BorrowKind::Shared => {
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||||
}
|
}
|
||||||
BorrowKind::Shallow => {
|
BorrowKind::Fake => {
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::FakeBorrow)
|
||||||
}
|
}
|
||||||
BorrowKind::Mut { .. } => {
|
BorrowKind::Mut { .. } => {
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
||||||
|
@ -500,7 +500,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
|
self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, place)
|
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake, place)
|
||||||
| Rvalue::AddressOf(Mutability::Not, place) => {
|
| Rvalue::AddressOf(Mutability::Not, place) => {
|
||||||
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
||||||
&self.ccx,
|
&self.ccx,
|
||||||
|
|
|
@ -105,7 +105,7 @@ where
|
||||||
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
|
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
|
||||||
match kind {
|
match kind {
|
||||||
mir::BorrowKind::Mut { .. } => true,
|
mir::BorrowKind::Mut { .. } => true,
|
||||||
mir::BorrowKind::Shared | mir::BorrowKind::Shallow => {
|
mir::BorrowKind::Shared | mir::BorrowKind::Fake => {
|
||||||
self.shared_borrow_allows_mutation(place)
|
self.shared_borrow_allows_mutation(place)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,7 +456,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
||||||
match kind {
|
match kind {
|
||||||
// Reject these borrow types just to be safe.
|
// Reject these borrow types just to be safe.
|
||||||
// FIXME(RalfJung): could we allow them? Should we? No point in it until we have a usecase.
|
// FIXME(RalfJung): could we allow them? Should we? No point in it until we have a usecase.
|
||||||
BorrowKind::Shallow | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => {
|
BorrowKind::Fake | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => {
|
||||||
return Err(Unpromotable);
|
return Err(Unpromotable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -848,11 +848,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
match rvalue {
|
match rvalue {
|
||||||
Rvalue::Use(_) | Rvalue::CopyForDeref(_) | Rvalue::Aggregate(..) => {}
|
Rvalue::Use(_) | Rvalue::CopyForDeref(_) | Rvalue::Aggregate(..) => {}
|
||||||
Rvalue::Ref(_, BorrowKind::Shallow, _) => {
|
Rvalue::Ref(_, BorrowKind::Fake, _) => {
|
||||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
"`Assign` statement with a `Shallow` borrow should have been removed in runtime MIR",
|
"`Assign` statement with a `Fake` borrow should have been removed in runtime MIR",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -942,7 +942,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
||||||
Ref(region, borrow_kind, ref place) => {
|
Ref(region, borrow_kind, ref place) => {
|
||||||
let kind_str = match borrow_kind {
|
let kind_str = match borrow_kind {
|
||||||
BorrowKind::Shared => "",
|
BorrowKind::Shared => "",
|
||||||
BorrowKind::Shallow => "shallow ",
|
BorrowKind::Fake => "fake ",
|
||||||
BorrowKind::Mut { .. } => "mut ",
|
BorrowKind::Mut { .. } => "mut ",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -446,7 +446,7 @@ impl<'tcx> Rvalue<'tcx> {
|
||||||
impl BorrowKind {
|
impl BorrowKind {
|
||||||
pub fn mutability(&self) -> Mutability {
|
pub fn mutability(&self) -> Mutability {
|
||||||
match *self {
|
match *self {
|
||||||
BorrowKind::Shared | BorrowKind::Shallow => Mutability::Not,
|
BorrowKind::Shared | BorrowKind::Fake => Mutability::Not,
|
||||||
BorrowKind::Mut { .. } => Mutability::Mut,
|
BorrowKind::Mut { .. } => Mutability::Mut,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,7 +454,7 @@ impl BorrowKind {
|
||||||
pub fn allows_two_phase_borrow(&self) -> bool {
|
pub fn allows_two_phase_borrow(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
BorrowKind::Shared
|
BorrowKind::Shared
|
||||||
| BorrowKind::Shallow
|
| BorrowKind::Fake
|
||||||
| BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::ClosureCapture } => {
|
| BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::ClosureCapture } => {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ pub enum AnalysisPhase {
|
||||||
/// * [`TerminatorKind::FalseEdge`]
|
/// * [`TerminatorKind::FalseEdge`]
|
||||||
/// * [`StatementKind::FakeRead`]
|
/// * [`StatementKind::FakeRead`]
|
||||||
/// * [`StatementKind::AscribeUserType`]
|
/// * [`StatementKind::AscribeUserType`]
|
||||||
/// * [`Rvalue::Ref`] with `BorrowKind::Shallow`
|
/// * [`Rvalue::Ref`] with `BorrowKind::Fake`
|
||||||
///
|
///
|
||||||
/// Furthermore, `Deref` projections must be the first projection within any place (if they
|
/// Furthermore, `Deref` projections must be the first projection within any place (if they
|
||||||
/// appear at all)
|
/// appear at all)
|
||||||
|
@ -182,7 +182,7 @@ pub enum BorrowKind {
|
||||||
/// should not prevent `if let None = x { ... }`, for example, because the
|
/// should not prevent `if let None = x { ... }`, for example, because the
|
||||||
/// mutating `(*x as Some).0` can't affect the discriminant of `x`.
|
/// mutating `(*x as Some).0` can't affect the discriminant of `x`.
|
||||||
/// We can also report errors with this kind of borrow differently.
|
/// We can also report errors with this kind of borrow differently.
|
||||||
Shallow,
|
Fake,
|
||||||
|
|
||||||
/// Data is mutable and not aliasable.
|
/// Data is mutable and not aliasable.
|
||||||
Mut { kind: MutBorrowKind },
|
Mut { kind: MutBorrowKind },
|
||||||
|
|
|
@ -278,7 +278,7 @@ impl BorrowKind {
|
||||||
|
|
||||||
// We have no type corresponding to a shallow borrow, so use
|
// We have no type corresponding to a shallow borrow, so use
|
||||||
// `&` as an approximation.
|
// `&` as an approximation.
|
||||||
BorrowKind::Shallow => hir::Mutability::Not,
|
BorrowKind::Fake => hir::Mutability::Not,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -649,8 +649,8 @@ macro_rules! make_mir_visitor {
|
||||||
BorrowKind::Shared => PlaceContext::NonMutatingUse(
|
BorrowKind::Shared => PlaceContext::NonMutatingUse(
|
||||||
NonMutatingUseContext::SharedBorrow
|
NonMutatingUseContext::SharedBorrow
|
||||||
),
|
),
|
||||||
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
|
BorrowKind::Fake => PlaceContext::NonMutatingUse(
|
||||||
NonMutatingUseContext::ShallowBorrow
|
NonMutatingUseContext::FakeBorrow
|
||||||
),
|
),
|
||||||
BorrowKind::Mut { .. } =>
|
BorrowKind::Mut { .. } =>
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow),
|
PlaceContext::MutatingUse(MutatingUseContext::Borrow),
|
||||||
|
@ -1261,8 +1261,8 @@ pub enum NonMutatingUseContext {
|
||||||
Move,
|
Move,
|
||||||
/// Shared borrow.
|
/// Shared borrow.
|
||||||
SharedBorrow,
|
SharedBorrow,
|
||||||
/// Shallow borrow.
|
/// A fake borrow.
|
||||||
ShallowBorrow,
|
FakeBorrow,
|
||||||
/// AddressOf for *const pointer.
|
/// AddressOf for *const pointer.
|
||||||
AddressOf,
|
AddressOf,
|
||||||
/// PlaceMention statement.
|
/// PlaceMention statement.
|
||||||
|
@ -1341,7 +1341,7 @@ impl PlaceContext {
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
PlaceContext::NonMutatingUse(
|
PlaceContext::NonMutatingUse(
|
||||||
NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::ShallowBorrow
|
NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::FakeBorrow
|
||||||
) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -690,7 +690,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
fake_borrow_temp.into(),
|
fake_borrow_temp.into(),
|
||||||
Rvalue::Ref(
|
Rvalue::Ref(
|
||||||
tcx.lifetimes.re_erased,
|
tcx.lifetimes.re_erased,
|
||||||
BorrowKind::Shallow,
|
BorrowKind::Fake,
|
||||||
Place { local: base_place.local, projection },
|
Place { local: base_place.local, projection },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2021,7 +2021,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let re_erased = tcx.lifetimes.re_erased;
|
let re_erased = tcx.lifetimes.re_erased;
|
||||||
let scrutinee_source_info = self.source_info(scrutinee_span);
|
let scrutinee_source_info = self.source_info(scrutinee_span);
|
||||||
for &(place, temp) in fake_borrows {
|
for &(place, temp) in fake_borrows {
|
||||||
let borrow = Rvalue::Ref(re_erased, BorrowKind::Shallow, place);
|
let borrow = Rvalue::Ref(re_erased, BorrowKind::Fake, place);
|
||||||
self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow);
|
self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
match borrow_kind {
|
match borrow_kind {
|
||||||
BorrowKind::Shallow | BorrowKind::Shared => {
|
BorrowKind::Fake | BorrowKind::Shared => {
|
||||||
if !ty.is_freeze(self.tcx, self.param_env) {
|
if !ty.is_freeze(self.tcx, self.param_env) {
|
||||||
self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
|
self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
|
||||||
}
|
}
|
||||||
|
@ -483,7 +483,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
visit::walk_expr(&mut visitor, expr);
|
visit::walk_expr(&mut visitor, expr);
|
||||||
if visitor.found {
|
if visitor.found {
|
||||||
match borrow_kind {
|
match borrow_kind {
|
||||||
BorrowKind::Shallow | BorrowKind::Shared
|
BorrowKind::Fake | BorrowKind::Shared
|
||||||
if !self.thir[arg].ty.is_freeze(self.tcx, self.param_env) =>
|
if !self.thir[arg].ty.is_freeze(self.tcx, self.param_env) =>
|
||||||
{
|
{
|
||||||
self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField)
|
self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField)
|
||||||
|
@ -491,7 +491,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
BorrowKind::Mut { .. } => {
|
BorrowKind::Mut { .. } => {
|
||||||
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField)
|
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField)
|
||||||
}
|
}
|
||||||
BorrowKind::Shallow | BorrowKind::Shared => {}
|
BorrowKind::Fake | BorrowKind::Shared => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Cast(..)
|
Rvalue::Cast(..)
|
||||||
| Rvalue::Ref(_, BorrowKind::Shallow, _)
|
| Rvalue::Ref(_, BorrowKind::Fake, _)
|
||||||
| Rvalue::ShallowInitBox(..)
|
| Rvalue::ShallowInitBox(..)
|
||||||
| Rvalue::Use(..)
|
| Rvalue::Use(..)
|
||||||
| Rvalue::ThreadLocalRef(..)
|
| Rvalue::ThreadLocalRef(..)
|
||||||
|
|
|
@ -201,7 +201,7 @@ impl DefUse {
|
||||||
| NonMutatingUseContext::Inspect
|
| NonMutatingUseContext::Inspect
|
||||||
| NonMutatingUseContext::Move
|
| NonMutatingUseContext::Move
|
||||||
| NonMutatingUseContext::PlaceMention
|
| NonMutatingUseContext::PlaceMention
|
||||||
| NonMutatingUseContext::ShallowBorrow
|
| NonMutatingUseContext::FakeBorrow
|
||||||
| NonMutatingUseContext::SharedBorrow,
|
| NonMutatingUseContext::SharedBorrow,
|
||||||
) => Some(DefUse::Use),
|
) => Some(DefUse::Use),
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//! [`Assign`]: rustc_middle::mir::StatementKind::Assign
|
//! [`Assign`]: rustc_middle::mir::StatementKind::Assign
|
||||||
//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
|
//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
|
||||||
//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
|
//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
|
||||||
//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
|
//! [`Fake`]: rustc_middle::mir::BorrowKind::Fake
|
||||||
|
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
|
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
|
||||||
|
@ -24,7 +24,7 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
|
||||||
for statement in basic_block.statements.iter_mut() {
|
for statement in basic_block.statements.iter_mut() {
|
||||||
match statement.kind {
|
match statement.kind {
|
||||||
StatementKind::AscribeUserType(..)
|
StatementKind::AscribeUserType(..)
|
||||||
| StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
|
| StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Fake, _)))
|
||||||
| StatementKind::FakeRead(..) => statement.make_nop(),
|
| StatementKind::FakeRead(..) => statement.make_nop(),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,7 +668,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
|
||||||
// These can't ever be propagated under any scheme, as we can't reason about indirect
|
// These can't ever be propagated under any scheme, as we can't reason about indirect
|
||||||
// mutation.
|
// mutation.
|
||||||
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||||
| NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
|
| NonMutatingUse(NonMutatingUseContext::FakeBorrow)
|
||||||
| NonMutatingUse(NonMutatingUseContext::AddressOf)
|
| NonMutatingUse(NonMutatingUseContext::AddressOf)
|
||||||
| MutatingUse(MutatingUseContext::Borrow)
|
| MutatingUse(MutatingUseContext::Borrow)
|
||||||
| MutatingUse(MutatingUseContext::AddressOf) => {
|
| MutatingUse(MutatingUseContext::AddressOf) => {
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
|
||||||
let observes_address = match ctxt {
|
let observes_address = match ctxt {
|
||||||
PlaceContext::NonMutatingUse(
|
PlaceContext::NonMutatingUse(
|
||||||
NonMutatingUseContext::SharedBorrow
|
NonMutatingUseContext::SharedBorrow
|
||||||
| NonMutatingUseContext::ShallowBorrow
|
| NonMutatingUseContext::FakeBorrow
|
||||||
| NonMutatingUseContext::AddressOf,
|
| NonMutatingUseContext::AddressOf,
|
||||||
) => true,
|
) => true,
|
||||||
// For debuginfo, merging locals is ok.
|
// For debuginfo, merging locals is ok.
|
||||||
|
|
|
@ -637,6 +637,14 @@ struct LivenessInfo {
|
||||||
storage_liveness: IndexVec<BasicBlock, Option<BitSet<Local>>>,
|
storage_liveness: IndexVec<BasicBlock, Option<BitSet<Local>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Computes which locals have to be stored in the state-machine for the
|
||||||
|
/// given coroutine.
|
||||||
|
///
|
||||||
|
/// The basic idea is as follows:
|
||||||
|
/// - a local is live until we encounter a `StorageDead` statement. In
|
||||||
|
/// case none exist, the local is considered to be always live.
|
||||||
|
/// - a local has to be stored if it is either directly used after the
|
||||||
|
/// the suspend point, or if it is live and has been previously borrowed.
|
||||||
fn locals_live_across_suspend_points<'tcx>(
|
fn locals_live_across_suspend_points<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
|
@ -1449,16 +1457,15 @@ pub(crate) fn mir_coroutine_witnesses<'tcx>(
|
||||||
// The first argument is the coroutine type passed by value
|
// The first argument is the coroutine type passed by value
|
||||||
let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
|
let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
|
||||||
|
|
||||||
// Get the interior types and args which typeck computed
|
|
||||||
let movable = match *coroutine_ty.kind() {
|
let movable = match *coroutine_ty.kind() {
|
||||||
ty::Coroutine(_, _, movability) => movability == hir::Movability::Movable,
|
ty::Coroutine(_, _, movability) => movability == hir::Movability::Movable,
|
||||||
ty::Error(_) => return None,
|
ty::Error(_) => return None,
|
||||||
_ => span_bug!(body.span, "unexpected coroutine type {}", coroutine_ty),
|
_ => span_bug!(body.span, "unexpected coroutine type {}", coroutine_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
// When first entering the coroutine, move the resume argument into its new local.
|
// The witness simply contains all locals live across suspend points.
|
||||||
let always_live_locals = always_storage_live_locals(&body);
|
|
||||||
|
|
||||||
|
let always_live_locals = always_storage_live_locals(&body);
|
||||||
let liveness_info = locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
|
let liveness_info = locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
|
||||||
|
|
||||||
// Extract locals which are live across suspension point into `layout`
|
// Extract locals which are live across suspension point into `layout`
|
||||||
|
|
|
@ -234,7 +234,7 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
|
||||||
// so we have to remove them too.
|
// so we have to remove them too.
|
||||||
PlaceContext::NonMutatingUse(
|
PlaceContext::NonMutatingUse(
|
||||||
NonMutatingUseContext::SharedBorrow
|
NonMutatingUseContext::SharedBorrow
|
||||||
| NonMutatingUseContext::ShallowBorrow
|
| NonMutatingUseContext::FakeBorrow
|
||||||
| NonMutatingUseContext::AddressOf,
|
| NonMutatingUseContext::AddressOf,
|
||||||
)
|
)
|
||||||
| PlaceContext::MutatingUse(_) => {
|
| PlaceContext::MutatingUse(_) => {
|
||||||
|
|
|
@ -455,7 +455,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind {
|
||||||
use mir::BorrowKind::*;
|
use mir::BorrowKind::*;
|
||||||
match *self {
|
match *self {
|
||||||
Shared => stable_mir::mir::BorrowKind::Shared,
|
Shared => stable_mir::mir::BorrowKind::Shared,
|
||||||
Shallow => stable_mir::mir::BorrowKind::Shallow,
|
Fake => stable_mir::mir::BorrowKind::Fake,
|
||||||
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
|
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,9 +437,10 @@ pub enum BorrowKind {
|
||||||
Shared,
|
Shared,
|
||||||
|
|
||||||
/// The immediately borrowed place must be immutable, but projections from
|
/// The immediately borrowed place must be immutable, but projections from
|
||||||
/// it don't need to be. For example, a shallow borrow of `a.b` doesn't
|
/// it don't need to be. This is used to prevent match guards from replacing
|
||||||
|
/// the scrutinee. For example, a fake borrow of `a.b` doesn't
|
||||||
/// conflict with a mutable borrow of `a.b.c`.
|
/// conflict with a mutable borrow of `a.b.c`.
|
||||||
Shallow,
|
Fake,
|
||||||
|
|
||||||
/// Data is mutable and not aliasable.
|
/// Data is mutable and not aliasable.
|
||||||
Mut {
|
Mut {
|
||||||
|
|
Loading…
Add table
Reference in a new issue