@@ -75,7 +75,7 @@ use middle::def;
75
75
use middle:: region;
76
76
use middle:: ty:: { self , Ty } ;
77
77
use util:: nodemap:: { NodeMap } ;
78
- use util:: ppaux:: { Repr } ;
78
+ use util:: ppaux:: { Repr , UserString } ;
79
79
80
80
use syntax:: ast:: { MutImmutable , MutMutable } ;
81
81
use syntax:: ast;
@@ -113,10 +113,17 @@ pub struct Upvar {
113
113
// different kinds of pointers:
114
114
#[ derive( Clone , Copy , PartialEq , Eq , Hash , Show ) ]
115
115
pub enum PointerKind {
116
+ /// `Box<T>`
116
117
Unique ,
118
+
119
+ /// `&T`
117
120
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 ) ,
120
127
}
121
128
122
129
// We use the term "interior" to mean "something reachable from the
@@ -453,7 +460,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
453
460
autoderefs,
454
461
cmt. repr( self . tcx( ) ) ) ;
455
462
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) ) ;
457
464
}
458
465
return Ok ( cmt) ;
459
466
}
@@ -465,7 +472,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
465
472
match expr. node {
466
473
ast:: ExprUnary ( ast:: UnDeref , ref e_base) => {
467
474
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 )
469
476
}
470
477
471
478
ast:: ExprField ( ref base, f_name) => {
@@ -489,10 +496,23 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
489
496
// If this is an index implemented by a method call, then it
490
497
// will include an implicit deref of the result.
491
498
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 )
496
516
}
497
517
None => {
498
518
self . cat_index ( expr, try!( self . cat_expr ( & * * base) ) )
@@ -837,8 +857,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
837
857
fn cat_deref < N : ast_node > ( & self ,
838
858
node : & N ,
839
859
base_cmt : cmt < ' tcx > ,
840
- deref_cnt : uint ,
841
- implicit : bool )
860
+ deref_cnt : uint )
842
861
-> McResult < cmt < ' tcx > > {
843
862
let adjustment = match self . typer . adjustments ( ) . borrow ( ) . get ( & node. id ( ) ) {
844
863
Some ( adj) if ty:: adjust_is_object ( adj) => ty:: AutoObject ,
@@ -866,7 +885,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
866
885
} ;
867
886
let base_cmt_ty = base_cmt. ty ;
868
887
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 ) ,
870
890
None => {
871
891
debug ! ( "Explicit deref of non-derefable type: {}" ,
872
892
base_cmt_ty. repr( self . tcx( ) ) ) ;
@@ -1236,7 +1256,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
1236
1256
// box p1, &p1, &mut p1. we can ignore the mutability of
1237
1257
// PatRegion since that information is already contained
1238
1258
// in the type.
1239
- let subcmt = try!( self . cat_deref ( pat, cmt, 0 , false ) ) ;
1259
+ let subcmt = try!( self . cat_deref ( pat, cmt, 0 ) ) ;
1240
1260
try!( self . cat_pattern_ ( subcmt, & * * subpat, op) ) ;
1241
1261
}
1242
1262
@@ -1392,22 +1412,6 @@ impl<'tcx> cmt_<'tcx> {
1392
1412
1393
1413
1394
1414
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
-
1411
1415
match self . cat {
1412
1416
cat_static_item => {
1413
1417
"static item" . to_string ( )
@@ -1427,16 +1431,23 @@ impl<'tcx> cmt_<'tcx> {
1427
1431
let upvar = self . upvar ( ) ;
1428
1432
match upvar. as_ref ( ) . map ( |i| & i. cat ) {
1429
1433
Some ( & cat_upvar( ref var) ) => {
1430
- upvar_to_string ( var, false )
1434
+ var. user_string ( tcx )
1431
1435
}
1432
1436
Some ( _) => unreachable ! ( ) ,
1433
1437
None => {
1434
1438
match pk {
1435
1439
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" )
1437
1450
}
1438
- Unique => format ! ( "dereference of `{}`" , ptr_sigil( pk) ) ,
1439
- _ => format ! ( "dereference of `{}`-pointer" , ptr_sigil( pk) )
1440
1451
}
1441
1452
}
1442
1453
}
@@ -1447,14 +1458,12 @@ impl<'tcx> cmt_<'tcx> {
1447
1458
cat_interior( _, InteriorField ( PositionalField ( _) ) ) => {
1448
1459
"anonymous field" . to_string ( )
1449
1460
}
1450
- cat_interior( _, InteriorElement ( VecElement ) ) => {
1451
- "vec content" . to_string ( )
1452
- }
1461
+ cat_interior( _, InteriorElement ( VecElement ) ) |
1453
1462
cat_interior( _, InteriorElement ( OtherElement ) ) => {
1454
1463
"indexed content" . to_string ( )
1455
1464
}
1456
1465
cat_upvar( ref var) => {
1457
- upvar_to_string ( var, true )
1466
+ var. user_string ( tcx )
1458
1467
}
1459
1468
cat_downcast( ref cmt, _) => {
1460
1469
cmt. descriptive_string ( tcx)
@@ -1483,7 +1492,7 @@ impl<'tcx> Repr<'tcx> for categorization<'tcx> {
1483
1492
format ! ( "{:?}" , * self )
1484
1493
}
1485
1494
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)
1487
1496
}
1488
1497
cat_interior( ref cmt, interior) => {
1489
1498
format ! ( "{}.{}" , cmt. cat. repr( tcx) , interior. repr( tcx) )
@@ -1504,7 +1513,32 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
1504
1513
Implicit ( ty:: MutBorrow , _) => "&mut" ,
1505
1514
BorrowedPtr ( ty:: UniqueImmBorrow , _) |
1506
1515
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
+ }
1508
1542
}
1509
1543
}
1510
1544
@@ -1531,3 +1565,27 @@ fn element_kind(t: Ty) -> ElementKind {
1531
1565
_ => OtherElement
1532
1566
}
1533
1567
}
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