rue_compiler/compile/binding/
struct_binding.rs1use log::debug;
2use rue_ast::AstStructBinding;
3use rue_diagnostic::DiagnosticKind;
4use rue_hir::{BindingSymbol, Declaration, Hir, Symbol, SymbolId, SymbolPath, Value};
5
6use crate::{
7 Compiler, Field, FieldResult, compile_field, create_binding, create_binding_for_identifier,
8};
9
10pub fn create_struct_binding(
11 ctx: &mut Compiler,
12 symbol: SymbolId,
13 struct_binding: &AstStructBinding,
14) {
15 let ty = ctx.symbol_type(symbol);
16 let reference = Value::new(ctx.alloc_hir(Hir::Reference(symbol)), ty)
17 .with_reference(SymbolPath::new(symbol, vec![]));
18
19 for field in struct_binding.fields() {
20 let Some(name) = field.name() else {
21 continue;
22 };
23
24 let value = match compile_field(ctx, reference.clone(), &Field::Named(name.text())) {
25 FieldResult::Value(value) => value,
26 FieldResult::Unknown => {
27 debug!("Unresolved field access due to unknown field");
28 let type_name = ctx.type_name(reference.ty);
29 ctx.diagnostic(
30 &name,
31 DiagnosticKind::UnknownField(name.text().to_string(), type_name),
32 );
33 ctx.builtins().unresolved.clone()
34 }
35 FieldResult::Error => {
36 debug!("Unresolved field access due to missing field in underlying struct type");
37 let type_name = ctx.type_name(reference.ty);
38 ctx.diagnostic(
39 &name,
40 DiagnosticKind::MissingField(name.text().to_string(), type_name),
41 );
42 ctx.builtins().unresolved.clone()
43 }
44 };
45
46 let binding_symbol = ctx.alloc_symbol(Symbol::Binding(BindingSymbol {
47 name: None,
48 value,
49 inline: true,
50 }));
51 ctx.push_declaration(Declaration::Symbol(binding_symbol));
52 ctx.reference(Declaration::Symbol(symbol));
53
54 if let Some(binding) = field.binding() {
55 create_binding(ctx, binding_symbol, &binding);
56 } else {
57 create_binding_for_identifier(ctx, binding_symbol, name);
58 }
59
60 ctx.pop_declaration();
61 }
62}