diff --git a/README.md b/README.md index 8c42771..8aa0d2b 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Currently missing big features (TODOs) are: - Importable binops? Big features that I want later but are not necessary: -- Associated functions +- Associated functions (for e.g. sizeof) - ~~User-defined binary operations~~ (DONE) - ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE) - Error handling diff --git a/examples/struct.reid b/examples/struct.reid index ac293d7..a831276 100644 --- a/examples/struct.reid +++ b/examples/struct.reid @@ -7,11 +7,10 @@ struct Test { fn main() -> u32 { let mut value = Test { - field: 5, second: 3, + field: 5, }; - value.second = 17; return value.second; } diff --git a/reid/src/mir/typecheck/mod.rs b/reid/src/mir/typecheck/mod.rs index 664eada..38dbe6f 100644 --- a/reid/src/mir/typecheck/mod.rs +++ b/reid/src/mir/typecheck/mod.rs @@ -50,6 +50,8 @@ pub enum ErrorKind { TriedAccessingNonStruct(TypeKind), #[error("No such struct-field on type {0}")] NoSuchField(String), + #[error("Missing definition for field \"{0}\"")] + MissingStructField(String), #[error("Struct field declared twice {0}")] DuplicateStructField(String), #[error("Type declared twice {0}")] diff --git a/reid/src/mir/typecheck/typecheck.rs b/reid/src/mir/typecheck/typecheck.rs index 1ff70f2..6e69024 100644 --- a/reid/src/mir/typecheck/typecheck.rs +++ b/reid/src/mir/typecheck/typecheck.rs @@ -632,6 +632,13 @@ impl Expression { .get_struct_type(&type_key) .ok_or(ErrorKind::NoSuchType(struct_name.clone(), type_key.1))? .clone(); + + let mut expected_fields = if let Some(struct_ty) = state.scope.get_struct_type(&type_key) { + struct_ty.0.iter().map(|f| f.0.clone()).collect() + } else { + HashSet::new() + }; + for (field_name, field_expr) in items { // Get expected type, or error if field does not exist let expected_ty = state.or_else( @@ -641,6 +648,7 @@ impl Expression { &TypeKind::Vague(VagueType::Unknown), field_expr.1, ); + expected_fields.remove(field_name); // Typecheck the actual expression let expr_res = field_expr.typecheck(state, typerefs, HintKind::Coerce(expected_ty.clone())); @@ -649,6 +657,15 @@ impl Expression { // Make sure both are the same type, report error if not state.ok(expr_ty.narrow_into(&expr_ty), field_expr.1); } + + state.note_errors( + &expected_fields + .into_iter() + .map(|v| ErrorKind::MissingStructField(v)) + .collect(), + self.1, + ); + Ok(TypeKind::CustomType(type_key)) } ExprKind::Borrow(var_ref, mutable) => {