Skip to content

Commit

Permalink
fix: check the argument count of generic types (#970)
Browse files Browse the repository at this point in the history
Check the argument count of generic types
  • Loading branch information
jfecher authored Mar 9, 2023
1 parent e31f41f commit 2688dc4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
19 changes: 18 additions & 1 deletion crates/noirc_frontend/src/hir/resolution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub use noirc_errors::Span;
use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic};
use thiserror::Error;

use crate::{Ident, Type};
use crate::{Ident, Shared, StructType, Type};

#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum ResolverError {
Expand Down Expand Up @@ -50,6 +50,13 @@ pub enum ResolverError {
NonStructWithGenerics { span: Span },
#[error("Cannot apply generics on Self type")]
GenericsOnSelfType { span: Span },
#[error("Incorrect amount of arguments to generic type constructor")]
IncorrectGenericCount {
span: Span,
struct_type: Shared<StructType>,
actual: usize,
expected: usize,
},
}

impl ResolverError {
Expand Down Expand Up @@ -235,6 +242,16 @@ impl From<ResolverError> for Diagnostic {
"Use an explicit type name or apply the generics at the start of the impl instead".into(),
span,
),
ResolverError::IncorrectGenericCount { span, struct_type, actual, expected } => {
let expected_plural = if expected == 1 { "" } else { "s" };
let actual_plural = if actual == 1 { "is" } else { "are" };

Diagnostic::simple_error(
format!("The struct type {} has {expected} generic{expected_plural} but {actual} {actual_plural} given here", struct_type.borrow()),
"Incorrect number of generic arguments".into(),
span,
)
}
}
}
}
17 changes: 16 additions & 1 deletion crates/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,24 @@ impl<'a> Resolver<'a> {
}
}

let span = path.span();
match self.lookup_struct_or_error(path) {
Some(struct_type) => {
let args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables));
let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables));
let expected_generic_count = struct_type.borrow().generics.len();

if args.len() != expected_generic_count {
self.push_err(ResolverError::IncorrectGenericCount {
span,
struct_type: struct_type.clone(),
actual: args.len(),
expected: expected_generic_count,
});

// Fix the generic count so we can continue typechecking
args.resize_with(expected_generic_count, || self.interner.next_type_variable())
}

Type::Struct(struct_type, args)
}
None => Type::Error,
Expand Down

0 comments on commit 2688dc4

Please sign in to comment.