Add test for duplicate variant check
This commit is contained in:
parent
30fbc9a721
commit
cec0f35fc3
@ -1,4 +1,4 @@
|
|||||||
use std::collections::{hash_map::Entry, HashMap};
|
use std::collections::{hash_map::Entry, HashMap, HashSet};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -85,6 +85,10 @@ pub enum SymbolError {
|
|||||||
prev_name: Fqsn,
|
prev_name: Fqsn,
|
||||||
location: Location,
|
location: Location,
|
||||||
},
|
},
|
||||||
|
DuplicateVariant {
|
||||||
|
type_fqsn: Fqsn,
|
||||||
|
name: String,
|
||||||
|
},
|
||||||
DuplicateRecord {
|
DuplicateRecord {
|
||||||
type_name: Fqsn,
|
type_name: Fqsn,
|
||||||
location: Location,
|
location: Location,
|
||||||
@ -486,6 +490,30 @@ impl<'a> SymbolTableRunner<'a> {
|
|||||||
location: Location,
|
location: Location,
|
||||||
scope_stack: &mut Vec<Scope>,
|
scope_stack: &mut Vec<Scope>,
|
||||||
) -> Vec<SymbolError> {
|
) -> 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 member_errors = vec![];
|
||||||
let mut 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());
|
let new_scope = Scope::Name(type_name.name.clone());
|
||||||
scope_stack.push(new_scope);
|
scope_stack.push(new_scope);
|
||||||
|
|
||||||
|
@ -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]
|
#[test]
|
||||||
fn no_variable_definition_duplicates_in_function() {
|
fn no_variable_definition_duplicates_in_function() {
|
||||||
let source = r#"
|
let source = r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user