1010
1111use rustc:: mir:: { self , Location , Mir } ;
1212use rustc:: mir:: visit:: Visitor ;
13- use rustc:: ty:: { Region , TyCtxt } ;
13+ use rustc:: ty:: { self , Region , TyCtxt } ;
1414use rustc:: ty:: RegionKind ;
1515use rustc:: ty:: RegionKind :: ReScope ;
1616use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -71,10 +71,14 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
7171 mir : & ' a Mir < ' tcx > ,
7272 nonlexical_regioncx : Option < & ' a RegionInferenceContext < ' tcx > > )
7373 -> Self {
74- let mut visitor = GatherBorrows { idx_vec : IndexVec :: new ( ) ,
75- location_map : FxHashMap ( ) ,
76- region_map : FxHashMap ( ) ,
77- region_span_map : FxHashMap ( ) } ;
74+ let mut visitor = GatherBorrows {
75+ tcx,
76+ mir,
77+ idx_vec : IndexVec :: new ( ) ,
78+ location_map : FxHashMap ( ) ,
79+ region_map : FxHashMap ( ) ,
80+ region_span_map : FxHashMap ( )
81+ } ;
7882 visitor. visit_mir ( mir) ;
7983 return Borrows { tcx : tcx,
8084 mir : mir,
@@ -84,17 +88,22 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
8488 region_span_map : visitor. region_span_map ,
8589 nonlexical_regioncx } ;
8690
87- struct GatherBorrows < ' tcx > {
91+ struct GatherBorrows < ' a , ' gcx : ' tcx , ' tcx : ' a > {
92+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
93+ mir : & ' a Mir < ' tcx > ,
8894 idx_vec : IndexVec < BorrowIndex , BorrowData < ' tcx > > ,
8995 location_map : FxHashMap < Location , BorrowIndex > ,
9096 region_map : FxHashMap < Region < ' tcx > , FxHashSet < BorrowIndex > > ,
9197 region_span_map : FxHashMap < RegionKind , Span > ,
9298 }
93- impl < ' tcx > Visitor < ' tcx > for GatherBorrows < ' tcx > {
99+
100+ impl < ' a , ' gcx , ' tcx > Visitor < ' tcx > for GatherBorrows < ' a , ' gcx , ' tcx > {
94101 fn visit_rvalue ( & mut self ,
95102 rvalue : & mir:: Rvalue < ' tcx > ,
96103 location : mir:: Location ) {
97104 if let mir:: Rvalue :: Ref ( region, kind, ref lvalue) = * rvalue {
105+ if is_unsafe_lvalue ( self . tcx , self . mir , lvalue) { return ; }
106+
98107 let borrow = BorrowData {
99108 location : location, kind : kind, region : region, lvalue : lvalue. clone ( ) ,
100109 } ;
@@ -197,7 +206,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
197206 }
198207
199208 mir:: StatementKind :: Assign ( _, ref rhs) => {
200- if let mir:: Rvalue :: Ref ( region, _, _) = * rhs {
209+ if let mir:: Rvalue :: Ref ( region, _, ref lvalue) = * rhs {
210+ if is_unsafe_lvalue ( self . tcx , self . mir , lvalue) { return ; }
201211 let index = self . location_map . get ( & location) . unwrap_or_else ( || {
202212 panic ! ( "could not find BorrowIndex for location {:?}" , location) ;
203213 } ) ;
@@ -248,3 +258,35 @@ impl<'a, 'gcx, 'tcx> DataflowOperator for Borrows<'a, 'gcx, 'tcx> {
248258 false // bottom = no Rvalue::Refs are active by default
249259 }
250260}
261+
262+ fn is_unsafe_lvalue < ' a , ' gcx : ' tcx , ' tcx : ' a > (
263+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
264+ mir : & ' a Mir < ' tcx > ,
265+ lvalue : & mir:: Lvalue < ' tcx >
266+ ) -> bool {
267+ use self :: mir:: Lvalue :: * ;
268+ use self :: mir:: ProjectionElem ;
269+
270+ match * lvalue {
271+ Local ( _) => false ,
272+ Static ( ref static_) => tcx. is_static_mut ( static_. def_id ) ,
273+ Projection ( ref proj) => {
274+ match proj. elem {
275+ ProjectionElem :: Field ( ..) |
276+ ProjectionElem :: Downcast ( ..) |
277+ ProjectionElem :: Subslice { .. } |
278+ ProjectionElem :: ConstantIndex { .. } |
279+ ProjectionElem :: Index ( _) => {
280+ is_unsafe_lvalue ( tcx, mir, & proj. base )
281+ }
282+ ProjectionElem :: Deref => {
283+ let ty = proj. base . ty ( mir, tcx) . to_ty ( tcx) ;
284+ match ty. sty {
285+ ty:: TyRawPtr ( ..) => true ,
286+ _ => is_unsafe_lvalue ( tcx, mir, & proj. base ) ,
287+ }
288+ }
289+ }
290+ }
291+ }
292+ }
0 commit comments