Skip to content

Commit 9272942

Browse files
committed
Use CoerceMany in BreakableContext
1 parent e968d83 commit 9272942

File tree

3 files changed

+26
-36
lines changed

3 files changed

+26
-36
lines changed

crates/hir_ty/src/infer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ use stdx::impl_from;
3535
use syntax::SmolStr;
3636

3737
use crate::{
38-
db::HirDatabase, fold_tys, lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy,
39-
DomainGoal, Goal, InEnvironment, Interner, ProjectionTy, Substitution, TraitEnvironment,
40-
TraitRef, Ty, TyBuilder, TyExt, TyKind,
38+
db::HirDatabase, fold_tys, infer::coerce::CoerceMany, lower::ImplTraitLoweringMode,
39+
to_assoc_type_id, AliasEq, AliasTy, DomainGoal, Goal, InEnvironment, Interner, ProjectionTy,
40+
Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind,
4141
};
4242

4343
// This lint has a false positive here. See the link below for details.
@@ -349,7 +349,7 @@ struct InferenceContext<'a> {
349349
#[derive(Clone, Debug)]
350350
struct BreakableContext {
351351
may_break: bool,
352-
break_ty: Ty,
352+
coerce: CoerceMany,
353353
label: Option<name::Name>,
354354
}
355355

crates/hir_ty/src/infer/coerce.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,6 @@ impl CoerceMany {
4848
CoerceMany { expected_ty: expected }
4949
}
5050

51-
pub(super) fn once(
52-
ctx: &mut InferenceContext<'_>,
53-
expected: Ty,
54-
expr: Option<ExprId>,
55-
expr_ty: &Ty,
56-
) -> Ty {
57-
let mut this = CoerceMany::new(expected);
58-
this.coerce(ctx, expr, expr_ty);
59-
this.complete()
60-
}
61-
6251
/// Merge two types from different branches, with possible coercion.
6352
///
6453
/// Mostly this means trying to coerce one to the other, but

crates/hir_ty/src/infer/expr.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'a> InferenceContext<'a> {
163163
let break_ty = self.table.new_type_var();
164164
self.breakables.push(BreakableContext {
165165
may_break: false,
166-
break_ty: break_ty.clone(),
166+
coerce: CoerceMany::new(break_ty.clone()),
167167
label: label.map(|label| self.body[label].name.clone()),
168168
});
169169
let ty = self.infer_block(
@@ -174,7 +174,7 @@ impl<'a> InferenceContext<'a> {
174174
);
175175
let ctxt = self.breakables.pop().expect("breakable stack broken");
176176
if ctxt.may_break {
177-
ctxt.break_ty
177+
ctxt.coerce.complete()
178178
} else {
179179
ty
180180
}
@@ -202,27 +202,24 @@ impl<'a> InferenceContext<'a> {
202202
Expr::Loop { body, label } => {
203203
self.breakables.push(BreakableContext {
204204
may_break: false,
205-
break_ty: self.table.new_type_var(),
205+
coerce: CoerceMany::new(self.table.new_type_var()),
206206
label: label.map(|label| self.body[label].name.clone()),
207207
});
208208
self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
209209

210210
let ctxt = self.breakables.pop().expect("breakable stack broken");
211-
if ctxt.may_break {
212-
self.diverges = Diverges::Maybe;
213-
}
214211

215212
if ctxt.may_break {
216-
ctxt.break_ty
213+
self.diverges = Diverges::Maybe;
214+
ctxt.coerce.complete()
217215
} else {
218216
TyKind::Never.intern(&Interner)
219217
}
220218
}
221219
Expr::While { condition, body, label } => {
222220
self.breakables.push(BreakableContext {
223221
may_break: false,
224-
break_ty: self.err_ty(),
225-
222+
coerce: CoerceMany::new(self.err_ty()),
226223
label: label.map(|label| self.body[label].name.clone()),
227224
});
228225
// while let is desugared to a match loop, so this is always simple while
@@ -241,7 +238,7 @@ impl<'a> InferenceContext<'a> {
241238

242239
self.breakables.push(BreakableContext {
243240
may_break: false,
244-
break_ty: self.err_ty(),
241+
coerce: CoerceMany::new(self.err_ty()),
245242
label: label.map(|label| self.body[label].name.clone()),
246243
});
247244
let pat_ty =
@@ -383,31 +380,35 @@ impl<'a> InferenceContext<'a> {
383380
}
384381
Expr::Continue { .. } => TyKind::Never.intern(&Interner),
385382
Expr::Break { expr, label } => {
386-
let expr = *expr;
387-
let last_ty =
388-
if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
389-
ctxt.break_ty.clone()
390-
} else {
391-
self.err_ty()
392-
};
383+
let mut coerce = match find_breakable(&mut self.breakables, label.as_ref()) {
384+
Some(ctxt) => {
385+
// avoiding the borrowck
386+
mem::replace(
387+
&mut ctxt.coerce,
388+
CoerceMany::new(self.result.standard_types.unknown.clone()),
389+
)
390+
}
391+
None => CoerceMany::new(self.result.standard_types.unknown.clone()),
392+
};
393393

394-
let val_ty = if let Some(expr) = expr {
394+
let val_ty = if let Some(expr) = *expr {
395395
self.infer_expr(expr, &Expectation::none())
396396
} else {
397397
TyBuilder::unit()
398398
};
399399

400400
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
401-
let merged_type = CoerceMany::once(self, last_ty, expr, &val_ty);
401+
coerce.coerce(self, *expr, &val_ty);
402402

403403
if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
404-
ctxt.break_ty = merged_type;
404+
ctxt.coerce = coerce;
405405
ctxt.may_break = true;
406406
} else {
407407
self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
408408
expr: tgt_expr,
409409
});
410-
}
410+
};
411+
411412
TyKind::Never.intern(&Interner)
412413
}
413414
Expr::Return { expr } => {

0 commit comments

Comments
 (0)