@@ -103,10 +103,6 @@ fn coerce_mutbls<'tcx>(
103103 if from_mutbl >= to_mutbl { Ok ( ( ) ) } else { Err ( TypeError :: Mutability ) }
104104}
105105
106- fn simple < ' tcx > ( kind : Adjust ) -> impl FnOnce ( Ty < ' tcx > ) -> Vec < Adjustment < ' tcx > > {
107- move |target| vec ! [ Adjustment { kind, target } ]
108- }
109-
110106/// This always returns `Ok(...)`.
111107fn success < ' tcx > (
112108 adj : Vec < Adjustment < ' tcx > > ,
@@ -163,12 +159,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
163159 }
164160
165161 /// Unify two types (using sub or lub) and produce a specific coercion.
166- fn unify_and < F > ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > , f : F ) -> CoerceResult < ' tcx >
167- where
168- F : FnOnce ( Ty < ' tcx > ) -> Vec < Adjustment < ' tcx > > ,
169- {
170- self . unify_raw ( a, b)
171- . and_then ( |InferOk { value : ty, obligations } | success ( f ( ty) , ty, obligations) )
162+ fn unify_and (
163+ & self ,
164+ a : Ty < ' tcx > ,
165+ b : Ty < ' tcx > ,
166+ mut adjustments : Vec < Adjustment < ' tcx > > ,
167+ final_adjustment : Adjust ,
168+ ) -> CoerceResult < ' tcx > {
169+ self . unify_raw ( a, b) . and_then ( |InferOk { value : ty, obligations } | {
170+ adjustments. push ( Adjustment { target : ty, kind : final_adjustment } ) ;
171+ success ( adjustments, ty, obligations)
172+ } )
172173 }
173174
174175 #[ instrument( skip( self ) ) ]
@@ -181,7 +182,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
181182 // Coercing from `!` to any type is allowed:
182183 if a. is_never ( ) {
183184 if self . coerce_never {
184- return success ( simple ( Adjust :: NeverToAny ) ( b) , b, PredicateObligations :: new ( ) ) ;
185+ return success (
186+ vec ! [ Adjustment { kind: Adjust :: NeverToAny , target: b } ] ,
187+ b,
188+ PredicateObligations :: new ( ) ,
189+ ) ;
185190 } else {
186191 // Otherwise the only coercion we can do is unification.
187192 return self . unify ( a, b) ;
@@ -574,13 +579,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
574579 // We only have the latter, so we use an inference variable
575580 // for the former and let type inference do the rest.
576581 let coerce_target = self . next_ty_var ( self . cause . span ) ;
577- let mut coercion = self . unify_and ( coerce_target, target, |target| {
578- let unsize = Adjustment { kind : Adjust :: Pointer ( PointerCoercion :: Unsize ) , target } ;
582+ let mut coercion = self . unify_and (
583+ coerce_target,
584+ target,
579585 match reborrow {
580- None => vec ! [ unsize] ,
581- Some ( ( ref deref, ref autoref) ) => vec ! [ deref. clone( ) , autoref. clone( ) , unsize] ,
582- }
583- } ) ?;
586+ None => vec ! [ ] ,
587+ Some ( ( ref deref, ref autoref) ) => vec ! [ deref. clone( ) , autoref. clone( ) ] ,
588+ } ,
589+ Adjust :: Pointer ( PointerCoercion :: Unsize ) ,
590+ ) ?;
584591
585592 let mut selcx = traits:: SelectionContext :: new ( self ) ;
586593
@@ -803,7 +810,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
803810
804811 // To complete the reborrow, we need to make sure we can unify the inner types, and if so we
805812 // add the adjustments.
806- self . unify_and ( a, b, simple ( Adjust :: ReborrowPin ( mut_b) ) )
813+ self . unify_and ( a, b, vec ! [ ] , Adjust :: ReborrowPin ( mut_b) )
807814 }
808815
809816 fn coerce_from_safe_fn (
@@ -820,22 +827,24 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
820827 && hdr_b. safety . is_unsafe ( )
821828 {
822829 let unsafe_a = self . tcx . safe_to_unsafe_fn_ty ( fn_ty_a) ;
823- self . unify_and ( unsafe_a, b, |target| match adjustment {
824- Some ( kind) => vec ! [
825- Adjustment { kind, target: Ty :: new_fn_ptr( self . tcx, fn_ty_a) } ,
826- Adjustment {
827- kind: Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ,
828- target,
829- } ,
830- ] ,
831- None => simple ( Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ) ( target) ,
832- } )
830+ let adjustments = match adjustment {
831+ Some ( kind) => {
832+ vec ! [ Adjustment { kind, target: Ty :: new_fn_ptr( self . tcx, fn_ty_a) } ]
833+ }
834+ None => vec ! [ ] ,
835+ } ;
836+ self . unify_and (
837+ unsafe_a,
838+ b,
839+ adjustments,
840+ Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ,
841+ )
833842 } else {
834843 let a = Ty :: new_fn_ptr ( self . tcx , fn_ty_a) ;
835- self . unify_and ( a , b , |target| match adjustment {
836- None => vec ! [ ] ,
837- Some ( kind ) => vec ! [ Adjustment { kind , target } ] ,
838- } )
844+ match adjustment {
845+ Some ( adjust ) => self . unify_and ( a , b , vec ! [ ] , adjust ) ,
846+ None => self . unify ( a , b ) ,
847+ }
839848 } ;
840849
841850 // FIXME(#73154): This is a hack. Currently LUB can generate
@@ -962,7 +971,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
962971 self . unify_and (
963972 pointer_ty,
964973 b,
965- simple ( Adjust :: Pointer ( PointerCoercion :: ClosureFnPointer ( safety) ) ) ,
974+ vec ! [ ] ,
975+ Adjust :: Pointer ( PointerCoercion :: ClosureFnPointer ( safety) ) ,
966976 )
967977 }
968978 _ => self . unify ( a, b) ,
@@ -990,14 +1000,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
9901000 // representation, we still register an Adjust::DerefRef so that
9911001 // regionck knows that the region for `a` must be valid here.
9921002 if is_ref {
993- self . unify_and ( a_raw , b , |target| {
994- vec ! [
995- Adjustment { kind : Adjust :: Deref ( None ) , target : mt_a . ty } ,
996- Adjustment { kind: Adjust :: Borrow ( AutoBorrow :: RawPtr ( mutbl_b ) ) , target } ,
997- ]
998- } )
1003+ self . unify_and (
1004+ a_raw ,
1005+ b ,
1006+ vec ! [ Adjustment { kind: Adjust :: Deref ( None ) , target: mt_a . ty } ] ,
1007+ Adjust :: Borrow ( AutoBorrow :: RawPtr ( mutbl_b ) ) ,
1008+ )
9991009 } else if mt_a. mutbl != mutbl_b {
1000- self . unify_and ( a_raw, b, simple ( Adjust :: Pointer ( PointerCoercion :: MutToConstPointer ) ) )
1010+ self . unify_and ( a_raw, b, vec ! [ ] , Adjust :: Pointer ( PointerCoercion :: MutToConstPointer ) )
10011011 } else {
10021012 self . unify ( a_raw, b)
10031013 }
0 commit comments