@@ -433,22 +433,11 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
433
433
for ( i, & expr) in exprs. iter ( ) . rev ( ) . enumerate ( ) {
434
434
debug ! ( "convert_lvalue_derefs_to_mutable: i={} expr={:?}" , i, expr) ;
435
435
436
- // Fix up the adjustment.
437
- let autoderefs = match self . tables . borrow_mut ( ) . adjustments . get_mut ( & expr. id ) {
438
- Some ( & mut Adjustment {
439
- kind : Adjust :: DerefRef { autoderefs, ref mut autoref, .. } , ref mut target
440
- } ) => {
441
- if let & mut Some ( AutoBorrow :: Ref ( _, ref mut mutbl) ) = autoref {
442
- * mutbl = hir:: Mutability :: MutMutable ;
443
- * target = match target. sty {
444
- ty:: TyRef ( r, ty:: TypeAndMut { ty, .. } ) =>
445
- self . tcx . mk_ref ( r, ty:: TypeAndMut { ty, mutbl : * mutbl } ) ,
446
- _ => span_bug ! ( expr. span, "AutoBorrow::Ref resulted in non-ref {:?}" ,
447
- target)
448
- } ;
449
- }
450
- autoderefs
451
- }
436
+ // Fix up the autoderefs. Autorefs can only occur immediately preceding
437
+ // overloaded lvalue ops, and will be fixed by them in order to get
438
+ // the correct region.
439
+ let autoderefs = match self . tables . borrow ( ) . adjustments . get ( & expr. id ) {
440
+ Some ( & Adjustment { kind : Adjust :: DerefRef { autoderefs, .. } , .. } ) => autoderefs,
452
441
Some ( _) | None => 0
453
442
} ;
454
443
@@ -502,10 +491,35 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
502
491
503
492
let method = self . try_overloaded_lvalue_op (
504
493
expr. span , None , base_ty, arg_tys, PreferMutLvalue , op) ;
505
- let ok = method. expect ( "re-trying op failed" ) ;
494
+ let ok = match method {
495
+ Some ( method) => method,
496
+ None => return self . tcx . sess . delay_span_bug ( expr. span , "re-trying op failed" )
497
+ } ;
506
498
let method = self . register_infer_ok_obligations ( ok) ;
507
499
debug ! ( "convert_lvalue_op_to_mutable: method={:?}" , method) ;
508
500
self . tables . borrow_mut ( ) . method_map . insert ( method_call, method) ;
501
+
502
+ // Convert the autoref in the base expr to mutable with the correct
503
+ // region and mutability.
504
+ if let Some ( & mut Adjustment {
505
+ ref mut target, kind : Adjust :: DerefRef {
506
+ autoref : Some ( AutoBorrow :: Ref ( ref mut r, ref mut mutbl) ) , ..
507
+ }
508
+ } ) = self . tables . borrow_mut ( ) . adjustments . get_mut ( & base_expr. id ) {
509
+ debug ! ( "convert_lvalue_op_to_mutable: converting autoref of {:?}" , target) ;
510
+
511
+ // extract method return type, which will be &mut T;
512
+ // all LB regions should have been instantiated during method lookup
513
+ let method_sig = self . tcx . no_late_bound_regions ( & method. ty . fn_sig ( ) ) . unwrap ( ) ;
514
+
515
+ * target = method_sig. inputs ( ) [ 0 ] ;
516
+ if let ty:: TyRef ( r_, mt) = target. sty {
517
+ * r = r_;
518
+ * mutbl = mt. mutbl ;
519
+ } else {
520
+ span_bug ! ( expr. span, "input to lvalue op is not a ref?" ) ;
521
+ }
522
+ }
509
523
}
510
524
511
525
///////////////////////////////////////////////////////////////////////////
0 commit comments