@@ -194,76 +194,75 @@ pub struct cmt_<'tcx> {
194
194
195
195
pub type cmt < ' tcx > = Rc < cmt_ < ' tcx > > ;
196
196
197
+ pub enum ImmutabilityBlame < ' tcx > {
198
+ ImmLocal ( ast:: NodeId ) ,
199
+ ClosureEnv ( ast:: NodeId ) ,
200
+ LocalDeref ( ast:: NodeId ) ,
201
+ AdtFieldDeref ( & ' tcx ty:: AdtDef , & ' tcx ty:: FieldDef )
202
+ }
203
+
197
204
impl < ' tcx > cmt_ < ' tcx > {
198
- pub fn get_def ( & self ) -> Option < ast:: NodeId > {
199
- match self . cat {
200
- Categorization :: Deref ( ref cmt, ..) |
201
- Categorization :: Interior ( ref cmt, _) |
202
- Categorization :: Downcast ( ref cmt, _) => {
203
- if let Categorization :: Local ( nid) = cmt. cat {
204
- Some ( nid)
205
- } else {
206
- None
207
- }
205
+ fn resolve_field ( & self , field_name : FieldName ) -> ( & ' tcx ty:: AdtDef , & ' tcx ty:: FieldDef )
206
+ {
207
+ let adt_def = self . ty . ty_adt_def ( ) . unwrap_or_else ( || {
208
+ bug ! ( "interior cmt {:?} is not an ADT" , self )
209
+ } ) ;
210
+ let variant_def = match self . cat {
211
+ Categorization :: Downcast ( _, variant_did) => {
212
+ adt_def. variant_with_id ( variant_did)
208
213
}
209
- _ => None
210
- }
214
+ _ => {
215
+ assert ! ( adt_def. is_univariant( ) ) ;
216
+ & adt_def. variants [ 0 ]
217
+ }
218
+ } ;
219
+ let field_def = match field_name {
220
+ NamedField ( name) => variant_def. field_named ( name) ,
221
+ PositionalField ( idx) => & variant_def. fields [ idx]
222
+ } ;
223
+ ( adt_def, field_def)
211
224
}
212
225
213
- pub fn get_field ( & self , name : ast :: Name ) -> Option < DefId > {
226
+ pub fn immutability_blame ( & self ) -> Option < ImmutabilityBlame < ' tcx > > {
214
227
match self . cat {
215
- Categorization :: Deref ( ref cmt, ..) |
216
- Categorization :: Interior ( ref cmt, _) |
217
- Categorization :: Downcast ( ref cmt, _) => {
218
- if let Categorization :: Local ( _) = cmt. cat {
219
- if let ty:: TyAdt ( def, _) = self . ty . sty {
220
- if def. is_struct ( ) {
221
- return def. struct_variant ( ) . find_field_named ( name) . map ( |x| x. did ) ;
228
+ Categorization :: Deref ( ref base_cmt, _, BorrowedPtr ( ty:: ImmBorrow , _) ) |
229
+ Categorization :: Deref ( ref base_cmt, _, Implicit ( ty:: ImmBorrow , _) ) => {
230
+ // try to figure out where the immutable reference came from
231
+ match base_cmt. cat {
232
+ Categorization :: Local ( node_id) =>
233
+ Some ( ImmutabilityBlame :: LocalDeref ( node_id) ) ,
234
+ Categorization :: Interior ( ref base_cmt, InteriorField ( field_name) ) => {
235
+ let ( adt_def, field_def) = base_cmt. resolve_field ( field_name) ;
236
+ Some ( ImmutabilityBlame :: AdtFieldDeref ( adt_def, field_def) )
237
+ }
238
+ Categorization :: Upvar ( Upvar { id, .. } ) => {
239
+ if let NoteClosureEnv ( ..) = self . note {
240
+ Some ( ImmutabilityBlame :: ClosureEnv ( id. closure_expr_id ) )
241
+ } else {
242
+ None
222
243
}
223
244
}
224
- None
225
- } else {
226
- cmt. get_field ( name)
245
+ _ => None
227
246
}
228
247
}
229
- _ => None
230
- }
231
- }
232
-
233
- pub fn get_field_name ( & self ) -> Option < ast:: Name > {
234
- match self . cat {
235
- Categorization :: Interior ( _, ref ik) => {
236
- if let InteriorKind :: InteriorField ( FieldName :: NamedField ( name) ) = * ik {
237
- Some ( name)
238
- } else {
239
- None
240
- }
248
+ Categorization :: Local ( node_id) => {
249
+ Some ( ImmutabilityBlame :: ImmLocal ( node_id) )
241
250
}
242
- Categorization :: Deref ( ref cmt, ..) |
243
- Categorization :: Downcast ( ref cmt, _) => {
244
- cmt. get_field_name ( )
251
+ Categorization :: Rvalue ( ..) |
252
+ Categorization :: Upvar ( ..) |
253
+ Categorization :: Deref ( .., UnsafePtr ( ..) ) => {
254
+ // This should not be reachable up to inference limitations.
255
+ None
245
256
}
246
- _ => None ,
247
- }
248
- }
249
-
250
- pub fn get_arg_if_immutable ( & self , map : & hir_map:: Map ) -> Option < ast:: NodeId > {
251
- match self . cat {
252
- Categorization :: Deref ( ref cmt, ..) |
253
- Categorization :: Interior ( ref cmt, _) |
254
- Categorization :: Downcast ( ref cmt, _) => {
255
- if let Categorization :: Local ( nid) = cmt. cat {
256
- if let ty:: TyAdt ( _, _) = self . ty . sty {
257
- if let ty:: TyRef ( _, ty:: TypeAndMut { mutbl : MutImmutable , ..} ) = cmt. ty . sty {
258
- return Some ( nid) ;
259
- }
260
- }
261
- None
262
- } else {
263
- cmt. get_arg_if_immutable ( map)
264
- }
257
+ Categorization :: Interior ( ref base_cmt, _) |
258
+ Categorization :: Downcast ( ref base_cmt, _) |
259
+ Categorization :: Deref ( ref base_cmt, _, _) => {
260
+ base_cmt. immutability_blame ( )
261
+ }
262
+ Categorization :: StaticItem => {
263
+ // Do we want to do something here?
264
+ None
265
265
}
266
- _ => None
267
266
}
268
267
}
269
268
}
@@ -1282,9 +1281,6 @@ pub enum Aliasability {
1282
1281
#[ derive( Copy , Clone , Debug ) ]
1283
1282
pub enum AliasableReason {
1284
1283
AliasableBorrowed ,
1285
- AliasableClosure ( ast:: NodeId ) , // Aliasable due to capture Fn closure env
1286
- AliasableOther ,
1287
- UnaliasableImmutable , // Created as needed upon seeing ImmutableUnique
1288
1284
AliasableStatic ,
1289
1285
AliasableStaticMut ,
1290
1286
}
@@ -1324,23 +1320,13 @@ impl<'tcx> cmt_<'tcx> {
1324
1320
Categorization :: Deref ( ref b, _, Implicit ( ty:: MutBorrow , _) ) |
1325
1321
Categorization :: Deref ( ref b, _, BorrowedPtr ( ty:: UniqueImmBorrow , _) ) |
1326
1322
Categorization :: Deref ( ref b, _, Implicit ( ty:: UniqueImmBorrow , _) ) |
1323
+ Categorization :: Deref ( ref b, _, Unique ) |
1327
1324
Categorization :: Downcast ( ref b, _) |
1328
1325
Categorization :: Interior ( ref b, _) => {
1329
1326
// Aliasability depends on base cmt
1330
1327
b. freely_aliasable ( )
1331
1328
}
1332
1329
1333
- Categorization :: Deref ( ref b, _, Unique ) => {
1334
- let sub = b. freely_aliasable ( ) ;
1335
- if b. mutbl . is_mutable ( ) {
1336
- // Aliasability depends on base cmt alone
1337
- sub
1338
- } else {
1339
- // Do not allow mutation through an immutable box.
1340
- ImmutableUnique ( Box :: new ( sub) )
1341
- }
1342
- }
1343
-
1344
1330
Categorization :: Rvalue ( ..) |
1345
1331
Categorization :: Local ( ..) |
1346
1332
Categorization :: Upvar ( ..) |
@@ -1356,13 +1342,9 @@ impl<'tcx> cmt_<'tcx> {
1356
1342
}
1357
1343
}
1358
1344
1359
- Categorization :: Deref ( ref base, _, BorrowedPtr ( ty:: ImmBorrow , _) ) |
1360
- Categorization :: Deref ( ref base, _, Implicit ( ty:: ImmBorrow , _) ) => {
1361
- match base. cat {
1362
- Categorization :: Upvar ( Upvar { id, .. } ) =>
1363
- FreelyAliasable ( AliasableClosure ( id. closure_expr_id ) ) ,
1364
- _ => FreelyAliasable ( AliasableBorrowed )
1365
- }
1345
+ Categorization :: Deref ( _, _, BorrowedPtr ( ty:: ImmBorrow , _) ) |
1346
+ Categorization :: Deref ( _, _, Implicit ( ty:: ImmBorrow , _) ) => {
1347
+ FreelyAliasable ( AliasableBorrowed )
1366
1348
}
1367
1349
}
1368
1350
}
0 commit comments