@@ -4,6 +4,7 @@ use std::rc::Rc;
44
55use rustc:: ty:: { self , layout:: Size } ;
66use rustc:: hir:: { Mutability , MutMutable , MutImmutable } ;
7+ use rustc:: mir:: RetagKind ;
78
89use crate :: {
910 EvalResult , EvalErrorKind , MiriEvalContext , HelpersEvalContextExt , Evaluator , MutValueVisitor ,
@@ -550,10 +551,11 @@ trait EvalContextPrivExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
550551 }
551552
552553 /// Retag an indidual pointer, returning the retagged version.
554+ /// `mutbl` can be `None` to make this a raw pointer.
553555 fn retag_reference (
554556 & mut self ,
555557 val : ImmTy < ' tcx , Borrow > ,
556- mutbl : Mutability ,
558+ mutbl : Option < Mutability > ,
557559 fn_barrier : bool ,
558560 two_phase : bool ,
559561 ) -> EvalResult < ' tcx , Immediate < Borrow > > {
@@ -571,16 +573,17 @@ trait EvalContextPrivExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
571573 // Compute new borrow.
572574 let time = this. machine . stacked_borrows . increment_clock ( ) ;
573575 let new_bor = match mutbl {
574- MutMutable => Borrow :: Uniq ( time) ,
575- MutImmutable => Borrow :: Shr ( Some ( time) ) ,
576+ Some ( MutMutable ) => Borrow :: Uniq ( time) ,
577+ Some ( MutImmutable ) => Borrow :: Shr ( Some ( time) ) ,
578+ None => Borrow :: default ( ) ,
576579 } ;
577580
578581 // Reborrow.
579582 this. reborrow ( place, size, fn_barrier, new_bor) ?;
580583 let new_place = place. with_tag ( new_bor) ;
581584 // Handle two-phase borrows.
582585 if two_phase {
583- assert ! ( mutbl == MutMutable , "two-phase shared borrows make no sense" ) ;
586+ assert ! ( mutbl == Some ( MutMutable ) , "two-phase shared borrows make no sense" ) ;
584587 // We immediately share it, to allow read accesses
585588 let two_phase_time = this. machine . stacked_borrows . increment_clock ( ) ;
586589 let two_phase_bor = Borrow :: Shr ( Some ( two_phase_time) ) ;
@@ -665,59 +668,47 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
665668 Ok ( ( ) )
666669 }
667670
668- /// The given place may henceforth be accessed through raw pointers.
669- #[ inline( always) ]
670- fn escape_to_raw (
671- & mut self ,
672- place : MPlaceTy < ' tcx , Borrow > ,
673- size : Size ,
674- ) -> EvalResult < ' tcx > {
675- let this = self . eval_context_mut ( ) ;
676- this. reborrow ( place, size, /*fn_barrier*/ false , Borrow :: default ( ) ) ?;
677- Ok ( ( ) )
678- }
679-
680671 fn retag (
681672 & mut self ,
682- fn_entry : bool ,
683- two_phase : bool ,
673+ kind : RetagKind ,
684674 place : PlaceTy < ' tcx , Borrow >
685675 ) -> EvalResult < ' tcx > {
686676 let this = self . eval_context_mut ( ) ;
687677 // Determine mutability and whether to add a barrier.
688678 // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
689679 // making it useless.
690- fn qualify ( ty : ty:: Ty < ' _ > , fn_entry : bool ) -> Option < ( Mutability , bool ) > {
680+ fn qualify ( ty : ty:: Ty < ' _ > , kind : RetagKind ) -> Option < ( Option < Mutability > , bool ) > {
691681 match ty. sty {
692682 // References are simple
693- ty:: Ref ( _, _, mutbl) => Some ( ( mutbl, fn_entry) ) ,
683+ ty:: Ref ( _, _, mutbl) => Some ( ( Some ( mutbl) , kind == RetagKind :: FnEntry ) ) ,
684+ // Raw pointers need to be enabled
685+ ty:: RawPtr ( ..) if kind == RetagKind :: Raw => Some ( ( None , false ) ) ,
694686 // Boxes do not get a barrier: Barriers reflect that references outlive the call
695687 // they were passed in to; that's just not the case for boxes.
696- ty:: Adt ( ..) if ty. is_box ( ) => Some ( ( MutMutable , false ) ) ,
688+ ty:: Adt ( ..) if ty. is_box ( ) => Some ( ( Some ( MutMutable ) , false ) ) ,
697689 _ => None ,
698690 }
699691 }
700692
701693 // We need a visitor to visit all references. However, that requires
702694 // a `MemPlace`, so we have a fast path for reference types that
703695 // avoids allocating.
704- if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , fn_entry ) {
696+ if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , kind ) {
705697 // fast path
706698 let val = this. read_immediate ( this. place_to_op ( place) ?) ?;
707- let val = this. retag_reference ( val, mutbl, barrier, two_phase ) ?;
699+ let val = this. retag_reference ( val, mutbl, barrier, kind == RetagKind :: TwoPhase ) ?;
708700 this. write_immediate ( val, place) ?;
709701 return Ok ( ( ) ) ;
710702 }
711703 let place = this. force_allocation ( place) ?;
712704
713- let mut visitor = RetagVisitor { ecx : this, fn_entry , two_phase } ;
705+ let mut visitor = RetagVisitor { ecx : this, kind } ;
714706 visitor. visit_value ( place) ?;
715707
716708 // The actual visitor
717709 struct RetagVisitor < ' ecx , ' a , ' mir , ' tcx > {
718710 ecx : & ' ecx mut MiriEvalContext < ' a , ' mir , ' tcx > ,
719- fn_entry : bool ,
720- two_phase : bool ,
711+ kind : RetagKind ,
721712 }
722713 impl < ' ecx , ' a , ' mir , ' tcx >
723714 MutValueVisitor < ' a , ' mir , ' tcx , Evaluator < ' tcx > >
@@ -736,9 +727,14 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
736727 {
737728 // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
738729 // making it useless.
739- if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , self . fn_entry ) {
730+ if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , self . kind ) {
740731 let val = self . ecx . read_immediate ( place. into ( ) ) ?;
741- let val = self . ecx . retag_reference ( val, mutbl, barrier, self . two_phase ) ?;
732+ let val = self . ecx . retag_reference (
733+ val,
734+ mutbl,
735+ barrier,
736+ self . kind == RetagKind :: TwoPhase
737+ ) ?;
742738 self . ecx . write_immediate ( val, place. into ( ) ) ?;
743739 }
744740 Ok ( ( ) )
0 commit comments