@@ -505,26 +505,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
505505 }
506506 } ;
507507
508- if coerced_a == a && mt_a. mutbl . is_not ( ) && autoderef. step_count ( ) == 1 {
509- // As a special case, if we would produce `&'a *x`, that's
510- // a total no-op. We end up with the type `&'a T` just as
511- // we started with. In that case, just skip it altogether.
512- //
513- // Unfortunately, this can actually effect capture analysis
514- // which in turn means this effects borrow checking. This can
515- // also effect diagnostics.
516- // FIXME(BoxyUwU): we should always emit reborrow coercions
517- //
518- // Note that for `&mut`, we DO want to reborrow --
519- // otherwise, this would be a move, which might be an
520- // error. For example `foo(self.x)` where `self` and
521- // `self.x` both have `&mut `type would be a move of
522- // `self.x`, but we auto-coerce it to `foo(&mut *self.x)`,
523- // which is a borrow.
524- assert ! ( mutbl_b. is_not( ) ) ; // can only coerce &T -> &U
525- return success ( vec ! [ ] , coerced_a, obligations) ;
526- }
527-
528508 let InferOk { value : mut adjustments, obligations : o } =
529509 self . adjust_steps_as_infer_ok ( & autoderef) ;
530510 obligations. extend ( o) ;
@@ -536,10 +516,31 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
536516 coerced_a
537517 ) ;
538518
539- // Now apply the autoref
540- let mutbl = AutoBorrowMutability :: new ( mutbl_b, self . allow_two_phase ) ;
541- adjustments
542- . push ( Adjustment { kind : Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) ) , target : coerced_a } ) ;
519+ if let Some ( Adjustment { kind : Adjust :: Deref ( DerefAdjustKind :: Builtin ) , .. } ) =
520+ adjustments. last ( )
521+ && let ty:: Ref ( _, _, ty:: Mutability :: Not ) = if adjustments. len ( ) >= 2 {
522+ * adjustments[ adjustments. len ( ) - 2 ] . target . kind ( )
523+ } else {
524+ ty:: Ref ( r_a, mt_a. ty , mt_a. mutbl )
525+ }
526+ && mutbl_b. is_not ( )
527+ {
528+ // As a special case, if we would produce `&'a *x`, that's
529+ // a total no-op. We end up with the type `&'a T` just as
530+ // we started with. In that case, just skip it altogether.
531+ //
532+ // FIXME: Ideally we would also skip `&mut` -> `&mut` reborrow,
533+ // and handle that in MIR. But unfortunately that would affect
534+ // closure capture inference, which affects borrowcheck
535+ adjustments. pop ( ) ;
536+ } else {
537+ // Now apply the autoref
538+ let mutbl = AutoBorrowMutability :: new ( mutbl_b, self . allow_two_phase ) ;
539+ adjustments. push ( Adjustment {
540+ kind : Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) ) ,
541+ target : coerced_a,
542+ } ) ;
543+ }
543544
544545 debug ! ( "coerce_to_ref: succeeded coerced_a={:?} adjustments={:?}" , coerced_a, adjustments) ;
545546
0 commit comments