@@ -4,6 +4,7 @@ use std::rc::Rc;
4
4
5
5
use rustc:: ty:: { self , layout:: Size } ;
6
6
use rustc:: hir:: { Mutability , MutMutable , MutImmutable } ;
7
+ use rustc:: mir:: RetagKind ;
7
8
8
9
use crate :: {
9
10
EvalResult , EvalErrorKind , MiriEvalContext , HelpersEvalContextExt , Evaluator , MutValueVisitor ,
@@ -550,10 +551,11 @@ trait EvalContextPrivExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
550
551
}
551
552
552
553
/// Retag an indidual pointer, returning the retagged version.
554
+ /// `mutbl` can be `None` to make this a raw pointer.
553
555
fn retag_reference (
554
556
& mut self ,
555
557
val : ImmTy < ' tcx , Borrow > ,
556
- mutbl : Mutability ,
558
+ mutbl : Option < Mutability > ,
557
559
fn_barrier : bool ,
558
560
two_phase : bool ,
559
561
) -> EvalResult < ' tcx , Immediate < Borrow > > {
@@ -571,16 +573,17 @@ trait EvalContextPrivExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
571
573
// Compute new borrow.
572
574
let time = this. machine . stacked_borrows . increment_clock ( ) ;
573
575
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 ( ) ,
576
579
} ;
577
580
578
581
// Reborrow.
579
582
this. reborrow ( place, size, fn_barrier, new_bor) ?;
580
583
let new_place = place. with_tag ( new_bor) ;
581
584
// Handle two-phase borrows.
582
585
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" ) ;
584
587
// We immediately share it, to allow read accesses
585
588
let two_phase_time = this. machine . stacked_borrows . increment_clock ( ) ;
586
589
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,
665
668
Ok ( ( ) )
666
669
}
667
670
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
-
680
671
fn retag (
681
672
& mut self ,
682
- fn_entry : bool ,
683
- two_phase : bool ,
673
+ kind : RetagKind ,
684
674
place : PlaceTy < ' tcx , Borrow >
685
675
) -> EvalResult < ' tcx > {
686
676
let this = self . eval_context_mut ( ) ;
687
677
// Determine mutability and whether to add a barrier.
688
678
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
689
679
// 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 ) > {
691
681
match ty. sty {
692
682
// 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 ) ) ,
694
686
// Boxes do not get a barrier: Barriers reflect that references outlive the call
695
687
// 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 ) ) ,
697
689
_ => None ,
698
690
}
699
691
}
700
692
701
693
// We need a visitor to visit all references. However, that requires
702
694
// a `MemPlace`, so we have a fast path for reference types that
703
695
// 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 ) {
705
697
// fast path
706
698
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 ) ?;
708
700
this. write_immediate ( val, place) ?;
709
701
return Ok ( ( ) ) ;
710
702
}
711
703
let place = this. force_allocation ( place) ?;
712
704
713
- let mut visitor = RetagVisitor { ecx : this, fn_entry , two_phase } ;
705
+ let mut visitor = RetagVisitor { ecx : this, kind } ;
714
706
visitor. visit_value ( place) ?;
715
707
716
708
// The actual visitor
717
709
struct RetagVisitor < ' ecx , ' a , ' mir , ' tcx > {
718
710
ecx : & ' ecx mut MiriEvalContext < ' a , ' mir , ' tcx > ,
719
- fn_entry : bool ,
720
- two_phase : bool ,
711
+ kind : RetagKind ,
721
712
}
722
713
impl < ' ecx , ' a , ' mir , ' tcx >
723
714
MutValueVisitor < ' a , ' mir , ' tcx , Evaluator < ' tcx > >
@@ -736,9 +727,14 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
736
727
{
737
728
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
738
729
// 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 ) {
740
731
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
+ ) ?;
742
738
self . ecx . write_immediate ( val, place. into ( ) ) ?;
743
739
}
744
740
Ok ( ( ) )
0 commit comments