Skip to content

Commit b7583d3

Browse files
committed
Auto merge of #117712 - lcnr:expand-coroutine, r=jackh726
generator layout: ignore fake borrows fixes #117059 We emit fake shallow borrows in case the scrutinee place uses a `Deref` and there is a match guard. This is necessary to prevent the match guard from mutating the scrutinee: https://github.com/rust-lang/rust/blob/fab1054e1742790c22ccc92a625736d658363677/compiler/rustc_mir_build/src/build/matches/mod.rs#L1250-L1265 These fake borrows end up impacting the generator witness computation in `mir_generator_witnesses`, which causes the issue in #117059. This PR now completely ignores fake borrows during this computation. This is sound as thse are always removed after analysis and the actual computation of the generator layout happens afterwards. Only the second commit impacts behavior, and could be backported by itself. r? types
2 parents e7998aa + 92267c9 commit b7583d3

40 files changed

+140
-91
lines changed

compiler/rustc_borrowck/src/borrow_set.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
7171
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
7272
let kind = match self.kind {
7373
mir::BorrowKind::Shared => "",
74-
mir::BorrowKind::Shallow => "shallow ",
74+
mir::BorrowKind::Fake => "fake ",
7575
mir::BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture } => "uniq ",
7676
// FIXME: differentiate `TwoPhaseBorrow`
7777
mir::BorrowKind::Mut {

compiler/rustc_borrowck/src/def_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
4949
// cross suspension points so this behavior is unproblematic.
5050
PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
5151
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
52-
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
52+
PlaceContext::NonMutatingUse(NonMutatingUseContext::FakeBorrow) |
5353

5454
// `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
5555
// contain dangling references.

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10221022
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
10231023
}
10241024

1025-
(BorrowKind::Mut { .. }, BorrowKind::Shallow) => {
1025+
(BorrowKind::Mut { .. }, BorrowKind::Fake) => {
10261026
if let Some(immutable_section_description) =
10271027
self.classify_immutable_section(issued_borrow.assigned_place)
10281028
{
@@ -1114,11 +1114,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11141114
)
11151115
}
11161116

1117-
(BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Shallow)
1118-
| (
1119-
BorrowKind::Shallow,
1120-
BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow,
1121-
) => unreachable!(),
1117+
(BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Fake)
1118+
| (BorrowKind::Fake, BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake) => {
1119+
unreachable!()
1120+
}
11221121
};
11231122

