@@ -125,7 +125,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
125125
126126 fn unify_raw ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> InferResult < ' tcx , Ty < ' tcx > > {
127127 debug ! ( "unify(a: {:?}, b: {:?}, use_lub: {})" , a, b, self . use_lub) ;
128- self . commit_if_ok ( |_| {
128+ self . commit_if_ok ( |snapshot| {
129+ let outer_universe = self . infcx . universe ( ) ;
130+
129131 let at = self . at ( & self . cause , self . fcx . param_env ) ;
130132
131133 let res = if self . use_lub {
@@ -138,7 +140,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
138140 // In the new solver, lazy norm may allow us to shallowly equate
139141 // more types, but we emit possibly impossible-to-satisfy obligations.
140142 // Filter these cases out to make sure our coercion is more accurate.
141- match res {
143+ let res = match res {
142144 Ok ( InferOk { value, obligations } ) if self . next_trait_solver ( ) => {
143145 let ocx = ObligationCtxt :: new ( self ) ;
144146 ocx. register_obligations ( obligations) ;
@@ -149,7 +151,27 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
149151 }
150152 }
151153 res => res,
152- }
154+ } ;
155+
156+ // We leak check here mostly because lub operations are
157+ // kind of scuffed around binders. Instead of computing an actual
158+ // lub'd binder we instead:
159+ // - Equate the binders
160+ // - Return the lhs of the lub operation
161+ //
162+ // In order to actually ensure that equating the binders *does*
163+ // result in equal binders, and that the lhs is actually a supertype
164+ // of the rhs, we must perform a leak check here.
165+ //
166+ // Leak checking even when `use_lub` is false causes us to emit some
167+ // errors in dead code where borrowck would otherwise not catch the
168+ // subtyping errors. This is not soundness critical.
169+ //
170+ // FIXME: Ideally the actual `eq/sub/lub` would handle leak checks
171+ // themselves whenever a binder is entered.
172+ self . leak_check ( outer_universe, Some ( snapshot) ) ?;
173+
174+ res
153175 } )
154176 }
155177
@@ -805,40 +827,26 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
805827 b : ty:: PolyFnSig < ' tcx > ,
806828 adjustment : Option < Adjust > ,
807829 ) -> CoerceResult < ' tcx > {
808- self . commit_if_ok ( |snapshot| {
809- let outer_universe = self . infcx . universe ( ) ;
810-
811- let a_ty = Ty :: new_fn_ptr ( self . tcx , a) ;
812- let b_ty = Ty :: new_fn_ptr ( self . tcx , b) ;
830+ let a_ty = Ty :: new_fn_ptr ( self . tcx , a) ;
831+ let b_ty = Ty :: new_fn_ptr ( self . tcx , b) ;
813832
814- // Handle coercing `fn(..)` to `unsafe fn(..)`
815- let result = if a. safety ( ) . is_safe ( ) && b. safety ( ) . is_unsafe ( ) {
816- let unsafe_a_ty = self . tcx . safe_to_unsafe_fn_ty ( a) ;
817- let adjustment = adjustment. map ( |kind| Adjustment { kind, target : a_ty } ) ;
833+ // Handle coercing `fn(..)` to `unsafe fn(..)`
834+ if a. safety ( ) . is_safe ( ) && b. safety ( ) . is_unsafe ( ) {
835+ let unsafe_a_ty = self . tcx . safe_to_unsafe_fn_ty ( a) ;
836+ let adjustment = adjustment. map ( |kind| Adjustment { kind, target : a_ty } ) ;
818837
819- self . unify_and (
820- unsafe_a_ty,
821- b_ty,
822- adjustment,
823- Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ,
824- )
825- } else {
826- match adjustment {
827- Some ( adjust) => self . unify_and ( a_ty, b_ty, [ ] , adjust) ,
828- None => self . unify ( a_ty, b_ty) ,
829- }
830- } ;
831-
832- // FIXME(#73154): This is a hack. Currently LUB can generate
833- // unsolvable constraints. Additionally, it returns `a`
834- // unconditionally, even when the "LUB" is `b`. In the future, we
835- // want the coerced type to be the actual supertype of these two,
836- // but for now, we want to just error to ensure we don't lock
837- // ourselves into a specific behavior with NLL.
838- self . leak_check ( outer_universe, Some ( snapshot) ) ?;
839-
840- result
841- } )
838+ self . unify_and (
839+ unsafe_a_ty,
840+ b_ty,
841+ adjustment,
842+ Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ,
843+ )
844+ } else {
845+ match adjustment {
846+ Some ( adjust) => self . unify_and ( a_ty, b_ty, [ ] , adjust) ,
847+ None => self . unify ( a_ty, b_ty) ,
848+ }
849+ }
842850 }
843851
844852 fn coerce_from_fn_pointer (
0 commit comments