diff --git a/crates/rue-compiler/src/compiler/builtins.rs b/crates/rue-compiler/src/compiler/builtins.rs index 84d71c8..b476ae8 100644 --- a/crates/rue-compiler/src/compiler/builtins.rs +++ b/crates/rue-compiler/src/compiler/builtins.rs @@ -129,10 +129,13 @@ fn divmod(db: &mut Database, ty: &mut TypeSystem) -> SymbolId { let type_id = ty.alloc(Type::Unknown); + let parameters = ty.alloc(Type::Pair(ty.std().int, ty.std().nil)); + let parameters = ty.alloc(Type::Pair(ty.std().int, parameters)); + *ty.get_mut(type_id) = Type::Callable(Callable { original_type_id: type_id, parameter_names: indexset!["lhs".to_string(), "rhs".to_string()], - parameters: ty.alloc(Type::Pair(int_pair, ty.std().nil)), + parameters, rest: Rest::Nil, return_type: int_pair, generic_types: Vec::new(), diff --git a/crates/rue-compiler/src/compiler/expr/field_access_expr.rs b/crates/rue-compiler/src/compiler/expr/field_access_expr.rs index f7db906..f4658d3 100644 --- a/crates/rue-compiler/src/compiler/expr/field_access_expr.rs +++ b/crates/rue-compiler/src/compiler/expr/field_access_expr.rs @@ -32,7 +32,6 @@ impl Compiler<'_> { let type_id = fields[index]; if index == ty.field_names.len() - 1 && ty.rest == Rest::Optional { - todo!(); // TODO: type_id = self.ty.alloc(Type::Optional(type_id)); } @@ -56,14 +55,28 @@ impl Compiler<'_> { Type::Variant(variant) => { let field_names = variant.field_names.clone().unwrap_or_default(); - let fields = variant - .field_names - .as_ref() - .map(|field_names| { - deconstruct_items(self.ty, variant.type_id, field_names.len(), variant.rest) - .expect("invalid struct type") - }) - .unwrap_or_default(); + let Type::Enum(ty) = self.ty.get(variant.original_enum_type_id) else { + unreachable!(); + }; + + let fields = if ty.has_fields { + let type_id = self + .ty + .get_pair(variant.type_id) + .expect("expected a pair") + .1; + + variant + .field_names + .as_ref() + .map(|field_names| { + deconstruct_items(self.ty, type_id, field_names.len(), variant.rest) + .expect("invalid struct type") + }) + .unwrap_or_default() + } else { + Vec::new() + }; if let Some(index) = field_names.get_index_of(field_name.text()) { let type_id = fields[index]; diff --git a/crates/rue-compiler/src/compiler/expr/initializer_expr.rs b/crates/rue-compiler/src/compiler/expr/initializer_expr.rs index fc779fe..7e1a938 100644 --- a/crates/rue-compiler/src/compiler/expr/initializer_expr.rs +++ b/crates/rue-compiler/src/compiler/expr/initializer_expr.rs @@ -37,13 +37,23 @@ impl Compiler<'_> { } Some(Type::Variant(enum_variant)) => { if let Some(field_names) = enum_variant.field_names { - let fields = deconstruct_items( - self.ty, - enum_variant.type_id, - field_names.len(), - enum_variant.rest, - ) - .expect("invalid variant type"); + let Type::Enum(enum_type) = self.ty.get(enum_variant.original_enum_type_id) + else { + unreachable!(); + }; + + let fields = if enum_type.has_fields { + let type_id = self + .ty + .get_pair(enum_variant.type_id) + .expect("expected a pair") + .1; + + deconstruct_items(self.ty, type_id, field_names.len(), enum_variant.rest) + .expect("invalid struct type") + } else { + Vec::new() + }; let fields_hir_id = self.compile_initializer_fields( &field_names.into_iter().zip(fields).collect(), @@ -111,7 +121,6 @@ impl Compiler<'_> { { // TODO: optional |= matches!(self.db.ty(value.type_id), Type::Optional(..)); // value.type_id = self.db.non_undefined(value.type_id); - todo!() } // Check the type of the field initializer. diff --git a/crates/rue-compiler/src/compiler/expr/lambda_expr.rs b/crates/rue-compiler/src/compiler/expr/lambda_expr.rs index 1faa437..bc21893 100644 --- a/crates/rue-compiler/src/compiler/expr/lambda_expr.rs +++ b/crates/rue-compiler/src/compiler/expr/lambda_expr.rs @@ -100,7 +100,7 @@ impl Compiler<'_> { // If the parameter is optional, wrap the type in a possibly undefined type. // This prevents referencing the parameter until it's checked for undefined. // TODO: self.ty.alloc(Type::Optional(type_id)) - todo!() + type_id } else { type_id }; diff --git a/crates/rue-compiler/src/compiler/item/function_item.rs b/crates/rue-compiler/src/compiler/item/function_item.rs index 6d2c543..44be22e 100644 --- a/crates/rue-compiler/src/compiler/item/function_item.rs +++ b/crates/rue-compiler/src/compiler/item/function_item.rs @@ -74,7 +74,7 @@ impl Compiler<'_> { // If the parameter is optional, wrap the type in a possibly undefined type. // This prevents referencing the parameter until it's checked for undefined. // TODO: self.ty.alloc(Type::Optional(type_id)) - todo!() + type_id } else { // Otherwise, just use the type. type_id