11241123
if issued_spans == borrow_spans {
@@ -2806,7 +2805,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
28062805
let loan_span = loan_spans.args_or_use();
28072806

28082807
let descr_place = self.describe_any_place(place.as_ref());
2809-
if loan.kind == BorrowKind::Shallow {
2808+
if loan.kind == BorrowKind::Fake {
28102809
if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
28112810
let mut err = self.cannot_mutate_in_immutable_section(
28122811
span,

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ impl UseSpans<'_> {
634634
err.subdiagnostic(match kind {
635635
Some(kd) => match kd {
636636
rustc_middle::mir::BorrowKind::Shared
637-
| rustc_middle::mir::BorrowKind::Shallow => {
637+
| rustc_middle::mir::BorrowKind::Fake => {
638638
CaptureVarKind::Immut { kind_span: capture_kind_span }
639639
}
640640

compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
253253
match rvalue {
254254
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
255255
let access_kind = match bk {
256-
BorrowKind::Shallow => {
257-
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
256+
BorrowKind::Fake => {
257+
(Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
258258
}
259259
BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))),
260260
BorrowKind::Mut { .. } => {
@@ -376,8 +376,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
376376
// have already taken the reservation
377377
}
378378

379-
(Read(_), BorrowKind::Shallow | BorrowKind::Shared)
380-
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => {
379+
(Read(_), BorrowKind::Fake | BorrowKind::Shared)
380+
| (Read(ReadKind::Borrow(BorrowKind::Fake)), BorrowKind::Mut { .. }) => {
381381
// Reads don't invalidate shared or shallow borrows
382382
}
383383

@@ -422,7 +422,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
422422

423423
// only mutable borrows should be 2-phase
424424
assert!(match borrow.kind {
425-
BorrowKind::Shared | BorrowKind::Shallow => false,
425+
BorrowKind::Shared | BorrowKind::Fake => false,
426426
BorrowKind::Mut { .. } => true,
427427
});
428428

compiler/rustc_borrowck/src/lib.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ use self::ReadOrWrite::{Activation, Read, Reservation, Write};
846846
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
847847
enum ArtificialField {
848848
ArrayLength,
849-
ShallowBorrow,
849+
FakeBorrow,
850850
}
851851

852852
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -1085,18 +1085,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10851085
Control::Continue
10861086
}
10871087

1088-
(Read(_), BorrowKind::Shared | BorrowKind::Shallow)
1089-
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => {
1088+
(Read(_), BorrowKind::Shared | BorrowKind::Fake)
1089+
| (Read(ReadKind::Borrow(BorrowKind::Fake)), BorrowKind::Mut { .. }) => {
10901090
Control::Continue
10911091
}
10921092

1093-
(Reservation(_), BorrowKind::Shallow | BorrowKind::Shared) => {
1093+
(Reservation(_), BorrowKind::Fake | BorrowKind::Shared) => {
10941094
// This used to be a future compatibility warning (to be
10951095
// disallowed on NLL). See rust-lang/rust#56254
10961096
Control::Continue
10971097
}
10981098

1099-
(Write(WriteKind::Move), BorrowKind::Shallow) => {
1099+
(Write(WriteKind::Move), BorrowKind::Fake) => {
11001100
// Handled by initialization checks.
11011101
Control::Continue
11021102
}
@@ -1204,8 +1204,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12041204
match rvalue {
12051205
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
12061206
let access_kind = match bk {
1207-
BorrowKind::Shallow => {
1208-
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
1207+
BorrowKind::Fake => {
1208+
(Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
12091209
}
12101210
BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))),
12111211
BorrowKind::Mut { .. } => {
@@ -1226,7 +1226,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12261226
flow_state,
12271227
);
12281228

1229-
let action = if bk == BorrowKind::Shallow {
1229+
let action = if bk == BorrowKind::Fake {
12301230
InitializationRequiringAction::MatchOn
12311231
} else {
12321232
InitializationRequiringAction::Borrow
@@ -1583,7 +1583,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15831583

15841584
// only mutable borrows should be 2-phase
15851585
assert!(match borrow.kind {
1586-
BorrowKind::Shared | BorrowKind::Shallow => false,
1586+
BorrowKind::Shared | BorrowKind::Fake => false,
15871587
BorrowKind::Mut { .. } => true,
15881588
});
15891589

@@ -2142,14 +2142,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21422142
| WriteKind::Replace
21432143
| WriteKind::StorageDeadOrDrop
21442144
| WriteKind::MutableBorrow(BorrowKind::Shared)
2145-
| WriteKind::MutableBorrow(BorrowKind::Shallow),
2145+
| WriteKind::MutableBorrow(BorrowKind::Fake),
21462146
)
21472147
| Write(
21482148
WriteKind::Move
21492149
| WriteKind::Replace
21502150
| WriteKind::StorageDeadOrDrop
21512151
| WriteKind::MutableBorrow(BorrowKind::Shared)
2152-
| WriteKind::MutableBorrow(BorrowKind::Shallow),
2152+
| WriteKind::MutableBorrow(BorrowKind::Fake),
21532153
) => {
21542154
if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
21552155
&& !self.has_buffered_errors()
@@ -2173,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21732173
return false;
21742174
}
21752175
Read(
2176-
ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow)
2176+
ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake)
21772177
| ReadKind::Copy,
21782178
) => {
21792179
// Access authorized

compiler/rustc_borrowck/src/places_conflict.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ fn place_components_conflict<'tcx>(
204204

205205
match (elem, &base_ty.kind(), access) {
206206
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
207-
| (_, _, Shallow(Some(ArtificialField::ShallowBorrow))) => {
207+
| (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
208208
// The array length is like additional fields on the
209209
// type; it does not overlap any existing data there.
210210
// Furthermore, if cannot actually be a prefix of any
@@ -273,10 +273,10 @@ fn place_components_conflict<'tcx>(
273273
// If the second example, where we did, then we still know
274274
// that the borrow can access a *part* of our place that
275275
// our access cares about, so we still have a conflict.
276-
if borrow_kind == BorrowKind::Shallow
276+
if borrow_kind == BorrowKind::Fake
277277
&& borrow_place.projection.len() < access_place.projection.len()
278278
{
279-
debug!("borrow_conflicts_with_place: shallow borrow");
279+
debug!("borrow_conflicts_with_place: fake borrow");
280280
false
281281
} else {
282282
debug!("borrow_conflicts_with_place: full borrow, CONFLICT");

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
751751
PlaceContext::MutatingUse(_) => ty::Invariant,
752752
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
753753
PlaceContext::NonMutatingUse(
754-
Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | AddressOf
754+
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | AddressOf
755755
| Projection,
756756
) => ty::Covariant,
757757
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,

compiler/rustc_codegen_ssa/src/mir/analyze.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
219219
| PlaceContext::NonMutatingUse(
220220
NonMutatingUseContext::Inspect
221221
| NonMutatingUseContext::SharedBorrow
222-
| NonMutatingUseContext::ShallowBorrow
222+
| NonMutatingUseContext::FakeBorrow
223223
| NonMutatingUseContext::AddressOf
224224
| NonMutatingUseContext::Projection,
225225
) => {

compiler/rustc_const_eval/src/transform/check_consts/check.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
423423
BorrowKind::Shared => {
424424
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
425425
}
426-
BorrowKind::Shallow => {
427-
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
426+
BorrowKind::Fake => {
427+
PlaceContext::NonMutatingUse(NonMutatingUseContext::FakeBorrow)
428428
}
429429
BorrowKind::Mut { .. } => {
430430
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
@@ -500,7 +500,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
500500
self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
501501
}
502502

503-
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, place)
503+
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake, place)
504504
| Rvalue::AddressOf(Mutability::Not, place) => {
505505
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
506506
&self.ccx,

0 commit comments

Comments
 (0)