internal: Resolve labels in body lowering

This commit is contained in:
Lukas Wirth 2023-04-06 12:50:16 +02:00
parent e9e57725aa
commit 0e7117900c
13 changed files with 420 additions and 182 deletions

View file

@ -18,6 +18,7 @@ use std::{convert::identity, ops::Index};
use chalk_ir::{cast::Cast, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags};
use either::Either;
use hir_def::expr::LabelId;
use hir_def::{
body::Body,
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
@ -188,12 +189,6 @@ pub enum InferenceDiagnostic {
/// Contains the type the field resolves to
field_with_same_name: Option<Ty>,
},
// FIXME: Make this proper
BreakOutsideOfLoop {
expr: ExprId,
is_break: bool,
bad_value_break: bool,
},
MismatchedArgCount {
call_expr: ExprId,
expected: usize,
@ -468,7 +463,7 @@ struct BreakableContext {
/// The coercion target of the context.
coerce: Option<CoerceMany>,
/// The optional label of the context.
label: Option<name::Name>,
label: Option<LabelId>,
kind: BreakableKind,
}
@ -483,28 +478,18 @@ enum BreakableKind {
fn find_breakable<'c>(
ctxs: &'c mut [BreakableContext],
label: Option<&name::Name>,
label: Option<LabelId>,
) -> Option<&'c mut BreakableContext> {
let mut ctxs = ctxs
.iter_mut()
.rev()
.take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
match label {
Some(_) => ctxs.find(|ctx| ctx.label.as_ref() == label),
Some(_) => ctxs.find(|ctx| ctx.label == label),
None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
}
}
fn find_continuable<'c>(
ctxs: &'c mut [BreakableContext],
label: Option<&name::Name>,
) -> Option<&'c mut BreakableContext> {
match label {
Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
None => find_breakable(ctxs, label),
}
}
impl<'a> InferenceContext<'a> {
fn new(
db: &'a dyn HirDatabase,