@@ -5,7 +5,11 @@ use rustc_target::abi::{Abi, Align, Size};
55use crate :: borrow_tracker:: { AccessKind , GlobalStateInner , ProtectorKind , RetagFields } ;
66use rustc_middle:: {
77 mir:: { Mutability , RetagKind } ,
8- ty:: { self , layout:: HasParamEnv , Ty } ,
8+ ty:: {
9+ self ,
10+ layout:: { HasParamEnv , HasTyCtxt } ,
11+ Ty ,
12+ } ,
913} ;
1014use rustc_span:: def_id:: DefId ;
1115
@@ -174,6 +178,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
174178 new_tag : BorTag ,
175179 ) -> InterpResult < ' tcx , Option < Provenance > > {
176180 let this = self . eval_context_mut ( ) ;
181+ // Make sure the new permission makes sense as the initial permission of a fresh tag.
182+ assert ! ( new_perm. initial_state. is_initial( ) ) ;
177183 // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
178184 this. check_ptr_access_align (
179185 place. ptr ( ) ,
@@ -275,10 +281,6 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
275281 diagnostics:: AccessCause :: Reborrow ,
276282 ) ?;
277283 // Record the parent-child pair in the tree.
278- // FIXME: We should eventually ensure that the following `assert` holds, because
279- // some "exhaustive" tests consider only the initial configurations that satisfy it.
280- // The culprit is `Permission::new_active` in `tb_protect_place`.
281- //assert!(new_perm.initial_state.is_initial());
282284 tree_borrows. new_child ( orig_tag, new_tag, new_perm. initial_state , range, span) ?;
283285 drop ( tree_borrows) ;
284286
@@ -306,15 +308,12 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
306308 Ok ( Some ( Provenance :: Concrete { alloc_id, tag : new_tag } ) )
307309 }
308310
309- /// Retags an individual pointer, returning the retagged version.
310- fn tb_retag_reference (
311+ fn tb_retag_place (
311312 & mut self ,
312- val : & ImmTy < ' tcx , Provenance > ,
313+ place : & MPlaceTy < ' tcx , Provenance > ,
313314 new_perm : NewPermission ,
314- ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
315+ ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , Provenance > > {
315316 let this = self . eval_context_mut ( ) ;
316- // We want a place for where the ptr *points to*, so we get one.
317- let place = this. ref_to_mplace ( val) ?;
318317
319318 // Determine the size of the reborrow.
320319 // For most types this is the entire size of the place, however
@@ -323,7 +322,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
323322 // then we override the size to do a zero-length reborrow.
324323 let reborrow_size = match new_perm {
325324 NewPermission { zero_size : false , .. } =>
326- this. size_and_align_of_mplace ( & place) ?
325+ this. size_and_align_of_mplace ( place) ?
327326 . map ( |( size, _) | size)
328327 . unwrap_or ( place. layout . size ) ,
329328 _ => Size :: from_bytes ( 0 ) ,
@@ -339,12 +338,21 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
339338 let new_tag = this. machine . borrow_tracker . as_mut ( ) . unwrap ( ) . get_mut ( ) . new_ptr ( ) ;
340339
341340 // Compute the actual reborrow.
342- let new_prov = this. tb_reborrow ( & place, reborrow_size, new_perm, new_tag) ?;
341+ let new_prov = this. tb_reborrow ( place, reborrow_size, new_perm, new_tag) ?;
343342
344- // Adjust pointer.
345- let new_place = place. map_provenance ( |_| new_prov) ;
343+ // Adjust place.
344+ Ok ( place. clone ( ) . map_provenance ( |_| new_prov) )
345+ }
346346
347- // Return new pointer.
347+ /// Retags an individual pointer, returning the retagged version.
348+ fn tb_retag_reference (
349+ & mut self ,
350+ val : & ImmTy < ' tcx , Provenance > ,
351+ new_perm : NewPermission ,
352+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
353+ let this = self . eval_context_mut ( ) ;
354+ let place = this. ref_to_mplace ( val) ?;
355+ let new_place = this. tb_retag_place ( & place, new_perm) ?;
348356 Ok ( ImmTy :: from_immediate ( new_place. to_ref ( this) , val. layout ) )
349357 }
350358}
@@ -493,22 +501,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
493501 /// call.
494502 ///
495503 /// This is used to ensure soundness of in-place function argument/return passing.
496- fn tb_protect_place ( & mut self , place : & MPlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
504+ fn tb_protect_place (
505+ & mut self ,
506+ place : & MPlaceTy < ' tcx , Provenance > ,
507+ ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , Provenance > > {
497508 let this = self . eval_context_mut ( ) ;
498509
499- // We have to turn the place into a pointer to use the usual retagging logic.
500- // (The pointer type does not matter, so we use a raw pointer.)
501- let ptr = this. mplace_to_ref ( place) ?;
502- // Reborrow it. With protection! That is the entire point.
510+ // Retag it. With protection! That is the entire point.
503511 let new_perm = NewPermission {
504- initial_state : Permission :: new_active ( ) ,
512+ initial_state : Permission :: new_reserved (
513+ place. layout . ty . is_freeze ( this. tcx ( ) , this. param_env ( ) ) ,
514+ ) ,
505515 zero_size : false ,
506516 protector : Some ( ProtectorKind :: StrongProtector ) ,
507517 } ;
508- let _new_ptr = this. tb_retag_reference ( & ptr, new_perm) ?;
509- // We just throw away `new_ptr`, so nobody can access this memory while it is protected.
510-
511- Ok ( ( ) )
518+ this. tb_retag_place ( place, new_perm)
512519 }
513520
514521 /// Mark the given tag as exposed. It was found on a pointer with the given AllocId.
0 commit comments