Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/noirc_frontend/src/parser/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ pub enum ParserErrorReason {
LogicalAnd,
#[error("Trait bounds are not allowed here")]
TraitBoundsNotAllowedHere,
#[error("Missing type for associated constant")]
MissingTypeForAssociatedConstant,
}

/// Represents a parsing error, or a parsing error in the making.
Expand Down Expand Up @@ -294,6 +296,11 @@ impl<'a> From<&'a ParserError> for Diagnostic {
.to_string();
Diagnostic::simple_error(primary, secondary, error.location)
}
ParserErrorReason::MissingTypeForAssociatedConstant => Diagnostic::simple_error(
"Missing type for associated constant".to_string(),
"Provide a type for the associated constant: `: u32`".to_string(),
error.location,
),
other => {
Diagnostic::simple_error(format!("{other}"), String::new(), error.location())
}
Expand Down
17 changes: 16 additions & 1 deletion compiler/noirc_frontend/src/parser/parser/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,15 @@ impl Parser<'_> {
}
};

let typ = self.parse_optional_type_annotation();
let typ = if self.eat_colon() {
self.parse_type_or_error()
} else {
self.push_error(
ParserErrorReason::MissingTypeForAssociatedConstant,
self.previous_token_location,
);
self.unspecified_type_at_previous_token_end()
};

let expr = if self.eat_assign() {
self.parse_expression_or_error()
Expand Down Expand Up @@ -533,6 +541,13 @@ mod tests {
assert_eq!(expr.to_string(), "1");
}

#[test]
fn parse_trait_impl_with_let_missing_type() {
let src = "impl Foo for Field { let x = 1; }";
let (_, errors) = parse_program_with_dummy_file(src);
assert!(!errors.is_empty());
}

#[test]
fn recovers_on_unknown_impl_item() {
let src = "
Expand Down
12 changes: 11 additions & 1 deletion compiler/noirc_frontend/src/parser/parser/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,10 @@ impl Parser<'_> {
let typ = if self.eat_colon() {
self.parse_type_or_error()
} else {
self.expected_token(Token::Colon);
self.push_error(
ParserErrorReason::MissingTypeForAssociatedConstant,
self.previous_token_location,
);
let location = self.location_at_previous_token_end();
UnresolvedType { typ: UnresolvedTypeData::Unspecified, location }
};
Expand Down Expand Up @@ -619,6 +622,13 @@ mod tests {
assert!(!errors.is_empty());
}

#[test]
fn parse_trait_with_constant_missing_type() {
let src = "trait Foo { let x = 1; }";
let (_, errors) = parse_program_with_dummy_file(src);
assert!(!errors.is_empty());
}

#[test]
fn parse_trait_with_type_missing_semicolon() {
let src = "trait Foo { type X }";
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/tests/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1152,13 +1152,13 @@ fn error_on_duplicate_impl_with_associated_constant() {

impl Foo for i32 {
~~~ Previous impl defined here
let Bar = 5;
let Bar: u32 = 5;
}

impl Foo for i32 {
^^^ Impl for type `i32` overlaps with existing impl
~~~ Overlapping impl
let Bar = 6;
let Bar: u32 = 6;
}

fn main() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
}

impl Foo for i32 {
let Bar = 5;
let Bar: u32 = 5;
}

impl Foo for i32 {
let Bar = 6;
let Bar: u32 = 6;
}

fn main() {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8917623676698984893
136060998287146535
4 changes: 2 additions & 2 deletions test_programs/compile_success_empty/serialize_1/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ where
A: Serialize,
B: Serialize,
{
let Size = <A as Serialize>::Size + <B as Serialize>::Size;
let Size: u32 = <A as Serialize>::Size + <B as Serialize>::Size;

fn serialize(self: Self) -> [Field; Self::Size] {
let mut array: [Field; Self::Size] = std::mem::zeroed();
Expand All @@ -31,7 +31,7 @@ impl<T, let N: u32> Serialize for [T; N]
where
T: Serialize,
{
let Size = <T as Serialize>::Size * N;
let Size: u32 = <T as Serialize>::Size * N;

fn serialize(self: Self) -> [Field; Self::Size] {
let mut array: [Field; Self::Size] = std::mem::zeroed();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl<A> Serialize for (A,)
where
A: Serialize,
{
let Size = <A as Serialize>::Size;
let Size: u32 = <A as Serialize>::Size;

fn serialize(self: Self) {
self.0.serialize();
Expand Down
4 changes: 2 additions & 2 deletions test_programs/compile_success_empty/serialize_3/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ where
A: Serialize,
B: Serialize,
{
let Size = <A as Serialize>::Size + <B as Serialize>::Size;
let Size: u32 = <A as Serialize>::Size + <B as Serialize>::Size;

fn serialize(self: Self) -> [Field; Self::Size] {
let _ = self.0.serialize();
Expand All @@ -21,7 +21,7 @@ impl<T, let N: u32> Serialize for [T; N]
where
T: Serialize,
{
let Size = <T as Serialize>::Size * N;
let Size: u32 = <T as Serialize>::Size * N;

fn serialize(self: Self) -> [Field; Self::Size] {
[0; Self::Size]
Expand Down
4 changes: 2 additions & 2 deletions test_programs/compile_success_empty/serialize_4/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ where
A: Serialize,
B: Serialize,
{
let Size = <A as Serialize>::Size + <B as Serialize>::Size;
let Size: u32 = <A as Serialize>::Size + <B as Serialize>::Size;

fn serialize(self: Self) -> [Field; Self::Size] {
let mut array: [Field; Self::Size] = std::mem::zeroed();
Expand All @@ -31,7 +31,7 @@ impl<T, let N: u32> Serialize for [T; N]
where
T: Serialize,
{
let Size = <T as Serialize>::Size * N;
let Size: u32 = <T as Serialize>::Size * N;

fn serialize(self: Self) -> [Field; Self::Size] {
let mut array: [Field; Self::Size] = std::mem::zeroed();
Expand Down
14 changes: 0 additions & 14 deletions tooling/nargo_fmt/src/formatter/trait_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,20 +189,6 @@ pub fn foo ( ) { }
assert_format(src, expected);
}

#[test]
fn format_trait_impl_constant_without_type() {
let src = " mod moo { impl Foo for Bar {
let X =42 ;
} }";
let expected = "mod moo {
impl Foo for Bar {
let X = 42;
}
}
";
assert_format(src, expected);
}

#[test]
fn format_trait_impl_constant_with_type() {
let src = " mod moo { impl Foo for Bar {
Expand Down
Loading