@@ -251,8 +251,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
251251 ty:: RawPtr ( _, b_mutbl) => {
252252 return self . coerce_to_raw_ptr ( a, b, b_mutbl) ;
253253 }
254- ty:: Ref ( _ , _, mutbl_b) => {
255- return self . coerce_to_ref ( a, b, mutbl_b) ;
254+ ty:: Ref ( r_b , _, mutbl_b) => {
255+ return self . coerce_to_ref ( a, b, mutbl_b, r_b ) ;
256256 }
257257 ty:: Adt ( pin, _)
258258 if self . tcx . features ( ) . pin_ergonomics ( )
@@ -343,15 +343,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
343343 a : Ty < ' tcx > ,
344344 b : Ty < ' tcx > ,
345345 mutbl_b : hir:: Mutability ,
346+ r_b : ty:: Region < ' tcx > ,
346347 ) -> CoerceResult < ' tcx > {
347348 debug ! ( "coerce_to_ref(a={:?}, b={:?})" , a, b) ;
348349 debug_assert ! ( self . shallow_resolve( a) == a) ;
349350 debug_assert ! ( self . shallow_resolve( b) == b) ;
350351
351- let mt_a = match * a. kind ( ) {
352- ty:: Ref ( _ , ty, mutbl) => {
352+ let ( r_a , mt_a) = match * a. kind ( ) {
353+ ty:: Ref ( r_a , ty, mutbl) => {
353354 coerce_mutbls ( mutbl, mutbl_b) ?;
354- ty:: TypeAndMut { ty, mutbl }
355+ ( r_a , ty:: TypeAndMut { ty, mutbl } )
355356 }
356357 _ => return self . unify ( a, b) ,
357358 } ;
@@ -368,6 +369,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
368369 // 3. `[T]`, autoref'd ty: `&M [T]`
369370 // - `&M [T]` does unify with `&M [T]`
370371 let mut first_error = None ;
372+ let mut r_borrow_var = None ;
371373 let mut autoderef = self . autoderef ( self . cause . span , a) ;
372374 let found = autoderef. by_ref ( ) . find_map ( |( deref_ty, autoderefs) | {
373375 if autoderefs == 0 {
@@ -376,9 +378,29 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
376378 return None ;
377379 }
378380
379- let coercion = RegionVariableOrigin :: Coercion ( self . cause . span ) ;
380- let r_borrow = self . next_region_var ( coercion) ;
381- let autorefd_deref_ty = Ty :: new_ref ( self . tcx , r_borrow, deref_ty, mutbl_b) ;
381+ let r = if !self . use_lub {
382+ r_b // [2] above
383+ } else if autoderefs == 1 {
384+ r_a // [3] above
385+ } else {
386+ if r_borrow_var. is_none ( ) {
387+ // create var lazily, at most once
388+ let coercion = RegionVariableOrigin :: Coercion ( self . cause . span ) ;
389+ let r = self . next_region_var ( coercion) ;
390+ r_borrow_var = Some ( r) ; // [4] above
391+ }
392+ r_borrow_var. unwrap ( )
393+ } ;
394+ let autorefd_deref_ty = Ty :: new_ref (
395+ self . tcx ,
396+ r,
397+ deref_ty,
398+ mutbl_b, // [1] above
399+ ) ;
400+
401+ // let coercion = RegionVariableOrigin::Coercion(self.cause.span);
402+ // let r_borrow = self.next_region_var(coercion);
403+ // let autorefd_deref_ty = Ty::new_ref(self.tcx, r_borrow, deref_ty, mutbl_b);
382404
383405 // Note that we unify the autoref'd `Target` type with `b` rather than
384406 // the `Target` type with the pointee of `b`. This is necessary
0 commit comments