@@ -2,7 +2,9 @@ use tracing::instrument;
2
2
3
3
use crate :: free_pcs:: CapabilityKind ;
4
4
use crate :: rustc_interface:: { ast:: Mutability , middle:: mir:: Location } ;
5
+ use crate :: utils:: display:: DisplayWithRepacker ;
5
6
use crate :: utils:: { Place , PlaceRepacker , SnapshotLocation } ;
7
+ use crate :: { RestoreCapability , Weaken } ;
6
8
7
9
use super :: borrow_pcg_edge:: { BorrowPCGEdge , LocalNode , ToBorrowsEdge } ;
8
10
use super :: borrow_pcg_expansion:: BorrowPCGExpansion ;
@@ -22,11 +24,67 @@ use super::region_projection_member::RegionProjectionMember;
22
24
/// in the `BorrowsVisitor`?
23
25
#[ derive( Clone , Debug ) ]
24
26
pub struct BorrowPCGAction < ' tcx > {
25
- kind : BorrowPCGActionKind < ' tcx > ,
27
+ pub ( crate ) kind : BorrowPCGActionKind < ' tcx > ,
26
28
debug_context : Option < String > ,
27
29
}
28
30
29
31
impl < ' tcx > BorrowPCGAction < ' tcx > {
32
+ pub ( crate ) fn debug_line ( & self , repacker : PlaceRepacker < ' _ , ' tcx > ) -> String {
33
+ match & self . kind {
34
+ BorrowPCGActionKind :: Weaken ( weaken) => weaken. debug_line ( repacker) ,
35
+ BorrowPCGActionKind :: Restore ( restore_capability) => {
36
+ restore_capability. debug_line ( repacker)
37
+ }
38
+ BorrowPCGActionKind :: MakePlaceOld ( place) => {
39
+ format ! ( "Make {} an old place" , place. to_short_string( repacker) )
40
+ }
41
+ BorrowPCGActionKind :: SetLatest ( place, location) => format ! (
42
+ "Set Latest of {} to {:?}" ,
43
+ place. to_short_string( repacker) ,
44
+ location
45
+ ) ,
46
+ BorrowPCGActionKind :: RemoveEdge ( borrow_pcgedge) => {
47
+ format ! ( "Remove Edge {}" , borrow_pcgedge. to_short_string( repacker) )
48
+ }
49
+ BorrowPCGActionKind :: AddRegionProjectionMember (
50
+ region_projection_member,
51
+ path_conditions,
52
+ ) => format ! (
53
+ "Add Region Projection Member: {}; path conditions: {}" ,
54
+ region_projection_member. to_short_string( repacker) ,
55
+ path_conditions
56
+ ) ,
57
+ BorrowPCGActionKind :: InsertBorrowPCGExpansion ( borrow_pcgexpansion, location) => {
58
+ format ! (
59
+ "Insert Expansion {} at {:?}" ,
60
+ borrow_pcgexpansion. to_short_string( repacker) ,
61
+ location
62
+ )
63
+ }
64
+ BorrowPCGActionKind :: RenamePlace { old, new } => {
65
+ format ! ( "Rename {:?} to {:?}" , old, new)
66
+ }
67
+ }
68
+ }
69
+
70
+ pub fn kind ( & self ) -> & BorrowPCGActionKind < ' tcx > {
71
+ & self . kind
72
+ }
73
+
74
+ pub ( super ) fn restore_capability ( node : LocalNode < ' tcx > , capability : CapabilityKind ) -> Self {
75
+ BorrowPCGAction {
76
+ kind : BorrowPCGActionKind :: Restore ( RestoreCapability :: new ( node, capability) ) ,
77
+ debug_context : None ,
78
+ }
79
+ }
80
+
81
+ pub ( super ) fn weaken ( place : Place < ' tcx > , from : CapabilityKind , to : CapabilityKind ) -> Self {
82
+ BorrowPCGAction {
83
+ kind : BorrowPCGActionKind :: Weaken ( Weaken :: new ( place, from, to) ) ,
84
+ debug_context : None ,
85
+ }
86
+ }
87
+
30
88
pub ( super ) fn rename_place ( old : MaybeOldPlace < ' tcx > , new : MaybeOldPlace < ' tcx > ) -> Self {
31
89
BorrowPCGAction {
32
90
kind : BorrowPCGActionKind :: RenamePlace { old, new } ,
@@ -91,7 +149,9 @@ impl<'tcx> From<BorrowPCGActionKind<'tcx>> for BorrowPCGAction<'tcx> {
91
149
}
92
150
93
151
#[ derive( Clone , Debug ) ]
94
- pub ( crate ) enum BorrowPCGActionKind < ' tcx > {
152
+ pub enum BorrowPCGActionKind < ' tcx > {
153
+ Weaken ( Weaken < ' tcx > ) ,
154
+ Restore ( RestoreCapability < ' tcx > ) ,
95
155
MakePlaceOld ( Place < ' tcx > ) ,
96
156
SetLatest ( Place < ' tcx > , Location ) ,
97
157
RemoveEdge ( BorrowPCGEdge < ' tcx > ) ,
@@ -121,6 +181,16 @@ impl<'tcx> BorrowsState<'tcx> {
121
181
repacker : PlaceRepacker < ' _ , ' tcx > ,
122
182
) -> bool {
123
183
let result = match action. kind {
184
+ BorrowPCGActionKind :: Restore ( restore) => {
185
+ assert ! ( self . get_capability( restore. node( ) ) . unwrap( ) < restore. capability( ) ) ;
186
+ assert ! ( self . set_capability( restore. node( ) , restore. capability( ) ) ) ;
187
+ true
188
+ }
189
+ BorrowPCGActionKind :: Weaken ( weaken) => {
190
+ assert_eq ! ( self . get_capability( weaken. place( ) ) , Some ( weaken. from) ) ;
191
+ assert ! ( self . set_capability( weaken. place( ) , weaken. to) ) ;
192
+ true
193
+ }
124
194
BorrowPCGActionKind :: MakePlaceOld ( place) => self . make_place_old ( place, repacker, None ) ,
125
195
BorrowPCGActionKind :: SetLatest ( place, location) => {
126
196
self . set_latest ( place, location, repacker)
@@ -130,34 +200,45 @@ impl<'tcx> BorrowsState<'tcx> {
130
200
self . add_region_projection_member ( member, pc, repacker)
131
201
}
132
202
BorrowPCGActionKind :: InsertBorrowPCGExpansion ( de, location) => {
133
- let inserted = self . insert (
203
+ let updated = self . insert (
134
204
de. clone ( )
135
205
. to_borrow_pcg_edge ( PathConditions :: new ( location. block ) ) ,
136
206
) ;
137
- if inserted {
207
+ if updated {
138
208
let base = de. base ( ) ;
139
- let capability = match self . get_capability ( base) {
140
- Some ( c) => c,
141
- None => {
142
- // The expansion presumably already exists under
143
- // different path conditions. TODO: Maybe this is
144
- // worth checking?
145
- return inserted;
209
+ let capability = match & de {
210
+ BorrowPCGExpansion :: FromOwned ( expansion_of_owned) => {
211
+ match expansion_of_owned. base ( ) . ty ( repacker) . ty . ref_mutability ( ) {
212
+ Some ( Mutability :: Mut ) => CapabilityKind :: Exclusive ,
213
+ Some ( Mutability :: Not ) => CapabilityKind :: Read ,
214
+ None => unreachable ! ( ) ,
215
+ }
216
+ }
217
+ BorrowPCGExpansion :: FromBorrow ( expansion_of_borrowed) => {
218
+ if let Some ( capability) =
219
+ self . get_capability ( expansion_of_borrowed. base )
220
+ {
221
+ capability
222
+ } else {
223
+ // Presumably already expanded in another branch
224
+ // TODO: Check expansion capability exists
225
+ return true ;
226
+ }
146
227
}
147
228
} ;
148
229
match capability {
149
230
CapabilityKind :: Read => {
150
- self . set_capability ( base, CapabilityKind :: Read ) ;
231
+ _ = self . set_capability ( base, CapabilityKind :: Read ) ;
151
232
}
152
233
_ => {
153
- self . remove_capability ( base) ;
234
+ _ = self . remove_capability ( base) ;
154
235
}
155
236
}
156
237
for p in de. expansion ( repacker) . iter ( ) {
157
- self . set_capability ( * p, capability) ;
238
+ _ = self . set_capability ( * p, capability) ;
158
239
}
159
240
}
160
- inserted
241
+ updated
161
242
}
162
243
BorrowPCGActionKind :: RenamePlace { old, new } => self . change_pcs_elem ( old, new) ,
163
244
} ;
0 commit comments