diff --git a/lang_tests/instance_fields_overlap/test.som b/lang_tests/instance_fields_overlap/test.som new file mode 100644 index 00000000..709135a7 --- /dev/null +++ b/lang_tests/instance_fields_overlap/test.som @@ -0,0 +1,13 @@ +" +VM: + status: error + stderr: + ...test.som', line 10, column 23: + test = test_super ( | a | + Field 'a' is already defined in a superclass. +" + +test = test_super ( | a | + run = ( + ) +) diff --git a/lang_tests/instance_fields_overlap/test_super.som b/lang_tests/instance_fields_overlap/test_super.som new file mode 100644 index 00000000..f5f95b34 --- /dev/null +++ b/lang_tests/instance_fields_overlap/test_super.som @@ -0,0 +1,3 @@ +test_super = ( + | a | +) diff --git a/lang_tests/instance_fields_overlap2.som b/lang_tests/instance_fields_overlap2.som new file mode 100644 index 00000000..2a9419ee --- /dev/null +++ b/lang_tests/instance_fields_overlap2.som @@ -0,0 +1,12 @@ +" +VM: + status: error + stderr: + ...instance_fields_overlap2.som', line 11, column 9: + | a a | + Field 'a' has already been defined in this class. +" + +instance_field_overlap2 = ( + | a a | +) diff --git a/src/lib/compiler/ast_to_instrs.rs b/src/lib/compiler/ast_to_instrs.rs index 8ce3200f..be6929c2 100644 --- a/src/lib/compiler/ast_to_instrs.rs +++ b/src/lib/compiler/ast_to_instrs.rs @@ -153,13 +153,36 @@ impl<'a, 'input> Compiler<'a, 'input> { .iter() .map(|(k, v)| (k.to_owned(), *v)), ); + for var in ast_inst_vars { + let n = lexer.span_str(*var); + if inst_vars.contains_key(n) { + return Err(vec![( + *var, + format!("Field '{}' is already defined in a superclass.", n), + )]); + } + } inst_vars } else { HashMap::with_capacity(ast_inst_vars.len()) }; for var in ast_inst_vars { let vars_len = inst_vars.len(); - inst_vars.insert(lexer.span_str(*var).to_owned(), vars_len); + let n = lexer.span_str(*var).to_owned(); + match inst_vars.entry(n) { + hash_map::Entry::Occupied(_) => { + return Err(vec![( + *var, + format!( + "Field '{}' has already been defined in this class.", + self.lexer.span_str(*var) + ), + )]) + } + hash_map::Entry::Vacant(e) => { + e.insert(vars_len); + } + } } self.vars_stack.push(inst_vars);