@@ -106,7 +106,8 @@ pub enum PointerKind {
106106 OwnedPtr ,
107107 GcPtr ,
108108 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 )
110111}
111112
112113// We use the term "interior" to mean "something reachable from the
@@ -293,7 +294,7 @@ impl MutabilityCategory {
293294 OwnedPtr => {
294295 base_mutbl. inherit ( )
295296 }
296- BorrowedPtr ( borrow_kind, _) => {
297+ BorrowedPtr ( borrow_kind, _) | Implicit ( borrow_kind , _ ) => {
297298 MutabilityCategory :: from_borrow_kind ( borrow_kind)
298299 }
299300 GcPtr => {
@@ -422,7 +423,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
422423 -> McResult < cmt > {
423424 let mut cmt = if_ok ! ( self . cat_expr_unadjusted( expr) ) ;
424425 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 ) ;
426427 }
427428 return Ok ( cmt) ;
428429 }
@@ -434,7 +435,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
434435 match expr. node {
435436 ast:: ExprUnary ( ast:: UnDeref , ref e_base) => {
436437 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 ) )
438439 }
439440
440441 ast:: ExprField ( ref base, f_name, _) => {
@@ -443,8 +444,22 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
443444 }
444445
445446 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+ }
448463 }
449464
450465 ast:: ExprPath ( _) => {
@@ -687,13 +702,14 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
687702 }
688703
689704 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 )
691706 }
692707
693708 fn cat_deref < N : ast_node > ( & self ,
694709 node : & N ,
695710 base_cmt : cmt ,
696- deref_cnt : uint )
711+ deref_cnt : uint ,
712+ implicit : bool )
697713 -> cmt {
698714 let adjustment = match self . typer . adjustments ( ) . borrow ( ) . find ( & node. id ( ) ) {
699715 Some ( & ty:: AutoObject ( ..) ) => typeck:: AutoObject ,
@@ -717,7 +733,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
717733 None => base_cmt
718734 } ;
719735 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 ) ,
721737 None => {
722738 self . tcx ( ) . sess . span_bug (
723739 node. span ( ) ,
@@ -731,10 +747,20 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
731747 node : & N ,
732748 base_cmt : cmt ,
733749 deref_cnt : uint ,
734- deref_ty : ty:: t )
750+ deref_ty : ty:: t ,
751+ implicit : bool )
735752 -> cmt {
736753 let ( m, cat) = match deref_kind ( self . tcx ( ) , base_cmt. ty ) {
737754 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+ } ;
738764 // for unique ptrs, we inherit mutability from the
739765 // owning reference.
740766 ( MutabilityCategory :: from_pointer_kind ( base_cmt. mutbl , ptr) ,
@@ -1073,7 +1099,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
10731099
10741100 ast:: PatBox ( ref subpat) | ast:: PatRegion ( ref subpat) => {
10751101 // @p1, ~p1
1076- let subcmt = self . cat_deref ( pat, cmt, 0 ) ;
1102+ let subcmt = self . cat_deref ( pat, cmt, 0 , false ) ;
10771103 if_ok ! ( self . cat_pattern( subcmt, & * * subpat, op) ) ;
10781104 }
10791105
@@ -1129,6 +1155,9 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
11291155 }
11301156 _ => {
11311157 match pk {
1158+ Implicit ( ..) => {
1159+ "dereference (dereference is implicit, due to indexing)" . to_string ( )
1160+ }
11321161 OwnedPtr | GcPtr => format ! ( "dereference of `{}`" , ptr_sigil( pk) ) ,
11331162 _ => format ! ( "dereference of `{}`-pointer" , ptr_sigil( pk) )
11341163 }
@@ -1188,6 +1217,7 @@ impl cmt_ {
11881217 cat_deref( _, _, UnsafePtr ( ..) ) |
11891218 cat_deref( _, _, GcPtr ( ..) ) |
11901219 cat_deref( _, _, BorrowedPtr ( ..) ) |
1220+ cat_deref( _, _, Implicit ( ..) ) |
11911221 cat_upvar( ..) => {
11921222 Rc :: new ( ( * self ) . clone ( ) )
11931223 }
@@ -1212,7 +1242,9 @@ impl cmt_ {
12121242
12131243 match self . cat {
12141244 cat_deref( ref b, _, BorrowedPtr ( ty:: MutBorrow , _) ) |
1245+ cat_deref( ref b, _, Implicit ( ty:: MutBorrow , _) ) |
12151246 cat_deref( ref b, _, BorrowedPtr ( ty:: UniqueImmBorrow , _) ) |
1247+ cat_deref( ref b, _, Implicit ( ty:: UniqueImmBorrow , _) ) |
12161248 cat_downcast( ref b) |
12171249 cat_deref( ref b, _, OwnedPtr ) |
12181250 cat_interior( ref b, _) |
@@ -1252,7 +1284,8 @@ impl cmt_ {
12521284 Some ( AliasableManaged )
12531285 }
12541286
1255- cat_deref( _, _, BorrowedPtr ( ty:: ImmBorrow , _) ) => {
1287+ cat_deref( _, _, BorrowedPtr ( ty:: ImmBorrow , _) ) |
1288+ cat_deref( _, _, Implicit ( ty:: ImmBorrow , _) ) => {
12561289 Some ( AliasableBorrowed )
12571290 }
12581291 }
@@ -1300,9 +1333,12 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
13001333 match ptr {
13011334 OwnedPtr => "Box" ,
13021335 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" ,
13061342 UnsafePtr ( _) => "*"
13071343 }
13081344}
0 commit comments