@@ -2263,17 +2263,36 @@ pub enum LvaluePreference {
22632263/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
22642264/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
22652265///
2266+ <<<<<<< HEAD
22662267/// Note: this method does not modify the adjustments table. The caller is responsible for
22672268/// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
22682269 pub fn autoderef< ' a , ' tcx , T , F > ( fcx : & FnCtxt < ' a , ' tcx > ,
22692270 sp : Span ,
2271+ ||||||| merged common ancestors
2272+ /// Note: this method does not modify the adjustments table. The caller is responsible for
2273+ /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2274+ pub fn autoderef < ' a , ' tcx , T , F > ( fcx: & FnCtxt < ' a , ' tcx > , sp : Span ,
2275+ =======
2276+ /// Note: this method does not modify the adjustments table. The
2277+ /// caller is responsible for inserting an AutoAdjustment record into
2278+ /// the `fcx` using one of the suitable methods. However, if
2279+ /// `opt_expr` is not `None`, it *will* insert the appropriate method
2280+ /// entries for the overloaded deref call.
2281+ pub fn autoderef < ' a , ' tcx , T , F > ( fcx : & FnCtxt < ' a , ' tcx > ,
2282+ sp : Span ,
2283+ >>>>>>> Add comments to autoderef ( ) helper and refactor it to take
22702284 base_ty : Ty < ' tcx > ,
2271- expr_id : Option < ast:: NodeId > ,
2285+ opt_expr : Option < & ast:: Expr > ,
22722286 mut lvalue_pref : LvaluePreference ,
22732287 mut should_stop : F )
2274- -> ( Ty < ' tcx > , uint , Option < T > ) where
2275- F : FnMut ( Ty < ' tcx > , uint ) -> Option < T > ,
2288+ -> ( Ty < ' tcx > , uint , Option < T > )
2289+ where F : FnMut ( Ty < ' tcx > , uint ) -> Option < T > ,
22762290{
2291+ debug ! ( "autoderef(base_ty={}, opt_expr={}, lvalue_pref={})" ,
2292+ base_ty. repr( fcx. tcx( ) ) ,
2293+ opt_expr,
2294+ lvalue_pref) ;
2295+
22772296 let mut t = base_ty;
22782297 for autoderefs in range( 0 , fcx. tcx( ) . sess. recursion_limit. get( ) ) {
22792298 let resolved_t = structurally_resolved_type( fcx, sp, t) ;
@@ -2291,7 +2310,19 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
22912310 let mt = match ty:: deref( resolved_t, false ) {
22922311 Some ( mt) => Some ( mt) ,
22932312 None => {
2294- let method_call = expr_id. map ( |id| MethodCall :: autoderef ( id, autoderefs) ) ;
2313+ let method_call = opt_expr. map( |expr| MethodCall :: autoderef( expr. id, autoderefs) ) ;
2314+
2315+ // Super subtle: it might seem as though we should
2316+ // pass `opt_expr` to `try_overloaded_deref`, so that
2317+ // the (implicit) autoref of using an overloaded deref
2318+ // would get added to the adjustment table. However we
2319+ // do not do that, because it's kind of a
2320+ // "meta-adjustment" -- instead, we just leave it
2321+ // unrecorded and know that there "will be" an
2322+ // autoref. regionck and other bits of the code base,
2323+ // when they encounter an overloaded autoderef, have
2324+ // to do some reconstructive surgery. This is a pretty
2325+ // complex mess that is begging for a proper MIR.
22952326 try_overloaded_deref( fcx, sp, method_call, None , resolved_t, lvalue_pref)
22962327 }
22972328 } ;
@@ -2324,7 +2355,7 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
23242355 // Try DerefMut first, if preferred.
23252356 let method = match ( lvalue_pref, fcx. tcx( ) . lang_items. deref_mut_trait( ) ) {
23262357 ( PreferMutLvalue , Some ( trait_did) ) => {
2327- method:: lookup_in_trait ( fcx, span, base_expr. map ( |x| & * x ) ,
2358+ method:: lookup_in_trait( fcx, span, base_expr,
23282359 token:: intern( "deref_mut") , trait_did,
23292360 base_ty, None )
23302361 }
@@ -2334,7 +2365,7 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
23342365 // Otherwise, fall back to Deref.
23352366 let method = match ( method, fcx. tcx ( ) . lang_items . deref_trait ( ) ) {
23362367 ( None , Some ( trait_did) ) => {
2337- method:: lookup_in_trait ( fcx, span, base_expr. map ( |x| & * x ) ,
2368+ method:: lookup_in_trait ( fcx, span, base_expr,
23382369 token:: intern ( "deref" ) , trait_did,
23392370 base_ty, None )
23402371 }
@@ -2390,7 +2421,7 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
23902421 // consolidated.
23912422
23922423 let ( ty, autoderefs, final_mt) =
2393- autoderef ( fcx, base_expr. span , base_ty, Some ( base_expr. id ) , lvalue_pref, |adj_ty, idx| {
2424+ autoderef ( fcx, base_expr. span , base_ty, Some ( base_expr) , lvalue_pref, |adj_ty, idx| {
23942425 let autoderefref = ty:: AutoDerefRef { autoderefs : idx, autoref : None } ;
23952426 step ( adj_ty, autoderefref)
23962427 } ) ;
@@ -3360,7 +3391,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
33603391 fcx. expr_ty ( base) ) ;
33613392 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
33623393 let ( _, autoderefs, field_ty) =
3363- autoderef ( fcx, expr. span , expr_t, Some ( base. id ) , lvalue_pref, |base_t, _| {
3394+ autoderef ( fcx, expr. span , expr_t, Some ( base) , lvalue_pref, |base_t, _| {
33643395 match base_t. sty {
33653396 ty:: ty_struct( base_id, substs) => {
33663397 debug ! ( "struct named {}" , ppaux:: ty_to_string( tcx, base_t) ) ;
@@ -3421,7 +3452,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
34213452 let mut tuple_like = false ;
34223453 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
34233454 let ( _, autoderefs, field_ty) =
3424- autoderef ( fcx, expr. span , expr_t, Some ( base. id ) , lvalue_pref, |base_t, _| {
3455+ autoderef ( fcx, expr. span , expr_t, Some ( base) , lvalue_pref, |base_t, _| {
34253456 match base_t. sty {
34263457 ty:: ty_struct( base_id, substs) => {
34273458 tuple_like = ty:: is_tuple_struct ( tcx, base_id) ;
0 commit comments