@@ -103,10 +103,6 @@ fn coerce_mutbls<'tcx>(
103
103
if from_mutbl >= to_mutbl { Ok ( ( ) ) } else { Err ( TypeError :: Mutability ) }
104
104
}
105
105
106
- fn simple < ' tcx > ( kind : Adjust ) -> impl FnOnce ( Ty < ' tcx > ) -> Vec < Adjustment < ' tcx > > {
107
- move |target| vec ! [ Adjustment { kind, target } ]
108
- }
109
-
110
106
/// This always returns `Ok(...)`.
111
107
fn success < ' tcx > (
112
108
adj : Vec < Adjustment < ' tcx > > ,
@@ -163,12 +159,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
163
159
}
164
160
165
161
/// 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
+ } )
172
173
}
173
174
174
175
#[ instrument( skip( self ) ) ]
@@ -181,7 +182,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
181
182
// Coercing from `!` to any type is allowed:
182
183
if a. is_never ( ) {
183
184
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
+ ) ;
185
190
} else {
186
191
// Otherwise the only coercion we can do is unification.
187
192
return self . unify ( a, b) ;
@@ -574,13 +579,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
574
579
// We only have the latter, so we use an inference variable
575
580
// for the former and let type inference do the rest.
576
581
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,
579
585
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
+ ) ?;
584
591
585
592
let mut selcx = traits:: SelectionContext :: new ( self ) ;
586
593
@@ -803,7 +810,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
803
810
804
811
// To complete the reborrow, we need to make sure we can unify the inner types, and if so we
805
812
// 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) )
807
814
}
808
815
809
816
fn coerce_from_safe_fn (
@@ -820,22 +827,24 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
820
827
&& hdr_b. safety . is_unsafe ( )
821
828
{
822
829
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
+ )
833
842
} else {
834
843
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
+ }
839
848
} ;
840
849
841
850
// FIXME(#73154): This is a hack. Currently LUB can generate
@@ -962,7 +971,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
962
971
self . unify_and (
963
972
pointer_ty,
964
973
b,
965
- simple ( Adjust :: Pointer ( PointerCoercion :: ClosureFnPointer ( safety) ) ) ,
974
+ vec ! [ ] ,
975
+ Adjust :: Pointer ( PointerCoercion :: ClosureFnPointer ( safety) ) ,
966
976
)
967
977
}
968
978
_ => self . unify ( a, b) ,
@@ -990,14 +1000,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
990
1000
// representation, we still register an Adjust::DerefRef so that
991
1001
// regionck knows that the region for `a` must be valid here.
992
1002
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
+ )
999
1009
} 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 ) )
1001
1011
} else {
1002
1012
self . unify ( a_raw, b)
1003
1013
}
0 commit comments