Add test for duplicate variant check

This commit is contained in:
Greg Shuflin 2021-10-29 00:48:44 -07:00
parent 30fbc9a721
commit cec0f35fc3
2 changed files with 46 additions and 2 deletions

View File

@ -1,4 +1,4 @@
use std::collections::{hash_map::Entry, HashMap};
use std::collections::{hash_map::Entry, HashMap, HashSet};
use std::fmt;
use std::rc::Rc;
@ -85,6 +85,10 @@ pub enum SymbolError {
prev_name: Fqsn,
location: Location,
},
DuplicateVariant {
type_fqsn: Fqsn,
name: String,
},
DuplicateRecord {
type_name: Fqsn,
location: Location,
@ -486,6 +490,30 @@ impl<'a> SymbolTableRunner<'a> {
location: Location,
scope_stack: &mut Vec<Scope>,
) -> Vec<SymbolError> {
let type_fqsn = Fqsn::from_scope_stack(scope_stack, type_name.name.clone());
let TypeBody(variants) = type_body;
let mut duplicates = HashSet::new();
let mut dup_errors = vec![];
for variant in variants {
if duplicates.contains(&variant.name) {
dup_errors.push(SymbolError::DuplicateVariant {
type_fqsn: type_fqsn.clone(),
name: variant.name.as_ref().to_string()
})
}
duplicates.insert(variant.name.clone());
}
if !dup_errors.is_empty() {
return dup_errors;
}
let mut member_errors = vec![];
let mut errors = vec![];
@ -501,7 +529,6 @@ impl<'a> SymbolTableRunner<'a> {
};
};
let TypeBody(variants) = type_body;
let new_scope = Scope::Name(type_name.name.clone());
scope_stack.push(new_scope);

View File

@ -89,6 +89,23 @@ fn no_type_definition_duplicates() {
}
}
#[test]
fn no_variant_duplicates() {
let source = r#"
type Panda = FoolsGold | Kappa(i32) | Remix | Kappa | Thursday | Remix
"#;
let (_, output) = add_symbols(source);
let errs = output.unwrap_err();
assert_eq!(errs.len(), 2);
assert_matches!(&errs[0], SymbolError::DuplicateVariant {
type_fqsn, name } if *type_fqsn == Fqsn::from_strs(&["Panda"]) &&
name == "Kappa");
assert_matches!(&errs[1], SymbolError::DuplicateVariant {
type_fqsn, name } if *type_fqsn == Fqsn::from_strs(&["Panda"]) &&
name == "Remix");
}
#[test]
fn no_variable_definition_duplicates_in_function() {
let source = r#"