@@ -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
8484 allow_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> {
125126 fcx : & ' f FnCtxt < ' f , ' tcx > ,
126127 cause : ObligationCause < ' tcx > ,
127128 allow_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
132134 fn 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:
179181 if 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.
10391045 pub ( crate ) fn coerce (
10401046 & self ,
1041- expr : & hir:: Expr < ' _ > ,
1047+ expr : & ' tcx hir:: Expr < ' tcx > ,
10421048 expr_ty : Ty < ' tcx > ,
10431049 mut target : Ty < ' tcx > ,
10441050 allow_two_phase : AllowTwoPhase ,
@@ -1055,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10551061
10561062 let 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 ) ) ;
10591065 let ok = self . commit_if_ok ( |_| coerce. coerce ( source, target) ) ?;
10601066
10611067 let ( adjustments, _) = self . register_infer_ok_obligations ( ok) ;
@@ -1078,7 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10781084
10791085 let 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 ) ;
10821088 self . probe ( |_| {
10831089 let Ok ( ok) = coerce. coerce ( source, target) else {
10841090 return false ;
@@ -1095,7 +1101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10951101 pub ( crate ) fn deref_steps ( & self , expr_ty : Ty < ' tcx > , target : Ty < ' tcx > ) -> Option < usize > {
10961102 let 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