@@ -106,7 +106,8 @@ pub enum PointerKind {
106
106
OwnedPtr ,
107
107
GcPtr ,
108
108
BorrowedPtr ( ty:: BorrowKind , ty:: Region ) ,
109
- UnsafePtr ( ast:: Mutability ) ,
109
+ Implicit ( ty:: BorrowKind , ty:: Region ) , // Implicit deref of a borrowed ptr.
110
+ UnsafePtr ( ast:: Mutability )
110
111
}
111
112
112
113
// We use the term "interior" to mean "something reachable from the
@@ -293,7 +294,7 @@ impl MutabilityCategory {
293
294
OwnedPtr => {
294
295
base_mutbl. inherit ( )
295
296
}
296
- BorrowedPtr ( borrow_kind, _) => {
297
+ BorrowedPtr ( borrow_kind, _) | Implicit ( borrow_kind , _ ) => {
297
298
MutabilityCategory :: from_borrow_kind ( borrow_kind)
298
299
}
299
300
GcPtr => {
@@ -422,7 +423,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
422
423
-> McResult < cmt > {
423
424
let mut cmt = if_ok ! ( self . cat_expr_unadjusted( expr) ) ;
424
425
for deref in range ( 1 u, autoderefs + 1 ) {
425
- cmt = self . cat_deref ( expr, cmt, deref) ;
426
+ cmt = self . cat_deref ( expr, cmt, deref, false ) ;
426
427
}
427
428
return Ok ( cmt) ;
428
429
}
@@ -434,7 +435,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
434
435
match expr. node {
435
436
ast:: ExprUnary ( ast:: UnDeref , ref e_base) => {
436
437
let base_cmt = if_ok ! ( self . cat_expr( & * * e_base) ) ;
437
- Ok ( self . cat_deref ( expr, base_cmt, 0 ) )
438
+ Ok ( self . cat_deref ( expr, base_cmt, 0 , false ) )
438
439
}
439
440
440
441
ast:: ExprField ( ref base, f_name, _) => {
@@ -443,8 +444,22 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
443
444
}
444
445
445
446
ast:: ExprIndex ( ref base, _) => {
446
- let base_cmt = if_ok ! ( self . cat_expr( & * * base) ) ;
447
- Ok ( self . cat_index ( expr, base_cmt, 0 ) )
447
+ let method_call = typeck:: MethodCall :: expr ( expr. id ( ) ) ;
448
+ match self . typer . node_method_ty ( method_call) {
449
+ Some ( method_ty) => {
450
+ // If this is an index implemented by a method call, then it will
451
+ // include an implicit deref of the result.
452
+ let ret_ty = ty:: ty_fn_ret ( method_ty) ;
453
+ Ok ( self . cat_deref ( expr,
454
+ self . cat_rvalue_node ( expr. id ( ) ,
455
+ expr. span ( ) ,
456
+ ret_ty) , 1 , true ) )
457
+ }
458
+ None => {
459
+ let base_cmt = if_ok ! ( self . cat_expr( & * * base) ) ;
460
+ Ok ( self . cat_index ( expr, base_cmt, 0 ) )
461
+ }
462
+ }
448
463
}
449
464
450
465
ast:: ExprPath ( _) => {
@@ -687,13 +702,14 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
687
702
}
688
703
689
704
pub fn cat_deref_obj < N : ast_node > ( & self , node : & N , base_cmt : cmt ) -> cmt {
690
- self . cat_deref_common ( node, base_cmt, 0 , ty:: mk_nil ( ) )
705
+ self . cat_deref_common ( node, base_cmt, 0 , ty:: mk_nil ( ) , false )
691
706
}
692
707
693
708
fn cat_deref < N : ast_node > ( & self ,
694
709
node : & N ,
695
710
base_cmt : cmt ,
696
- deref_cnt : uint )
711
+ deref_cnt : uint ,
712
+ implicit : bool )
697
713
-> cmt {
698
714
let adjustment = match self . typer . adjustments ( ) . borrow ( ) . find ( & node. id ( ) ) {
699
715
Some ( & ty:: AutoObject ( ..) ) => typeck:: AutoObject ,
@@ -717,7 +733,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
717
733
None => base_cmt
718
734
} ;
719
735
match ty:: deref ( base_cmt. ty , true ) {
720
- Some ( mt) => self . cat_deref_common ( node, base_cmt, deref_cnt, mt. ty ) ,
736
+ Some ( mt) => self . cat_deref_common ( node, base_cmt, deref_cnt, mt. ty , implicit ) ,
721
737
None => {
722
738
self . tcx ( ) . sess . span_bug (
723
739
node. span ( ) ,
@@ -731,10 +747,20 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
731
747
node : & N ,
732
748
base_cmt : cmt ,
733
749
deref_cnt : uint ,
734
- deref_ty : ty:: t )
750
+ deref_ty : ty:: t ,
751
+ implicit : bool )
735
752
-> cmt {
736
753
let ( m, cat) = match deref_kind ( self . tcx ( ) , base_cmt. ty ) {
737
754
deref_ptr( ptr) => {
755
+ let ptr = if implicit {
756
+ match ptr {
757
+ BorrowedPtr ( bk, r) => Implicit ( bk, r) ,
758
+ _ => self . tcx ( ) . sess . span_bug ( node. span ( ) ,
759
+ "Implicit deref of non-borrowed pointer" )
760
+ }
761
+ } else {
762
+ ptr
763
+ } ;
738
764
// for unique ptrs, we inherit mutability from the
739
765
// owning reference.
740
766
( MutabilityCategory :: from_pointer_kind ( base_cmt. mutbl , ptr) ,
@@ -1073,7 +1099,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
1073
1099
1074
1100
ast:: PatBox ( ref subpat) | ast:: PatRegion ( ref subpat) => {
1075
1101
// @p1, ~p1
1076
- let subcmt = self . cat_deref ( pat, cmt, 0 ) ;
1102
+ let subcmt = self . cat_deref ( pat, cmt, 0 , false ) ;
1077
1103
if_ok ! ( self . cat_pattern( subcmt, & * * subpat, op) ) ;
1078
1104
}
1079
1105
@@ -1129,6 +1155,9 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
1129
1155
}
1130
1156
_ => {
1131
1157
match pk {
1158
+ Implicit ( ..) => {
1159
+ "dereference (dereference is implicit, due to indexing)" . to_string ( )
1160
+ }
1132
1161
OwnedPtr | GcPtr => format ! ( "dereference of `{}`" , ptr_sigil( pk) ) ,
1133
1162
_ => format ! ( "dereference of `{}`-pointer" , ptr_sigil( pk) )
1134
1163
}
@@ -1188,6 +1217,7 @@ impl cmt_ {
1188
1217
cat_deref( _, _, UnsafePtr ( ..) ) |
1189
1218
cat_deref( _, _, GcPtr ( ..) ) |
1190
1219
cat_deref( _, _, BorrowedPtr ( ..) ) |
1220
+ cat_deref( _, _, Implicit ( ..) ) |
1191
1221
cat_upvar( ..) => {
1192
1222
Rc :: new ( ( * self ) . clone ( ) )
1193
1223
}
@@ -1212,7 +1242,9 @@ impl cmt_ {
1212
1242
1213
1243
match self . cat {
1214
1244
cat_deref( ref b, _, BorrowedPtr ( ty:: MutBorrow , _) ) |
1245
+ cat_deref( ref b, _, Implicit ( ty:: MutBorrow , _) ) |
1215
1246
cat_deref( ref b, _, BorrowedPtr ( ty:: UniqueImmBorrow , _) ) |
1247
+ cat_deref( ref b, _, Implicit ( ty:: UniqueImmBorrow , _) ) |
1216
1248
cat_downcast( ref b) |
1217
1249
cat_deref( ref b, _, OwnedPtr ) |
1218
1250
cat_interior( ref b, _) |
@@ -1252,7 +1284,8 @@ impl cmt_ {
1252
1284
Some ( AliasableManaged )
1253
1285
}
1254
1286
1255
- cat_deref( _, _, BorrowedPtr ( ty:: ImmBorrow , _) ) => {
1287
+ cat_deref( _, _, BorrowedPtr ( ty:: ImmBorrow , _) ) |
1288
+ cat_deref( _, _, Implicit ( ty:: ImmBorrow , _) ) => {
1256
1289
Some ( AliasableBorrowed )
1257
1290
}
1258
1291
}
@@ -1300,9 +1333,12 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
1300
1333
match ptr {
1301
1334
OwnedPtr => "Box" ,
1302
1335
GcPtr => "Gc" ,
1303
- BorrowedPtr ( ty:: ImmBorrow , _) => "&" ,
1304
- BorrowedPtr ( ty:: MutBorrow , _) => "&mut" ,
1305
- BorrowedPtr ( ty:: UniqueImmBorrow , _) => "&unique" ,
1336
+ BorrowedPtr ( ty:: ImmBorrow , _) |
1337
+ Implicit ( ty:: ImmBorrow , _) => "&" ,
1338
+ BorrowedPtr ( ty:: MutBorrow , _) |
1339
+ Implicit ( ty:: MutBorrow , _) => "&mut" ,
1340
+ BorrowedPtr ( ty:: UniqueImmBorrow , _) |
1341
+ Implicit ( ty:: UniqueImmBorrow , _) => "&unique" ,
1306
1342
UnsafePtr ( _) => "*"
1307
1343
}
1308
1344
}
0 commit comments