@@ -75,7 +75,7 @@ use middle::def;
7575use middle:: region;
7676use middle:: ty:: { self , Ty } ;
7777use util:: nodemap:: { NodeMap } ;
78- use util:: ppaux:: { Repr } ;
78+ use util:: ppaux:: { Repr , UserString } ;
7979
8080use syntax:: ast:: { MutImmutable , MutMutable } ;
8181use syntax:: ast;
@@ -113,10 +113,17 @@ pub struct Upvar {
113113// different kinds of pointers:
114114#[ derive( Clone , Copy , PartialEq , Eq , Hash , Show ) ]
115115pub enum PointerKind {
116+ /// `Box<T>`
116117 Unique ,
118+
119+ /// `&T`
117120 BorrowedPtr ( ty:: BorrowKind , ty:: Region ) ,
118- Implicit ( ty:: BorrowKind , ty:: Region ) , // Implicit deref of a borrowed ptr.
119- UnsafePtr ( ast:: Mutability )
121+
122+ /// `*T`
123+ UnsafePtr ( ast:: Mutability ) ,
124+
125+ /// Implicit deref of the `&T` that results from an overloaded index `[]`.
126+ Implicit ( ty:: BorrowKind , ty:: Region ) ,
120127}
121128
122129// We use the term "interior" to mean "something reachable from the
@@ -453,7 +460,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
453460 autoderefs,
454461 cmt. repr( self . tcx( ) ) ) ;
455462 for deref in range ( 1 u, autoderefs + 1 ) {
456- cmt = try!( self . cat_deref ( expr, cmt, deref, false ) ) ;
463+ cmt = try!( self . cat_deref ( expr, cmt, deref) ) ;
457464 }
458465 return Ok ( cmt) ;
459466 }
@@ -465,7 +472,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
465472 match expr. node {
466473 ast:: ExprUnary ( ast:: UnDeref , ref e_base) => {
467474 let base_cmt = try!( self . cat_expr ( & * * e_base) ) ;
468- self . cat_deref ( expr, base_cmt, 0 , false )
475+ self . cat_deref ( expr, base_cmt, 0 )
469476 }
470477
471478 ast:: ExprField ( ref base, f_name) => {
@@ -489,10 +496,23 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
489496 // If this is an index implemented by a method call, then it
490497 // will include an implicit deref of the result.
491498 let ret_ty = self . overloaded_method_return_ty ( method_ty) ;
492- self . cat_deref ( expr,
493- self . cat_rvalue_node ( expr. id ( ) ,
494- expr. span ( ) ,
495- ret_ty) , 1 , true )
499+
500+ // The index method always returns an `&T`, so
501+ // dereference it to find the result type.
502+ let elem_ty = match ret_ty. sty {
503+ ty:: ty_rptr( _, mt) => mt. ty ,
504+ _ => {
505+ debug ! ( "cat_expr_unadjusted: return type of overloaded index is {}?" ,
506+ ret_ty. repr( self . tcx( ) ) ) ;
507+ return Err ( ( ) ) ;
508+ }
509+ } ;
510+
511+ // The call to index() returns a `&T` value, which
512+ // is an rvalue. That is what we will be
513+ // dereferencing.
514+ let base_cmt = self . cat_rvalue_node ( expr. id ( ) , expr. span ( ) , ret_ty) ;
515+ self . cat_deref_common ( expr, base_cmt, 1 , elem_ty, true )
496516 }
497517 None => {
498518 self . cat_index ( expr, try!( self . cat_expr ( & * * base) ) )
@@ -837,8 +857,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
837857 fn cat_deref < N : ast_node > ( & self ,
838858 node : & N ,
839859 base_cmt : cmt < ' tcx > ,
840- deref_cnt : uint ,
841- implicit : bool )
860+ deref_cnt : uint )
842861 -> McResult < cmt < ' tcx > > {
843862 let adjustment = match self . typer . adjustments ( ) . borrow ( ) . get ( & node. id ( ) ) {
844863 Some ( adj) if ty:: adjust_is_object ( adj) => ty:: AutoObject ,
@@ -866,7 +885,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
866885 } ;
867886 let base_cmt_ty = base_cmt. ty ;
868887 match ty:: deref ( base_cmt_ty, true ) {
869- Some ( mt) => self . cat_deref_common ( node, base_cmt, deref_cnt, mt. ty , implicit) ,
888+ Some ( mt) => self . cat_deref_common ( node, base_cmt, deref_cnt, mt. ty ,
889+ /* implicit: */ false ) ,
870890 None => {
871891 debug ! ( "Explicit deref of non-derefable type: {}" ,
872892 base_cmt_ty. repr( self . tcx( ) ) ) ;
@@ -1236,7 +1256,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
12361256 // box p1, &p1, &mut p1. we can ignore the mutability of
12371257 // PatRegion since that information is already contained
12381258 // in the type.
1239- let subcmt = try!( self . cat_deref ( pat, cmt, 0 , false ) ) ;
1259+ let subcmt = try!( self . cat_deref ( pat, cmt, 0 ) ) ;
12401260 try!( self . cat_pattern_ ( subcmt, & * * subpat, op) ) ;
12411261 }
12421262
@@ -1392,22 +1412,6 @@ impl<'tcx> cmt_<'tcx> {
13921412
13931413
13941414 pub fn descriptive_string ( & self , tcx : & ty:: ctxt ) -> String {
1395- fn upvar_to_string ( upvar : & Upvar , is_copy : bool ) -> String {
1396- if upvar. is_unboxed {
1397- let kind = match upvar. kind {
1398- ty:: FnUnboxedClosureKind => "Fn" ,
1399- ty:: FnMutUnboxedClosureKind => "FnMut" ,
1400- ty:: FnOnceUnboxedClosureKind => "FnOnce"
1401- } ;
1402- format ! ( "captured outer variable in an `{}` closure" , kind)
1403- } else {
1404- ( match ( upvar. kind , is_copy) {
1405- ( ty:: FnOnceUnboxedClosureKind , true ) => "captured outer variable in a proc" ,
1406- _ => "captured outer variable"
1407- } ) . to_string ( )
1408- }
1409- }
1410-
14111415 match self . cat {
14121416 cat_static_item => {
14131417 "static item" . to_string ( )
@@ -1427,16 +1431,23 @@ impl<'tcx> cmt_<'tcx> {
14271431 let upvar = self . upvar ( ) ;
14281432 match upvar. as_ref ( ) . map ( |i| & i. cat ) {
14291433 Some ( & cat_upvar( ref var) ) => {
1430- upvar_to_string ( var, false )
1434+ var. user_string ( tcx )
14311435 }
14321436 Some ( _) => unreachable ! ( ) ,
14331437 None => {
14341438 match pk {
14351439 Implicit ( ..) => {
1436- "dereference (dereference is implicit, due to indexing)" . to_string ( )
1440+ format ! ( "indexed content" )
1441+ }
1442+ Unique => {
1443+ format ! ( "`Box` content" )
1444+ }
1445+ UnsafePtr ( ..) => {
1446+ format ! ( "dereference of unsafe pointer" )
1447+ }
1448+ BorrowedPtr ( ..) => {
1449+ format ! ( "borrowed content" )
14371450 }
1438- Unique => format ! ( "dereference of `{}`" , ptr_sigil( pk) ) ,
1439- _ => format ! ( "dereference of `{}`-pointer" , ptr_sigil( pk) )
14401451 }
14411452 }
14421453 }
@@ -1447,14 +1458,12 @@ impl<'tcx> cmt_<'tcx> {
14471458 cat_interior( _, InteriorField ( PositionalField ( _) ) ) => {
14481459 "anonymous field" . to_string ( )
14491460 }
1450- cat_interior( _, InteriorElement ( VecElement ) ) => {
1451- "vec content" . to_string ( )
1452- }
1461+ cat_interior( _, InteriorElement ( VecElement ) ) |
14531462 cat_interior( _, InteriorElement ( OtherElement ) ) => {
14541463 "indexed content" . to_string ( )
14551464 }
14561465 cat_upvar( ref var) => {
1457- upvar_to_string ( var, true )
1466+ var. user_string ( tcx )
14581467 }
14591468 cat_downcast( ref cmt, _) => {
14601469 cmt. descriptive_string ( tcx)
@@ -1483,7 +1492,7 @@ impl<'tcx> Repr<'tcx> for categorization<'tcx> {
14831492 format ! ( "{:?}" , * self )
14841493 }
14851494 cat_deref( ref cmt, derefs, ptr) => {
1486- format ! ( "{}-{}{}->" , cmt. cat. repr( tcx) , ptr_sigil ( ptr) , derefs)
1495+ format ! ( "{}-{}{}->" , cmt. cat. repr( tcx) , ptr. repr ( tcx ) , derefs)
14871496 }
14881497 cat_interior( ref cmt, interior) => {
14891498 format ! ( "{}.{}" , cmt. cat. repr( tcx) , interior. repr( tcx) )
@@ -1504,7 +1513,32 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
15041513 Implicit ( ty:: MutBorrow , _) => "&mut" ,
15051514 BorrowedPtr ( ty:: UniqueImmBorrow , _) |
15061515 Implicit ( ty:: UniqueImmBorrow , _) => "&unique" ,
1507- UnsafePtr ( _) => "*"
1516+ UnsafePtr ( _) => "*" ,
1517+ }
1518+ }
1519+
1520+ impl < ' tcx > Repr < ' tcx > for PointerKind {
1521+ fn repr ( & self , tcx : & ty:: ctxt < ' tcx > ) -> String {
1522+ match * self {
1523+ Unique => {
1524+ format ! ( "Box" )
1525+ }
1526+ BorrowedPtr ( ty:: ImmBorrow , ref r) |
1527+ Implicit ( ty:: ImmBorrow , ref r) => {
1528+ format ! ( "&{}" , r. repr( tcx) )
1529+ }
1530+ BorrowedPtr ( ty:: MutBorrow , ref r) |
1531+ Implicit ( ty:: MutBorrow , ref r) => {
1532+ format ! ( "&{} mut" , r. repr( tcx) )
1533+ }
1534+ BorrowedPtr ( ty:: UniqueImmBorrow , ref r) |
1535+ Implicit ( ty:: UniqueImmBorrow , ref r) => {
1536+ format ! ( "&{} uniq" , r. repr( tcx) )
1537+ }
1538+ UnsafePtr ( _) => {
1539+ format ! ( "*" )
1540+ }
1541+ }
15081542 }
15091543}
15101544
@@ -1531,3 +1565,27 @@ fn element_kind(t: Ty) -> ElementKind {
15311565 _ => OtherElement
15321566 }
15331567}
1568+
1569+ impl < ' tcx > Repr < ' tcx > for ty:: UnboxedClosureKind {
1570+ fn repr ( & self , _: & ty:: ctxt ) -> String {
1571+ format ! ( "Upvar({:?})" , self )
1572+ }
1573+ }
1574+
1575+ impl < ' tcx > Repr < ' tcx > for Upvar {
1576+ fn repr ( & self , tcx : & ty:: ctxt ) -> String {
1577+ format ! ( "Upvar({})" , self . kind. repr( tcx) )
1578+ }
1579+ }
1580+
1581+ impl < ' tcx > UserString < ' tcx > for Upvar {
1582+ fn user_string ( & self , _: & ty:: ctxt ) -> String {
1583+ let kind = match self . kind {
1584+ ty:: FnUnboxedClosureKind => "Fn" ,
1585+ ty:: FnMutUnboxedClosureKind => "FnMut" ,
1586+ ty:: FnOnceUnboxedClosureKind => "FnOnce" ,
1587+ } ;
1588+ format ! ( "captured outer variable in an `{}` closure" , kind)
1589+ }
1590+ }
1591+
0 commit comments