@@ -82,6 +82,7 @@ struct Coerce<'a, 'tcx> {
82
82
/// See #47489 and #48598
83
83
/// See docs on the "AllowTwoPhase" type for a more detailed discussion
84
84
allow_two_phase : AllowTwoPhase ,
85
+ coerce_never : bool ,
85
86
}
86
87
87
88
impl < ' a , ' tcx > Deref for Coerce < ' a , ' tcx > {
@@ -125,8 +126,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
125
126
fcx : & ' f FnCtxt < ' f , ' tcx > ,
126
127
cause : ObligationCause < ' tcx > ,
127
128
allow_two_phase : AllowTwoPhase ,
129
+ coerce_never : bool ,
128
130
) -> Self {
129
- Coerce { fcx, cause, allow_two_phase, use_lub : false }
131
+ Coerce { fcx, cause, allow_two_phase, use_lub : false , coerce_never }
130
132
}
131
133
132
134
fn unify ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> InferResult < ' tcx , Ty < ' tcx > > {
@@ -177,7 +179,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
177
179
178
180
// Coercing from `!` to any type is allowed:
179
181
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
+ }
181
187
}
182
188
183
189
// Coercing *from* an unresolved inference variable means that
@@ -979,7 +985,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
979
985
/// The expressions *must not* have any preexisting adjustments.
980
986
pub ( crate ) fn coerce (
981
987
& self ,
982
- expr : & hir:: Expr < ' _ > ,
988
+ expr : & ' tcx hir:: Expr < ' tcx > ,
983
989
expr_ty : Ty < ' tcx > ,
984
990
mut target : Ty < ' tcx > ,
985
991
allow_two_phase : AllowTwoPhase ,
@@ -996,7 +1002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
996
1002
997
1003
let cause =
998
1004
cause. unwrap_or_else ( || self . cause ( expr. span , ObligationCauseCode :: ExprAssignable ) ) ;
999
- let coerce = Coerce :: new ( self , cause, allow_two_phase) ;
1005
+ let coerce = Coerce :: new ( self , cause, allow_two_phase, self . expr_constitutes_read ( expr ) ) ;
1000
1006
let ok = self . commit_if_ok ( |_| coerce. coerce ( source, target) ) ?;
1001
1007
1002
1008
let ( adjustments, _) = self . register_infer_ok_obligations ( ok) ;
@@ -1019,7 +1025,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1019
1025
1020
1026
let cause = self . cause ( DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
1021
1027
// We don't ever need two-phase here since we throw out the result of the coercion
1022
- let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No ) ;
1028
+ let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No , true ) ;
1023
1029
self . probe ( |_| {
1024
1030
let Ok ( ok) = coerce. coerce ( source, target) else {
1025
1031
return false ;
@@ -1036,7 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1036
1042
pub ( crate ) fn deref_steps ( & self , expr_ty : Ty < ' tcx > , target : Ty < ' tcx > ) -> Option < usize > {
1037
1043
let cause = self . cause ( DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
1038
1044
// We don't ever need two-phase here since we throw out the result of the coercion
1039
- let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No ) ;
1045
+ let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No , true ) ;
1040
1046
coerce
1041
1047
. autoderef ( DUMMY_SP , expr_ty)
1042
1048
. find_map ( |( ty, steps) | self . probe ( |_| coerce. unify ( ty, target) ) . ok ( ) . map ( |_| steps) )
@@ -1193,7 +1199,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1193
1199
// probably aren't processing function arguments here and even if we were,
1194
1200
// they're going to get autorefed again anyway and we can apply 2-phase borrows
1195
1201
// at that time.
1196
- let mut coerce = Coerce :: new ( self , cause. clone ( ) , AllowTwoPhase :: No ) ;
1202
+ let mut coerce = Coerce :: new ( self , cause. clone ( ) , AllowTwoPhase :: No , true ) ;
1197
1203
coerce. use_lub = true ;
1198
1204
1199
1205
// First try to coerce the new expression to the type of the previous ones,
0 commit comments