@@ -82,6 +82,7 @@ struct Coerce<'a, 'tcx> {
8282/// See #47489 and #48598
8383/// See docs on the "AllowTwoPhase" type for a more detailed discussion
8484allow_two_phase : AllowTwoPhase ,
85+ coerce_never : bool ,
8586}
8687
8788impl < ' a , ' tcx > Deref for Coerce < ' a , ' tcx > {
@@ -125,8 +126,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
125126fcx : & ' f FnCtxt < ' f , ' tcx > ,
126127cause : ObligationCause < ' tcx > ,
127128allow_two_phase : AllowTwoPhase ,
129+ coerce_never : bool ,
128130) -> Self {
129- Coerce { fcx, cause, allow_two_phase, use_lub : false }
131+ Coerce { fcx, cause, allow_two_phase, use_lub : false , coerce_never }
130132}
131133
132134fn unify ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> InferResult < ' tcx , Ty < ' tcx > > {
@@ -177,7 +179,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
177179
178180// Coercing from `!` to any type is allowed:
179181if a. is_never ( ) {
180- return success ( simple ( Adjust :: NeverToAny ) ( b) , b, vec ! [ ] ) ;
182+ if self . coerce_never {
183+ return success ( simple ( Adjust :: NeverToAny ) ( b) , b, vec ! [ ] ) ;
184+ } else {
185+ return self . unify_and ( a, b, identity) ;
186+ }
181187}
182188
183189// Coercing *from* an unresolved inference variable means that
@@ -1038,7 +1044,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10381044/// The expressions *must not* have any preexisting adjustments.
10391045pub ( crate ) fn coerce (
10401046& self ,
1041- expr : & hir:: Expr < ' _ > ,
1047+ expr : & ' tcx hir:: Expr < ' tcx > ,
10421048expr_ty : Ty < ' tcx > ,
10431049mut target : Ty < ' tcx > ,
10441050allow_two_phase : AllowTwoPhase ,
@@ -1055,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10551061
10561062let cause =
10571063 cause. unwrap_or_else ( || self . cause ( expr. span , ObligationCauseCode :: ExprAssignable ) ) ;
1058- let coerce = Coerce :: new ( self , cause, allow_two_phase) ;
1064+ let coerce = Coerce :: new ( self , cause, allow_two_phase, self . expr_constitutes_read ( expr ) ) ;
10591065let ok = self . commit_if_ok ( |_| coerce. coerce ( source, target) ) ?;
10601066
10611067let ( adjustments, _) = self . register_infer_ok_obligations ( ok) ;
@@ -1078,7 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10781084
10791085let cause = self . cause ( DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
10801086// We don't ever need two-phase here since we throw out the result of the coercion
1081- let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No ) ;
1087+ let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No , true ) ;
10821088self . probe ( |_| {
10831089let Ok ( ok) = coerce. coerce ( source, target) else {
10841090return false ;
@@ -1095,7 +1101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10951101pub ( crate ) fn deref_steps ( & self , expr_ty : Ty < ' tcx > , target : Ty < ' tcx > ) -> Option < usize > {
10961102let cause = self . cause ( DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
10971103// We don't ever need two-phase here since we throw out the result of the coercion
1098- let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No ) ;
1104+ let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No , true ) ;
10991105 coerce
11001106. autoderef ( DUMMY_SP , expr_ty)
11011107. find_map ( |( ty, steps) | self . probe ( |_| coerce. unify ( ty, target) ) . ok ( ) . map ( |_| steps) )
@@ -1252,7 +1258,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12521258// probably aren't processing function arguments here and even if we were,
12531259// they're going to get autorefed again anyway and we can apply 2-phase borrows
12541260// at that time.
1255- let mut coerce = Coerce :: new ( self , cause. clone ( ) , AllowTwoPhase :: No ) ;
1261+ let mut coerce = Coerce :: new ( self , cause. clone ( ) , AllowTwoPhase :: No , true ) ;
12561262 coerce. use_lub = true ;
12571263
12581264// First try to coerce the new expression to the type of the previous ones,
0 commit comments