@@ -2263,17 +2263,36 @@ pub enum LvaluePreference {
2263
2263
/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2264
2264
/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2265
2265
///
2266
+ <<<<<<< HEAD
2266
2267
/// Note: this method does not modify the adjustments table. The caller is responsible for
2267
2268
/// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2268
2269
pub fn autoderef< ' a , ' tcx , T , F > ( fcx : & FnCtxt < ' a , ' tcx > ,
2269
2270
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
2270
2284
base_ty : Ty < ' tcx > ,
2271
- expr_id : Option < ast:: NodeId > ,
2285
+ opt_expr : Option < & ast:: Expr > ,
2272
2286
mut lvalue_pref : LvaluePreference ,
2273
2287
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 > ,
2276
2290
{
2291
+ debug ! ( "autoderef(base_ty={}, opt_expr={}, lvalue_pref={})" ,
2292
+ base_ty. repr( fcx. tcx( ) ) ,
2293
+ opt_expr,
2294
+ lvalue_pref) ;
2295
+
2277
2296
let mut t = base_ty;
2278
2297
for autoderefs in range( 0 , fcx. tcx( ) . sess. recursion_limit. get( ) ) {
2279
2298
let resolved_t = structurally_resolved_type( fcx, sp, t) ;
@@ -2291,7 +2310,19 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2291
2310
let mt = match ty:: deref( resolved_t, false ) {
2292
2311
Some ( mt) => Some ( mt) ,
2293
2312
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.
2295
2326
try_overloaded_deref( fcx, sp, method_call, None , resolved_t, lvalue_pref)
2296
2327
}
2297
2328
} ;
@@ -2324,7 +2355,7 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2324
2355
// Try DerefMut first, if preferred.
2325
2356
let method = match ( lvalue_pref, fcx. tcx( ) . lang_items. deref_mut_trait( ) ) {
2326
2357
( 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,
2328
2359
token:: intern( "deref_mut") , trait_did,
2329
2360
base_ty, None )
2330
2361
}
@@ -2334,7 +2365,7 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2334
2365
// Otherwise, fall back to Deref.
2335
2366
let method = match ( method, fcx. tcx ( ) . lang_items . deref_trait ( ) ) {
2336
2367
( 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,
2338
2369
token:: intern ( "deref" ) , trait_did,
2339
2370
base_ty, None )
2340
2371
}
@@ -2390,7 +2421,7 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2390
2421
// consolidated.
2391
2422
2392
2423
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| {
2394
2425
let autoderefref = ty:: AutoDerefRef { autoderefs : idx, autoref : None } ;
2395
2426
step ( adj_ty, autoderefref)
2396
2427
} ) ;
@@ -3360,7 +3391,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3360
3391
fcx. expr_ty ( base) ) ;
3361
3392
// FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3362
3393
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, _| {
3364
3395
match base_t. sty {
3365
3396
ty:: ty_struct( base_id, substs) => {
3366
3397
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>,
3421
3452
let mut tuple_like = false ;
3422
3453
// FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3423
3454
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, _| {
3425
3456
match base_t. sty {
3426
3457
ty:: ty_struct( base_id, substs) => {
3427
3458
tuple_like = ty:: is_tuple_struct ( tcx, base_id) ;
0 commit comments