@@ -3,55 +3,26 @@ use super::*;
33use crate :: { AnalysisDomain , GenKill , GenKillAnalysis } ;
44use rustc_middle:: mir:: visit:: Visitor ;
55use rustc_middle:: mir:: * ;
6- use rustc_middle:: ty:: { ParamEnv , TyCtxt } ;
7- use rustc_span:: DUMMY_SP ;
8-
9- pub type MaybeMutBorrowedLocals < ' mir , ' tcx > = MaybeBorrowedLocals < MutBorrow < ' mir , ' tcx > > ;
106
117/// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points
128/// to a given local.
139///
14- /// The `K` parameter determines what kind of borrows are tracked. By default,
15- /// `MaybeBorrowedLocals` looks for *any* borrow of a local. If you are only interested in borrows
16- /// that might allow mutation, use the `MaybeMutBorrowedLocals` type alias instead.
17- ///
1810/// At present, this is used as a very limited form of alias analysis. For example,
1911/// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
20- /// immovable generators. `MaybeMutBorrowedLocals` is used during const checking to prove that a
21- /// local has not been mutated via indirect assignment (e.g., `*p = 42`), the side-effects of a
22- /// function call or inline assembly.
23- pub struct MaybeBorrowedLocals < K = AnyBorrow > {
24- kind : K ,
12+ /// immovable generators.
13+ pub struct MaybeBorrowedLocals {
2514 ignore_borrow_on_drop : bool ,
2615}
2716
2817impl MaybeBorrowedLocals {
2918 /// A dataflow analysis that records whether a pointer or reference exists that may alias the
3019 /// given local.
3120 pub fn all_borrows ( ) -> Self {
32- MaybeBorrowedLocals { kind : AnyBorrow , ignore_borrow_on_drop : false }
33- }
34- }
35-
36- impl MaybeMutBorrowedLocals < ' mir , ' tcx > {
37- /// A dataflow analysis that records whether a pointer or reference exists that may *mutably*
38- /// alias the given local.
39- ///
40- /// This includes `&mut` and pointers derived from an `&mut`, as well as shared borrows of
41- /// types with interior mutability.
42- pub fn mut_borrows_only (
43- tcx : TyCtxt < ' tcx > ,
44- body : & ' mir mir:: Body < ' tcx > ,
45- param_env : ParamEnv < ' tcx > ,
46- ) -> Self {
47- MaybeBorrowedLocals {
48- kind : MutBorrow { body, tcx, param_env } ,
49- ignore_borrow_on_drop : false ,
50- }
21+ MaybeBorrowedLocals { ignore_borrow_on_drop : false }
5122 }
5223}
5324
54- impl < K > MaybeBorrowedLocals < K > {
25+ impl MaybeBorrowedLocals {
5526 /// During dataflow analysis, ignore the borrow that may occur when a place is dropped.
5627 ///
5728 /// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut self` as a
@@ -69,21 +40,14 @@ impl<K> MaybeBorrowedLocals<K> {
6940 MaybeBorrowedLocals { ignore_borrow_on_drop : true , ..self }
7041 }
7142
72- fn transfer_function < ' a , T > ( & ' a self , trans : & ' a mut T ) -> TransferFunction < ' a , T , K > {
73- TransferFunction {
74- kind : & self . kind ,
75- trans,
76- ignore_borrow_on_drop : self . ignore_borrow_on_drop ,
77- }
43+ fn transfer_function < ' a , T > ( & ' a self , trans : & ' a mut T ) -> TransferFunction < ' a , T > {
44+ TransferFunction { trans, ignore_borrow_on_drop : self . ignore_borrow_on_drop }
7845 }
7946}
8047
81- impl < K > AnalysisDomain < ' tcx > for MaybeBorrowedLocals < K >
82- where
83- K : BorrowAnalysisKind < ' tcx > ,
84- {
48+ impl AnalysisDomain < ' tcx > for MaybeBorrowedLocals {
8549 type Domain = BitSet < Local > ;
86- const NAME : & ' static str = K :: ANALYSIS_NAME ;
50+ const NAME : & ' static str = "maybe_borrowed_locals" ;
8751
8852 fn bottom_value ( & self , body : & mir:: Body < ' tcx > ) -> Self :: Domain {
8953 // bottom = unborrowed
9559 }
9660}
9761
98- impl < K > GenKillAnalysis < ' tcx > for MaybeBorrowedLocals < K >
99- where
100- K : BorrowAnalysisKind < ' tcx > ,
101- {
62+ impl GenKillAnalysis < ' tcx > for MaybeBorrowedLocals {
10263 type Idx = Local ;
10364
10465 fn statement_effect (
@@ -131,16 +92,14 @@ where
13192}
13293
13394/// A `Visitor` that defines the transfer function for `MaybeBorrowedLocals`.
134- struct TransferFunction < ' a , T , K > {
95+ struct TransferFunction < ' a , T > {
13596 trans : & ' a mut T ,
136- kind : & ' a K ,
13797 ignore_borrow_on_drop : bool ,
13898}
13999
140- impl < T , K > Visitor < ' tcx > for TransferFunction < ' a , T , K >
100+ impl < T > Visitor < ' tcx > for TransferFunction < ' a , T >
141101where
142102 T : GenKill < Local > ,
143- K : BorrowAnalysisKind < ' tcx > ,
144103{
145104 fn visit_statement ( & mut self , stmt : & Statement < ' tcx > , location : Location ) {
146105 self . super_statement ( stmt, location) ;
@@ -156,14 +115,14 @@ where
156115 self . super_rvalue ( rvalue, location) ;
157116
158117 match rvalue {
159- mir:: Rvalue :: AddressOf ( mt , borrowed_place) => {
160- if !borrowed_place. is_indirect ( ) && self . kind . in_address_of ( * mt , * borrowed_place ) {
118+ mir:: Rvalue :: AddressOf ( _mt , borrowed_place) => {
119+ if !borrowed_place. is_indirect ( ) {
161120 self . trans . gen ( borrowed_place. local ) ;
162121 }
163122 }
164123
165- mir:: Rvalue :: Ref ( _, kind , borrowed_place) => {
166- if !borrowed_place. is_indirect ( ) && self . kind . in_ref ( * kind , * borrowed_place ) {
124+ mir:: Rvalue :: Ref ( _, _kind , borrowed_place) => {
125+ if !borrowed_place. is_indirect ( ) {
167126 self . trans . gen ( borrowed_place. local ) ;
168127 }
169128 }
@@ -211,64 +170,3 @@ where
211170 }
212171 }
213172}
214-
215- pub struct AnyBorrow ;
216-
217- pub struct MutBorrow < ' mir , ' tcx > {
218- tcx : TyCtxt < ' tcx > ,
219- body : & ' mir Body < ' tcx > ,
220- param_env : ParamEnv < ' tcx > ,
221- }
222-
223- impl MutBorrow < ' mir , ' tcx > {
224- /// `&` and `&raw` only allow mutation if the borrowed place is `!Freeze`.
225- ///
226- /// This assumes that it is UB to take the address of a struct field whose type is
227- /// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of
228- /// that same struct whose type is `!Freeze`. If we decide that this is not UB, we will
229- /// have to check the type of the borrowed **local** instead of the borrowed **place**
230- /// below. See [rust-lang/unsafe-code-guidelines#134].
231- ///
232- /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
233- fn shared_borrow_allows_mutation ( & self , place : Place < ' tcx > ) -> bool {
234- !place. ty ( self . body , self . tcx ) . ty . is_freeze ( self . tcx . at ( DUMMY_SP ) , self . param_env )
235- }
236- }
237-
238- pub trait BorrowAnalysisKind < ' tcx > {
239- const ANALYSIS_NAME : & ' static str ;
240-
241- fn in_address_of ( & self , mt : Mutability , place : Place < ' tcx > ) -> bool ;
242- fn in_ref ( & self , kind : mir:: BorrowKind , place : Place < ' tcx > ) -> bool ;
243- }
244-
245- impl BorrowAnalysisKind < ' tcx > for AnyBorrow {
246- const ANALYSIS_NAME : & ' static str = "maybe_borrowed_locals" ;
247-
248- fn in_ref ( & self , _: mir:: BorrowKind , _: Place < ' _ > ) -> bool {
249- true
250- }
251- fn in_address_of ( & self , _: Mutability , _: Place < ' _ > ) -> bool {
252- true
253- }
254- }
255-
256- impl BorrowAnalysisKind < ' tcx > for MutBorrow < ' mir , ' tcx > {
257- const ANALYSIS_NAME : & ' static str = "maybe_mut_borrowed_locals" ;
258-
259- fn in_ref ( & self , kind : mir:: BorrowKind , place : Place < ' tcx > ) -> bool {
260- match kind {
261- mir:: BorrowKind :: Mut { .. } => true ,
262- mir:: BorrowKind :: Shared | mir:: BorrowKind :: Shallow | mir:: BorrowKind :: Unique => {
263- self . shared_borrow_allows_mutation ( place)
264- }
265- }
266- }
267-
268- fn in_address_of ( & self , mt : Mutability , place : Place < ' tcx > ) -> bool {
269- match mt {
270- Mutability :: Mut => true ,
271- Mutability :: Not => self . shared_borrow_allows_mutation ( place) ,
272- }
273- }
274- }
0 commit comments