diff --git a/compiler/noirc_frontend/src/elaborator/impls.rs b/compiler/noirc_frontend/src/elaborator/impls.rs index 3b0d5e078ed..bb519ecd27d 100644 --- a/compiler/noirc_frontend/src/elaborator/impls.rs +++ b/compiler/noirc_frontend/src/elaborator/impls.rs @@ -210,7 +210,11 @@ impl Elaborator<'_> { self.declare_methods(self_type, &function_ids); } } else { - self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { location }); + let is_primitive = self_type.is_primitive(); + self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { + location, + is_primitive, + }); } } } diff --git a/compiler/noirc_frontend/src/hir/def_collector/errors.rs b/compiler/noirc_frontend/src/hir/def_collector/errors.rs index 17f8858bc20..ee427644a87 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/errors.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/errors.rs @@ -35,7 +35,7 @@ pub enum DefCollectorErrorKind { #[error("Cannot re-export {item_name} because it has less visibility than this use statement")] CannotReexportItemWithLessVisibility { item_name: Ident, desired_visibility: ItemVisibility }, #[error("Non-struct type used in impl")] - NonStructTypeInImpl { location: Location }, + NonStructTypeInImpl { location: Location, is_primitive: bool }, #[error("Cannot implement trait on a reference type")] ReferenceInTraitImpl { location: Location }, #[error("Impl for type `{typ}` overlaps with existing impl")] @@ -101,7 +101,7 @@ impl DefCollectorErrorKind { } | DefCollectorErrorKind::TestOnAssociatedFunction { location } | DefCollectorErrorKind::ExportOnAssociatedFunction { location } - | DefCollectorErrorKind::NonStructTypeInImpl { location } + | DefCollectorErrorKind::NonStructTypeInImpl { location, .. } | DefCollectorErrorKind::ReferenceInTraitImpl { location } | DefCollectorErrorKind::OverlappingImpl { location, .. } | DefCollectorErrorKind::ModuleAlreadyPartOfCrate { location, .. } @@ -193,11 +193,21 @@ impl<'a> From<&'a DefCollectorErrorKind> for Diagnostic { format!("consider marking {item_name} as {desired_visibility}"), item_name.location()) } - DefCollectorErrorKind::NonStructTypeInImpl { location } => Diagnostic::simple_error( - "Non-struct type used in impl".into(), - "Only struct types may have implementation methods".into(), - *location, - ), + DefCollectorErrorKind::NonStructTypeInImpl { location, is_primitive } =>{ + if *is_primitive { + Diagnostic::simple_error( + "Cannot define inherent `impl` for primitive types".into(), + "Primitive types can only have implementation methods defined in the standard library".into(), + *location, + ) + }else{ + Diagnostic::simple_error( + "Non-struct type used in impl".into(), + "Only struct types may have implementation methods".into(), + *location, + ) + } + } DefCollectorErrorKind::ReferenceInTraitImpl { location } => Diagnostic::simple_error( "Trait impls are not allowed on reference types".into(), "Try using a struct type here instead".into(), diff --git a/compiler/noirc_frontend/src/tests/structs.rs b/compiler/noirc_frontend/src/tests/structs.rs index 954ec55953d..59f01ebe81a 100644 --- a/compiler/noirc_frontend/src/tests/structs.rs +++ b/compiler/noirc_frontend/src/tests/structs.rs @@ -222,8 +222,8 @@ fn errors_on_impl_for_primitive_type_outside_stdlib() { let src = r#" // User code (not stdlib) cannot impl methods on primitive types impl Field { - ^^^^^ Non-struct type used in impl - ~~~~~ Only struct types may have implementation methods + ^^^^^ Cannot define inherent `impl` for primitive types + ~~~~~ Primitive types can only have implementation methods defined in the standard library fn my_method(self) -> Field { self } diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/dep_impl_primitive/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/dep_impl_primitive/execute__tests__stderr.snap index 01f1db44d9f..02599ad1302 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/dep_impl_primitive/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/dep_impl_primitive/execute__tests__stderr.snap @@ -9,11 +9,11 @@ warning: unused import bad_impl │ -------- unused import │ -error: Non-struct type used in impl +error: Cannot define inherent `impl` for primitive types ┌─ test_programs/test_libraries/bad_impl/src/lib.nr:1:6 │ 1 │ impl Field { - │ ----- Only struct types may have implementation methods + │ ----- Primitive types can only have implementation methods defined in the standard library │ error: No method named 'something' found for type 'Field'