@@ -359,8 +359,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
359
359
360
360
match result {
361
361
Some ( Some ( result) ) => {
362
- self . fixup_derefs_on_method_receiver_if_necessary ( & result,
363
- self_ty) ;
362
+ self . fixup_derefs_on_method_receiver_if_necessary ( & result) ;
364
363
Some ( result)
365
364
}
366
365
_ => None
@@ -1388,8 +1387,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
1388
1387
1389
1388
fn fixup_derefs_on_method_receiver_if_necessary (
1390
1389
& self ,
1391
- method_callee : & MethodCallee ,
1392
- self_ty : ty:: t ) {
1390
+ method_callee : & MethodCallee ) {
1393
1391
let sig = match ty:: get ( method_callee. ty ) . sty {
1394
1392
ty:: ty_bare_fn( ref f) => f. sig . clone ( ) ,
1395
1393
ty:: ty_closure( ref f) => f. sig . clone ( ) ,
@@ -1404,55 +1402,82 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
1404
1402
_ => return ,
1405
1403
}
1406
1404
1407
- // Fix up autoderefs and derefs.
1408
- let mut self_expr = match self . self_expr {
1409
- Some ( expr) => expr,
1410
- None => return ,
1411
- } ;
1405
+ // Gather up expressions we want to munge.
1406
+ let mut exprs = Vec :: new ( ) ;
1407
+ match self . self_expr {
1408
+ Some ( expr) => exprs. push ( expr) ,
1409
+ None => { }
1410
+ }
1412
1411
loop {
1412
+ if exprs. len ( ) == 0 {
1413
+ break
1414
+ }
1415
+ let last = exprs[ exprs. len ( ) - 1 ] ;
1416
+ match last. node {
1417
+ ast:: ExprParen ( ref expr) |
1418
+ ast:: ExprField ( ref expr, _, _) |
1419
+ ast:: ExprTupField ( ref expr, _, _) |
1420
+ ast:: ExprSlice ( ref expr, _, _, _) |
1421
+ ast:: ExprIndex ( ref expr, _) |
1422
+ ast:: ExprUnary ( ast:: UnDeref , ref expr) => exprs. push ( & * * expr) ,
1423
+ _ => break ,
1424
+ }
1425
+ }
1426
+
1427
+ // Fix up autoderefs and derefs.
1428
+ for ( i, expr) in exprs. iter ( ) . rev ( ) . enumerate ( ) {
1413
1429
// Count autoderefs.
1414
1430
let autoderef_count = match self . fcx
1415
1431
. inh
1416
1432
. adjustments
1417
1433
. borrow ( )
1418
- . find ( & self_expr . id ) {
1434
+ . find ( & expr . id ) {
1419
1435
Some ( & ty:: AdjustDerefRef ( ty:: AutoDerefRef {
1420
1436
autoderefs : autoderef_count,
1421
1437
autoref : _
1422
- } ) ) if autoderef_count > 0 => autoderef_count,
1423
- Some ( _) | None => return ,
1438
+ } ) ) => autoderef_count,
1439
+ Some ( _) | None => 0 ,
1424
1440
} ;
1425
1441
1426
- check:: autoderef ( self . fcx ,
1427
- self_expr. span ,
1428
- self . fcx . expr_ty ( self_expr) ,
1429
- Some ( self_expr. id ) ,
1430
- PreferMutLvalue ,
1431
- |_, autoderefs| {
1432
- if autoderefs == autoderef_count + 1 {
1433
- Some ( ( ) )
1434
- } else {
1435
- None
1436
- }
1437
- } ) ;
1438
-
1439
- match self_expr. node {
1440
- ast:: ExprParen ( ref expr) |
1441
- ast:: ExprIndex ( ref expr, _) |
1442
- ast:: ExprField ( ref expr, _, _) |
1443
- ast:: ExprTupField ( ref expr, _, _) |
1444
- ast:: ExprSlice ( ref expr, _, _, _) => self_expr = & * * expr,
1445
- ast:: ExprUnary ( ast:: UnDeref , ref expr) => {
1446
- drop ( check:: try_overloaded_deref (
1447
- self . fcx ,
1448
- self_expr. span ,
1449
- Some ( MethodCall :: expr ( self_expr. id ) ) ,
1450
- Some ( self_expr) ,
1451
- self_ty,
1452
- PreferMutLvalue ) ) ;
1453
- self_expr = & * * expr
1442
+ if autoderef_count > 0 {
1443
+ check:: autoderef ( self . fcx ,
1444
+ expr. span ,
1445
+ self . fcx . expr_ty ( * expr) ,
1446
+ Some ( expr. id ) ,
1447
+ PreferMutLvalue ,
1448
+ |_, autoderefs| {
1449
+ if autoderefs == autoderef_count + 1 {
1450
+ Some ( ( ) )
1451
+ } else {
1452
+ None
1453
+ }
1454
+ } ) ;
1455
+ }
1456
+
1457
+ // Don't retry the first one or we might infinite loop!
1458
+ if i != 0 {
1459
+ match expr. node {
1460
+ ast:: ExprIndex ( ref base_expr, ref index_expr) => {
1461
+ check:: try_overloaded_index (
1462
+ self . fcx ,
1463
+ Some ( MethodCall :: expr ( expr. id ) ) ,
1464
+ * expr,
1465
+ & * * base_expr,
1466
+ self . fcx . expr_ty ( & * * base_expr) ,
1467
+ index_expr,
1468
+ PreferMutLvalue ) ;
1469
+ }
1470
+ ast:: ExprUnary ( ast:: UnDeref , ref base_expr) => {
1471
+ check:: try_overloaded_deref (
1472
+ self . fcx ,
1473
+ expr. span ,
1474
+ Some ( MethodCall :: expr ( expr. id ) ) ,
1475
+ Some ( & * * base_expr) ,
1476
+ self . fcx . expr_ty ( & * * base_expr) ,
1477
+ PreferMutLvalue ) ;
1478
+ }
1479
+ _ => { }
1454
1480
}
1455
- _ => break ,
1456
1481
}
1457
1482
}
1458
1483
}
0 commit comments