@@ -86,10 +86,11 @@ use middle::traits;
8686use middle:: ty:: * ;
8787use middle:: ty;
8888use middle:: typeck:: astconv:: AstConv ;
89- use middle:: typeck:: check:: { FnCtxt , PreferMutLvalue , impl_self_ty} ;
89+ use middle:: typeck:: check:: { FnCtxt , NoPreference , PreferMutLvalue } ;
90+ use middle:: typeck:: check:: { impl_self_ty} ;
9091use middle:: typeck:: check;
9192use middle:: typeck:: infer;
92- use middle:: typeck:: MethodCallee ;
93+ use middle:: typeck:: { MethodCall , MethodCallee } ;
9394use middle:: typeck:: { MethodOrigin , MethodParam , MethodTypeParam } ;
9495use middle:: typeck:: { MethodStatic , MethodStaticUnboxedClosure , MethodObject , MethodTraitObject } ;
9596use middle:: typeck:: check:: regionmanip:: replace_late_bound_regions_in_fn_sig;
@@ -353,11 +354,15 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
353354
354355 let ( _, _, result) =
355356 check:: autoderef (
356- self . fcx , span, self_ty, self_expr_id, PreferMutLvalue ,
357+ self . fcx , span, self_ty, self_expr_id, NoPreference ,
357358 |self_ty, autoderefs| self . search_step ( self_ty, autoderefs) ) ;
358359
359360 match result {
360- Some ( Some ( result) ) => Some ( result) ,
361+ Some ( Some ( result) ) => {
362+ self . fixup_derefs_on_method_receiver_if_necessary ( & result,
363+ self_ty) ;
364+ Some ( result)
365+ }
361366 _ => None
362367 }
363368 }
@@ -430,7 +435,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
430435 */
431436
432437 let span = self . self_expr . map_or ( self . span , |e| e. span ) ;
433- check:: autoderef ( self . fcx , span, self_ty, None , PreferMutLvalue , |self_ty, _| {
438+ check:: autoderef ( self . fcx , span, self_ty, None , NoPreference , |self_ty, _| {
434439 match get ( self_ty) . sty {
435440 ty_trait( box TyTrait { def_id, ref substs, bounds, .. } ) => {
436441 self . push_inherent_candidates_from_object (
@@ -458,7 +463,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
458463
459464 fn push_bound_candidates ( & mut self , self_ty : ty:: t , restrict_to : Option < DefId > ) {
460465 let span = self . self_expr . map_or ( self . span , |e| e. span ) ;
461- check:: autoderef ( self . fcx , span, self_ty, None , PreferMutLvalue , |self_ty, _| {
466+ check:: autoderef ( self . fcx , span, self_ty, None , NoPreference , |self_ty, _| {
462467 match get ( self_ty) . sty {
463468 ty_param( p) => {
464469 self . push_inherent_candidates_from_param ( self_ty, restrict_to, p) ;
@@ -1135,7 +1140,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
11351140 } ;
11361141
11371142 // This is hokey. We should have mutability inference as a
1138- // variable. But for now, try &const, then & , then &mut:
1143+ // variable. But for now, try &, then &mut:
11391144 let region =
11401145 self . infcx ( ) . next_region_var ( infer:: Autoref ( self . span ) ) ;
11411146 for mutbl in mutbls. iter ( ) {
@@ -1381,6 +1386,77 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
13811386 }
13821387 }
13831388
1389+ fn fixup_derefs_on_method_receiver_if_necessary (
1390+ & self ,
1391+ method_callee : & MethodCallee ,
1392+ self_ty : ty:: t ) {
1393+ let sig = match ty:: get ( method_callee. ty ) . sty {
1394+ ty:: ty_bare_fn( ref f) => f. sig . clone ( ) ,
1395+ ty:: ty_closure( ref f) => f. sig . clone ( ) ,
1396+ _ => return ,
1397+ } ;
1398+
1399+ match ty:: get ( * sig. inputs . get ( 0 ) ) . sty {
1400+ ty:: ty_rptr( _, ty:: mt {
1401+ ty : _,
1402+ mutbl : ast:: MutMutable ,
1403+ } ) => { }
1404+ _ => return ,
1405+ }
1406+
1407+ // Fix up autoderefs and derefs.
1408+ let mut self_expr = match self . self_expr {
1409+ Some ( expr) => expr,
1410+ None => return ,
1411+ } ;
1412+ loop {
1413+ // Count autoderefs.
1414+ let autoderef_count = match self . fcx
1415+ . inh
1416+ . adjustments
1417+ . borrow ( )
1418+ . find ( & self_expr. id ) {
1419+ Some ( & ty:: AdjustDerefRef ( ty:: AutoDerefRef {
1420+ autoderefs : autoderef_count,
1421+ autoref : _
1422+ } ) ) if autoderef_count > 0 => autoderef_count,
1423+ Some ( _) | None => return ,
1424+ } ;
1425+
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
1454+ }
1455+ _ => break ,
1456+ }
1457+ }
1458+ }
1459+
13841460 fn enforce_object_limitations ( & self , candidate : & Candidate ) {
13851461 /*!
13861462 * There are some limitations to calling functions through an
0 commit comments