Skip to content

Commit

Permalink
Make sure that type parameters clash with struct names
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkdp committed May 15, 2024
1 parent a433310 commit 26cad48
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
14 changes: 9 additions & 5 deletions numbat/src/name_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,29 @@ pub struct Namespace {
}

impl Namespace {
pub fn add_allow_override(
pub fn add_identifier_allow_override(
&mut self,
name: String,
span: Span,
item_type: String,
) -> Result<(), NameResolutionError> {
self.add_inner(name, span, item_type, true)
self.add_impl(name, span, item_type, true)
}

pub fn add(
pub fn add_identifier(
&mut self,
name: String,
span: Span,
item_type: String,
) -> Result<(), NameResolutionError> {
self.add_inner(name, span, item_type, false)
self.add_impl(name, span, item_type, false)
}

fn add_inner(
pub fn has_identifier(&self, name: &str) -> bool {
self.seen.contains_key(name)
}

fn add_impl(
&mut self,
name: String,
span: Span,
Expand Down
30 changes: 24 additions & 6 deletions numbat/src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,7 @@ impl TypeChecker {
self.identifiers
.insert(name.clone(), (type_deduced.clone(), Some(*identifier_span)));

self.value_namespace.add_allow_override(
self.value_namespace.add_identifier_allow_override(
name.clone(),
*identifier_span,
"constant".to_owned(),
Expand Down Expand Up @@ -1459,13 +1459,13 @@ impl TypeChecker {
return_type_annotation,
} => {
if body.is_none() {
self.value_namespace.add(
self.value_namespace.add_identifier(
function_name.clone(),
*function_name_span,
"foreign function".to_owned(),
)?;
} else {
self.value_namespace.add_allow_override(
self.value_namespace.add_identifier_allow_override(
function_name.clone(),
*function_name_span,
"function".to_owned(),
Expand All @@ -1477,6 +1477,13 @@ impl TypeChecker {
let mut type_parameters = type_parameters.clone();

for (span, type_parameter) in &type_parameters {
if typechecker_fn.type_namespace.has_identifier(type_parameter) {
return Err(TypeCheckError::TypeParameterNameClash(
*span,
type_parameter.clone(),
));
}

match typechecker_fn.registry.add_base_dimension(type_parameter) {
Err(RegistryError::EntryExists(name)) => {
return Err(TypeCheckError::TypeParameterNameClash(*span, name))
Expand Down Expand Up @@ -1665,8 +1672,11 @@ impl TypeChecker {
)
}
ast::Statement::DefineDimension(name_span, name, dexprs) => {
self.type_namespace
.add(name.clone(), *name_span, "dimension".to_owned())?;
self.type_namespace.add_identifier(
name.clone(),
*name_span,
"dimension".to_owned(),
)?;

if let Some(dexpr) = dexprs.first() {
self.registry
Expand Down Expand Up @@ -1780,7 +1790,7 @@ impl TypeChecker {
struct_name,
fields,
} => {
self.type_namespace.add(
self.type_namespace.add_identifier(
struct_name.clone(),
*struct_name_span,
"struct".to_owned(),
Expand Down Expand Up @@ -2171,6 +2181,14 @@ mod tests {
"),
TypeCheckError::TypeParameterNameClash(_, name) if name == "Existing"
));

assert!(matches!(
get_typecheck_error("
struct Existing {}
fn f<Existing>(x: Existing) = 1
"),
TypeCheckError::TypeParameterNameClash(_, name) if name == "Existing"
));
}

#[test]
Expand Down

0 comments on commit 26cad48

Please sign in to comment.