@@ -3,55 +3,26 @@ use super::*;
3
3
use crate :: { AnalysisDomain , GenKill , GenKillAnalysis } ;
4
4
use rustc_middle:: mir:: visit:: Visitor ;
5
5
use 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 > > ;
10
6
11
7
/// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points
12
8
/// to a given local.
13
9
///
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
- ///
18
10
/// At present, this is used as a very limited form of alias analysis. For example,
19
11
/// `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 {
25
14
ignore_borrow_on_drop : bool ,
26
15
}
27
16
28
17
impl MaybeBorrowedLocals {
29
18
/// A dataflow analysis that records whether a pointer or reference exists that may alias the
30
19
/// given local.
31
20
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 }
51
22
}
52
23
}
53
24
54
- impl < K > MaybeBorrowedLocals < K > {
25
+ impl MaybeBorrowedLocals {
55
26
/// During dataflow analysis, ignore the borrow that may occur when a place is dropped.
56
27
///
57
28
/// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut self` as a
@@ -69,21 +40,14 @@ impl<K> MaybeBorrowedLocals<K> {
69
40
MaybeBorrowedLocals { ignore_borrow_on_drop : true , ..self }
70
41
}
71
42
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 }
78
45
}
79
46
}
80
47
81
- impl < K > AnalysisDomain < ' tcx > for MaybeBorrowedLocals < K >
82
- where
83
- K : BorrowAnalysisKind < ' tcx > ,
84
- {
48
+ impl AnalysisDomain < ' tcx > for MaybeBorrowedLocals {
85
49
type Domain = BitSet < Local > ;
86
- const NAME : & ' static str = K :: ANALYSIS_NAME ;
50
+ const NAME : & ' static str = "maybe_borrowed_locals" ;
87
51
88
52
fn bottom_value ( & self , body : & mir:: Body < ' tcx > ) -> Self :: Domain {
89
53
// bottom = unborrowed
95
59
}
96
60
}
97
61
98
- impl < K > GenKillAnalysis < ' tcx > for MaybeBorrowedLocals < K >
99
- where
100
- K : BorrowAnalysisKind < ' tcx > ,
101
- {
62
+ impl GenKillAnalysis < ' tcx > for MaybeBorrowedLocals {
102
63
type Idx = Local ;
103
64
104
65
fn statement_effect (
@@ -131,16 +92,14 @@ where
131
92
}
132
93
133
94
/// A `Visitor` that defines the transfer function for `MaybeBorrowedLocals`.
134
- struct TransferFunction < ' a , T , K > {
95
+ struct TransferFunction < ' a , T > {
135
96
trans : & ' a mut T ,
136
- kind : & ' a K ,
137
97
ignore_borrow_on_drop : bool ,
138
98
}
139
99
140
- impl < T , K > Visitor < ' tcx > for TransferFunction < ' a , T , K >
100
+ impl < T > Visitor < ' tcx > for TransferFunction < ' a , T >
141
101
where
142
102
T : GenKill < Local > ,
143
- K : BorrowAnalysisKind < ' tcx > ,
144
103
{
145
104
fn visit_statement ( & mut self , stmt : & Statement < ' tcx > , location : Location ) {
146
105
self . super_statement ( stmt, location) ;
@@ -156,14 +115,14 @@ where
156
115
self . super_rvalue ( rvalue, location) ;
157
116
158
117
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 ( ) {
161
120
self . trans . gen ( borrowed_place. local ) ;
162
121
}
163
122
}
164
123
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 ( ) {
167
126
self . trans . gen ( borrowed_place. local ) ;
168
127
}
169
128
}
@@ -211,64 +170,3 @@ where
211
170
}
212
171
}
213
172
}
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