Skip to content

Commit

Permalink
Merge #147
Browse files Browse the repository at this point in the history
147: Detect overlapping field names r=vext01 a=ltratt

There are two cases to be dealt with:

1. A field name has already been defined in a superclass (5e00d91).
2. A class defines the same field more than once (9370609).

The first of those was pointed out by @Hirevo in SOM-st/SOM#42; the second is a relatively simple variation on the same theme.

Co-authored-by: Laurence Tratt <[email protected]>
  • Loading branch information
bors[bot] and ltratt authored Jun 10, 2020
2 parents b34fa1f + 4d6ba76 commit 48f10d9
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
13 changes: 13 additions & 0 deletions lang_tests/instance_fields_overlap/test.som
Original file line number Diff line number Diff line change
@@ -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 = (
)
)
3 changes: 3 additions & 0 deletions lang_tests/instance_fields_overlap/test_super.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test_super = (
| a |
)
12 changes: 12 additions & 0 deletions lang_tests/instance_fields_overlap2.som
Original file line number Diff line number Diff line change
@@ -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 |
)
25 changes: 24 additions & 1 deletion src/lib/compiler/ast_to_instrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 48f10d9

Please sign in to comment.