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