rename BorrowKind::Shallow to Fake

also adds some comments
This commit is contained in:
lcnr 2023-11-08 13:42:30 +01:00
parent a42eca42df
commit 992d93f687
30 changed files with 75 additions and 68 deletions

View file

@ -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 {

View file

@ -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.

View file

@ -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,

View file

@ -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 }
} }

View file

@ -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,
}); });

View file

@ -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

View file

@ -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");

View file

@ -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,

View file

@ -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,
) => { ) => {

View file

@ -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,

View file

@ -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)
} }
} }

View file

@ -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);
} }

View file

@ -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",
); );
} }
} }

View file

@ -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 ",
}; };

View file

@ -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
} }

View file

@ -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 },

View file

@ -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,
} }
} }
} }

View file

@ -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)
) )
} }

View file

@ -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 },
), ),
); );

View file

@ -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);
} }

View file

@ -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 => {}
} }
} }
} }

View file

@ -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(..)

View file

@ -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),

View file

@ -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(),
_ => (), _ => (),
} }

View file

@ -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) => {

View file

@ -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.

View file

@ -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`

View file

@ -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(_) => {

View file

@ -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) },
} }
} }

View file

@ -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 {