@@ -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
@@ -1038,7 +1044,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1038
1044
/// The expressions *must not* have any preexisting adjustments.
1039
1045
pub ( crate ) fn coerce (
1040
1046
& self ,
1041
- expr : & hir:: Expr < ' _ > ,
1047
+ expr : & ' tcx hir:: Expr < ' tcx > ,
1042
1048
expr_ty : Ty < ' tcx > ,
1043
1049
mut target : Ty < ' tcx > ,
1044
1050
allow_two_phase : AllowTwoPhase ,
@@ -1055,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1055
1061
1056
1062
let cause =
1057
1063
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 ) ) ;
1059
1065
let ok = self . commit_if_ok ( |_| coerce. coerce ( source, target) ) ?;
1060
1066
1061
1067
let ( adjustments, _) = self . register_infer_ok_obligations ( ok) ;
@@ -1078,7 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1078
1084
1079
1085
let cause = self . cause ( DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
1080
1086
// 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 ) ;
1082
1088
self . probe ( |_| {
1083
1089
let Ok ( ok) = coerce. coerce ( source, target) else {
1084
1090
return false ;
@@ -1095,7 +1101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1095
1101
pub ( crate ) fn deref_steps ( & self , expr_ty : Ty < ' tcx > , target : Ty < ' tcx > ) -> Option < usize > {
1096
1102
let cause = self . cause ( DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
1097
1103
// 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 ) ;
1099
1105
coerce
1100
1106
. autoderef ( DUMMY_SP , expr_ty)
1101
1107
. find_map ( |( ty, steps) | self . probe ( |_| coerce. unify ( ty, target) ) . ok ( ) . map ( |_| steps) )
@@ -1252,7 +1258,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1252
1258
// probably aren't processing function arguments here and even if we were,
1253
1259
// they're going to get autorefed again anyway and we can apply 2-phase borrows
1254
1260
// 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 ) ;
1256
1262
coerce. use_lub = true ;
1257
1263
1258
1264
// First try to coerce the new expression to the type of the previous ones,
0 commit comments