From 9194d423f5389da8f043c706cd28655e964486da Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Thu, 9 Mar 2023 13:03:03 -0600 Subject: [PATCH] Check the argument count of generic types --- .../src/hir/resolution/errors.rs | 19 ++++++++++++++++++- .../src/hir/resolution/resolver.rs | 17 ++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/crates/noirc_frontend/src/hir/resolution/errors.rs b/crates/noirc_frontend/src/hir/resolution/errors.rs index 155288203d7..330a18072c4 100644 --- a/crates/noirc_frontend/src/hir/resolution/errors.rs +++ b/crates/noirc_frontend/src/hir/resolution/errors.rs @@ -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 { @@ -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, + actual: usize, + expected: usize, + }, } impl ResolverError { @@ -235,6 +242,16 @@ impl From 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, + ) + } } } } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 6b2b095cc64..e5373d58fd0 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -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,