Skip to content

Commit 5193c21

Browse files
Do not coerce places if they do not constitute reads
1 parent 6371ef6 commit 5193c21

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

‎compiler/rustc_hir_typeck/src/coercion.rs‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

8788
impl<'a,'tcx>DerefforCoerce<'a,'tcx>{
@@ -125,8 +126,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
125126
fcx:&'fFnCtxt<'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
fnunify(&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-
returnsuccess(simple(Adjust::NeverToAny)(b), b,vec![]);
182+
ifself.coerce_never{
183+
returnsuccess(simple(Adjust::NeverToAny)(b), b,vec![]);
184+
}else{
185+
returnself.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)fncoerce(
10401046
&self,
1041-
expr:&hir::Expr<'_>,
1047+
expr:&'tcxhir::Expr<'tcx>,
10421048
expr_ty:Ty<'tcx>,
10431049
muttarget: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
letOk(ok) = coerce.coerce(source, target)else{
10841090
returnfalse;
@@ -1095,7 +1101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10951101
pub(crate)fnderef_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-
letmut coerce = Coerce::new(self, cause.clone(),AllowTwoPhase::No);
1261+
letmut 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

Comments
 (0)