diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 6be22bdea24..f1bfbcedc27 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -1030,6 +1030,15 @@ pub fn collect_function( interner.register_function(func_id, &function.def); } + if is_entry_point_function { + if let Some(generic) = function.def.generics.first() { + let name = name.to_string(); + let location = generic.location(); + let error = DefCollectorErrorKind::EntryPointWithGenerics { name, location }; + errors.push(error.into()); + } + } + if !is_test && !is_fuzzing_harness && !is_entry_point_function diff --git a/compiler/noirc_frontend/src/hir/def_collector/errors.rs b/compiler/noirc_frontend/src/hir/def_collector/errors.rs index 216a323572f..dc693046719 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/errors.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/errors.rs @@ -79,6 +79,8 @@ pub enum DefCollectorErrorKind { TestOnlyFailWithWithoutParameters { location: Location }, #[error("The `#[fuzz]` attribute may only be used on functions with parameters")] FuzzingHarnessWithoutParameters { location: Location }, + #[error("`{name}` entry-point function is not allowed to have generic parameters")] + EntryPointWithGenerics { name: String, location: Location }, } impl DefCollectorErrorKind { @@ -112,7 +114,8 @@ impl DefCollectorErrorKind { | DefCollectorErrorKind::TraitMissingMethod { trait_impl_location: location, .. } | DefCollectorErrorKind::ForeignImpl { location, .. } | DefCollectorErrorKind::TestOnlyFailWithWithoutParameters { location } - | DefCollectorErrorKind::FuzzingHarnessWithoutParameters { location } => *location, + | DefCollectorErrorKind::FuzzingHarnessWithoutParameters { location } + | DefCollectorErrorKind::EntryPointWithGenerics { location, .. } => *location, DefCollectorErrorKind::NotATrait { not_a_trait_name: path } | DefCollectorErrorKind::TraitNotFound { trait_path: path } => path.location, DefCollectorErrorKind::UnsupportedNumericGenericType( @@ -297,6 +300,11 @@ impl<'a> From<&'a DefCollectorErrorKind> for Diagnostic { String::new(), *location, ), + DefCollectorErrorKind::EntryPointWithGenerics { name, location } => Diagnostic::simple_error( + format!("`{name}` entry-point function is not allowed to have generic parameters"), + String::new(), + *location, + ), } } } diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index f78a2d2efc0..5df60d0ac49 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -1268,16 +1268,18 @@ impl Type { match self { // Type::Error is allowed as usual since it indicates an error was already issued and // we don't need to issue further errors about this likely unresolved type + // TypeVariable and Generic are allowed here too as they can only result from + // generics being declared on the function itself, but we produce a different error in that case. Type::FieldElement | Type::Integer(_, _) | Type::Bool | Type::Unit | Type::Constant(_, _) + | Type::TypeVariable(_) + | Type::NamedGeneric(_) | Type::Error => true, Type::FmtString(_, _) - | Type::TypeVariable(_) - | Type::NamedGeneric(_) | Type::Function(_, _, _, _) | Type::Reference(..) | Type::Forall(_, _) diff --git a/test_programs/compile_failure/main_with_generics/Nargo.toml b/test_programs/compile_failure/main_with_generics/Nargo.toml new file mode 100644 index 00000000000..72d131a2449 --- /dev/null +++ b/test_programs/compile_failure/main_with_generics/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "main_with_generics" +type = "bin" +authors = [""] +compiler_version = ">=0.33.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/main_with_generics/src/main.nr b/test_programs/compile_failure/main_with_generics/src/main.nr new file mode 100644 index 00000000000..1343431eecb --- /dev/null +++ b/test_programs/compile_failure/main_with_generics/src/main.nr @@ -0,0 +1,3 @@ +fn main(x: [Field; F]) { + assert(x[0] != x[1]); +} diff --git a/test_programs/compile_failure/main_with_generics/stderr.txt b/test_programs/compile_failure/main_with_generics/stderr.txt new file mode 100644 index 00000000000..4fcada7b909 --- /dev/null +++ b/test_programs/compile_failure/main_with_generics/stderr.txt @@ -0,0 +1,8 @@ +error: `main` entry-point function is not allowed to have generic parameters + ┌─ src/main.nr:1:13 + │ +1 │ fn main(x: [Field; F]) { + │ ------ + │ + +Aborting due to 1 previous error