use diagnostics::LocalSink;
use syntax::ast::{Expression, Span};
use syntax::types::{Type, unqualified_name};
use crate::store::Store;
pub(crate) fn run(typed_ast: &[Expression], store: &Store, sink: &LocalSink) {
for item in typed_ast {
visit_expression(item, store, sink);
}
}
fn visit_expression(expression: &Expression, store: &Store, sink: &LocalSink) {
match expression {
Expression::Identifier {
qualified: Some(qualified),
value,
span,
..
} => {
if let Some((enum_id, variant_name)) = qualified.rsplit_once('.') {
check(enum_id, variant_name, value, *span, store, sink);
}
}
Expression::DotAccess {
expression: base,
member,
span,
..
} => {
if let Type::Nominal { id, .. } = base.get_type().strip_refs() {
let display = format!("{}.{}", unqualified_name(&id), member);
check(&id, member, &display, *span, store, sink);
}
}
_ => {}
}
for child in expression.children() {
visit_expression(child, store, sink);
}
}
fn check(
enum_qualified: &str,
variant_name: &str,
display: &str,
span: Span,
store: &Store,
sink: &LocalSink,
) {
let Some(variant) = store.variant_of(enum_qualified, variant_name) else {
return;
};
if !variant.fields.is_struct() {
return;
}
sink.push(diagnostics::infer::enum_variant_constructor_value(
display, span,
));
}