11use formality_core:: {
2- Cons , Fallible , Set , judgment_fn, variable:: CoreUniversalVar
2+ Cons , Fallible , Set , judgment_fn, variable:: CoreUniversalVar , term
33} ;
4- use formality_rust:: grammar:: minirust:: { BasicBlock , Statement , Terminator , ValueExpression } ;
4+ use formality_rust:: grammar:: minirust:: { BasicBlock , PlaceExpression , Statement , Terminator , ValueExpression } ;
55use formality_types:: {
6- grammar:: Wcs ,
6+ grammar:: { Lt , RefKind , Wcs } ,
77 rust:: FormalityLang ,
88} ;
99use formality_prove:: combinators:: for_all;
1010
11- use crate :: mini_rust_check:: { Location , TypeckEnv } ;
11+ use crate :: { borrow_check :: liveness :: LivePlaces , mini_rust_check:: { Location , TypeckEnv } } ;
1212
1313/// So what is a lifetime? The NLL answer is that a lifetime corresponds to one of the following:
1414///
@@ -138,7 +138,7 @@ judgment_fn! {
138138 fn loans_in_basic_block_respected(
139139 env: TypeckEnv ,
140140 fn_assumptions: Wcs ,
141- block: BasicBlock
141+ block: BasicBlock ,
142142 ) => ( ) {
143143 debug( block, fn_assumptions, env)
144144
@@ -150,6 +150,7 @@ judgment_fn! {
150150 )
151151 }
152152}
153+
153154judgment_fn ! {
154155 /// Prove that any loans issued in this statement are respected.
155156 fn loans_in_statements_respected(
@@ -173,7 +174,6 @@ judgment_fn! {
173174 }
174175}
175176
176-
177177judgment_fn ! {
178178 /// Prove that any loans issued in this statement are respected.
179179 fn loans_in_terminator_respected(
@@ -238,4 +238,127 @@ judgment_fn! {
238238
239239
240240 }
241- }
241+ }
242+
243+ pub type Loans = Set < Loan > ;
244+
245+ #[ term]
246+
247+ struct Loan {
248+ lt : Lt ,
249+ place : PlaceExpression ,
250+ kind : RefKind ,
251+ }
252+
253+
254+ judgment_fn ! {
255+ /// Prove that any loans issued in this statement are respected.
256+ fn borrow_check_statement(
257+ env: TypeckEnv ,
258+ assumptions: Wcs ,
259+ loaned_on_entry: Loans ,
260+ live_after: LivePlaces ,
261+ statement: Statement ,
262+ ) => Loans {
263+ debug( statement, loaned_on_entry, live_after, assumptions, env)
264+
265+ (
266+ ( place_not_borrowed_by_any( env, assumptions, & loaned, live_after, local_id) => ( ) )
267+ --- ( "storage-dead" )
268+ ( borrow_check_statement( env, assumptions, loaned, live_after, Statement :: StorageDead ( local_id) ) => & loaned)
269+ )
270+ }
271+ }
272+
273+
274+
275+ judgment_fn ! {
276+ /// Prove that none of the borrows in `borrowed` does not affect `place`.
277+ fn place_not_borrowed_by_any(
278+ env: TypeckEnv ,
279+ assumptions: Wcs ,
280+ loaned: Set <Loan >,
281+ live_after: LivePlaces ,
282+ accessed_place: PlaceExpression ,
283+ ) => ( ) {
284+ debug( accessed_place, loaned, live_after, assumptions, env)
285+
286+ (
287+ // Clearly, `place` is not borrowed if nothing has been borrowed.
288+ --- ( "no borrows" )
289+ ( place_not_borrowed_by_any( _env, _assumptions, ( ) , _live_after, _place) => ( ) )
290+ )
291+
292+ (
293+ ( place_not_borrowed_by( & env, & assumptions, head, & live_after, & place) => ( ) )
294+ ( place_not_borrowed_by_any( & env, & assumptions, & tail, & live_after, & place) => ( ) )
295+ --- ( "no borrows" )
296+ ( place_not_borrowed_by_any( env, assumptions, Cons ( head, tail) , live_after, place) => ( ) )
297+ )
298+ }
299+ }
300+
301+ judgment_fn ! {
302+ /// Prove that the borrow `borrow` does not affect `place`.
303+ fn place_not_borrowed_by(
304+ env: TypeckEnv ,
305+ fn_assumptions: Wcs ,
306+ loan: Loan ,
307+ live_after: LivePlaces ,
308+ accessed_place: PlaceExpression ,
309+ ) => ( ) {
310+ debug( accessed_place, loan, live_after, fn_assumptions, env)
311+
312+ (
313+ ( place_disjoint_from_place( loan. place, accessed_place) => ( ) )
314+ --- ( "borrows of disjoint places" )
315+ ( place_not_borrowed_by(<
C46B
/span>_env, _assumptions, loan, _live_after, accessed_place) => ( ) )
316+ )
317+
318+ (
319+ --- ( "borrow not live -- no live places" )
320+ ( place_not_borrowed_by( _env, _assumptions, _loan, ( ) , _accessed_place) => ( ) )
321+ )
322+
323+ (
324+ ( place_not_borrowed_by_live_variable( & env, & assumptions, & head, & loan, & accessed_place) => ( ) )
325+ ( place_not_borrowed_by( & env, & assumptions, & loan, & tail, & accessed_place) => ( ) )
326+ --- ( "borrow not live -- live place" )
327+ ( place_not_borrowed_by( env, assumptions, loan, Cons ( head, tail) , accessed_place) => ( ) )
328+ )
329+ }
330+ }
331+
332+ judgment_fn ! {
333+ /// Prove that `accessed_place` can still be accessed even though `live_place` is live and the borrow occurs.
334+ fn place_not_borrowed_by_live_variable(
335+ env: TypeckEnv ,
336+ assumptions: Wcs ,
337+ live_place: PlaceExpression ,
338+ borrowed_place: Loan ,
339+ accessed_place: PlaceExpression ,
340+ ) => ( ) {
341+ debug( accessed_place, borrowed_place, live_place, assumptions, env)
342+
343+ }
344+ }
345+
346+ judgment_fn ! {
347+ fn place_disjoint_from_place(
348+ place1: PlaceExpression ,
349+ place2: PlaceExpression ,
350+ ) => ( ) {
351+ debug( place1, place2)
352+
353+ (
354+ ( if local1 != local2)
355+ --- ( "different locals" )
356+ ( place_disjoint_from_place(
357+ PlaceExpression :: Local ( local1) ,
358+ PlaceExpression :: Local ( local2) ,
359+ ) => ( ) )
360+ )
361+
362+ // ... fill this in ...
363+ }
364+ }
0 commit comments