Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl StatementKind {
}
}

#[derive(Eq, Debug, Clone, Default)]
#[derive(Eq, Debug, Clone)]
pub struct Ident(Located<String>);

impl PartialEq<Ident> for Ident {
Expand Down
9 changes: 6 additions & 3 deletions compiler/noirc_frontend/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,11 +530,14 @@ impl<'a> Parser<'a> {
}

fn location_at_previous_token_end(&self) -> Location {
Location::new(self.span_at_previous_token_end(), self.previous_token_location.file)
let span_at_previous_token_end = Span::from(
self.previous_token_location.span.end()..self.previous_token_location.span.end(),
);
Location::new(span_at_previous_token_end, self.previous_token_location.file)
}

fn span_at_previous_token_end(&self) -> Span {
Span::from(self.previous_token_location.span.end()..self.previous_token_location.span.end())
fn empty_ident_at_previous_token_end(&self) -> Ident {
Ident::new(String::new(), self.location_at_previous_token_end())
}

fn expected_identifier(&mut self) {
Expand Down
6 changes: 4 additions & 2 deletions compiler/noirc_frontend/src/parser/parser/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Parser<'_> {
let Some(name) = self.eat_ident() else {
self.expected_identifier();
return self.empty_enum(
Ident::default(),
self.empty_ident_at_previous_token_end(),
attributes,
visibility,
Vec::new(),
Expand Down Expand Up @@ -119,6 +119,8 @@ impl Parser<'_> {

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use crate::{
ast::{IntegerBitSize, NoirEnumeration, UnresolvedGeneric, UnresolvedTypeData},
parse_program_with_dummy_file,
Expand Down Expand Up @@ -258,6 +260,6 @@ mod tests {

assert_eq!(errors.len(), 1);
let error = &errors[0];
assert_eq!(error.to_string(), "Expected an identifier but found '42'");
assert_snapshot!(error.to_string(), @"Expected an identifier but found '42'");
}
}
13 changes: 7 additions & 6 deletions compiler/noirc_frontend/src/parser/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@
/// = bool
/// | int
/// | str
/// | rawstr

Check warning on line 707 in compiler/noirc_frontend/src/parser/parser/expression.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (rawstr)
/// | fmtstr
/// | QuoteExpression
/// | ArrayExpression
Expand Down Expand Up @@ -1015,6 +1015,7 @@

#[cfg(test)]
mod tests {
use insta::assert_snapshot;
use strum::IntoEnumIterator;

use crate::{
Expand Down Expand Up @@ -1281,7 +1282,7 @@
let mut parser = Parser::for_str_with_dummy_file(&src);
parser.parse_expression();
let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected an expression but found end of input");
assert_snapshot!(error.to_string(), @"Expected an expression but found end of input");
}

#[test]
Expand Down Expand Up @@ -1653,7 +1654,7 @@
let expr = parser.parse_expression_or_error();

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a ':' but found '='");
assert_snapshot!(error.to_string(), @"Expected a ':' but found '='");

let ExpressionKind::Constructor(mut constructor) = expr.kind else {
panic!("Expected constructor");
Expand Down Expand Up @@ -1681,7 +1682,7 @@
let expr = parser.parse_expression_or_error();

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a ':' but found '::'");
assert_snapshot!(error.to_string(), @"Expected a ':' but found '::'");

let ExpressionKind::Constructor(mut constructor) = expr.kind else {
panic!("Expected constructor");
Expand Down Expand Up @@ -1719,7 +1720,7 @@
assert_eq!(expr.to_string(), "1");

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected an identifier but found '2'");
assert_snapshot!(error.to_string(), @"Expected an identifier but found '2'");
}

#[test]
Expand Down Expand Up @@ -1747,7 +1748,7 @@
assert_eq!(expr.to_string(), "2");

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected an identifier but found '2'");
assert_snapshot!(error.to_string(), @"Expected an identifier but found '2'");
}

#[test]
Expand Down Expand Up @@ -1821,7 +1822,7 @@
let mut parser = Parser::for_str_with_dummy_file(&src);
parser.parse_expression();
let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a type but found end of input");
assert_snapshot!(error.to_string(), @"Expected a type but found end of input");
}

#[test]
Expand Down
47 changes: 35 additions & 12 deletions compiler/noirc_frontend/src/parser/parser/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,17 @@ impl Parser<'_> {
allow_optional_body: bool,
allow_self: bool,
) -> FunctionDefinitionWithOptionalBody {
let Some(name) = self.eat_ident() else {
let name = if let Some(name) = self.eat_ident() {
name
} else if self.at(Token::LeftParen) || self.at(Token::Less) {
// If it's `fn (...` or `fn <...` we assume the user missed the function name but a function
// definition follows. This can happen if the user is currently renaming a function by first
// erasing the name.
self.expected_identifier();
return empty_function(self.previous_token_location);
self.empty_ident_at_previous_token_end()
} else {
self.expected_identifier();
return empty_function(self.location_at_previous_token_end());
};

let generics = self.parse_generics_allowing_trait_bounds();
Expand Down Expand Up @@ -320,15 +328,14 @@ impl Parser<'_> {
}

fn empty_function(location: Location) -> FunctionDefinitionWithOptionalBody {
let span = Span::from(location.span.end()..location.span.end());
FunctionDefinitionWithOptionalBody {
name: Ident::default(),
name: Ident::new(String::new(), location),
generics: Vec::new(),
parameters: Vec::new(),
body: None,
location: Location::new(span, location.file),
location,
where_clause: Vec::new(),
return_type: FunctionReturnType::Default(Location::new(span, location.file)),
return_type: FunctionReturnType::Default(location),
return_visibility: Visibility::Private,
}
}
Expand All @@ -339,6 +346,8 @@ fn empty_body() -> BlockExpression {

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use crate::{
ast::{
ExpressionKind, IntegerBitSize, ItemVisibility, NoirFunction, StatementKind,
Expand Down Expand Up @@ -499,7 +508,7 @@ mod tests {
assert_eq!(noir_function.parameters().len(), 1);

let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a pattern but found '1'");
assert_snapshot!(error.to_string(), @"Expected a pattern but found '1'");
}

#[test]
Expand Down Expand Up @@ -535,7 +544,7 @@ mod tests {
assert_eq!(noir_function.parameters().len(), 2);

let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a type but found ','");
assert_snapshot!(error.to_string(), @"Expected a type but found ','");
}

#[test]
Expand Down Expand Up @@ -568,7 +577,7 @@ mod tests {
let (src, span) = get_source_with_error_span(src);
let (mut module, errors) = parse_program_with_dummy_file(&src);
let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a type but found 'mut'");
assert_snapshot!(error.to_string(), @"Expected a type but found 'mut'");

assert_eq!(module.items.len(), 1);
let item = module.items.remove(0);
Expand Down Expand Up @@ -653,7 +662,7 @@ mod tests {
let _ = parser.parse_program();

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Unexpected 'struct', expected one of 'where', '{', '->'");
assert_snapshot!(error.to_string(), @"Unexpected 'struct', expected one of 'where', '{', '->'");
}

#[test]
Expand All @@ -667,7 +676,7 @@ mod tests {
let _ = parser.parse_program();

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Unexpected 'struct', expected one of 'where', '{'");
assert_snapshot!(error.to_string(), @"Unexpected 'struct', expected one of 'where', '{'");
}

#[test]
Expand All @@ -681,6 +690,20 @@ mod tests {
let _ = parser.parse_program();

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a '{' but found 'struct'");
assert_snapshot!(error.to_string(), @"Expected a '{' but found 'struct'");
}

#[test]
fn errors_on_missing_function_name() {
let src = "
fn () {}
^
";
let (src, span) = get_source_with_error_span(src);
let mut parser = Parser::for_str_with_dummy_file(&src);
let _ = parser.parse_program();

let error = get_single_error(&parser.errors, span);
assert_snapshot!(error.to_string(), @"Expected an identifier but found '('");
}
}
6 changes: 4 additions & 2 deletions compiler/noirc_frontend/src/parser/parser/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ impl Parser<'_> {
let Some(ident) = self.eat_ident() else {
self.eat_semicolon();
let location = self.location_at_previous_token_end();
let ident = self.empty_ident_at_previous_token_end();
return LetStatement {
pattern: ident_to_pattern(Ident::default(), mutable),
pattern: ident_to_pattern(ident, mutable),
r#type: UnresolvedType { typ: UnresolvedTypeData::Unspecified, location },
expression: Expression { kind: ExpressionKind::Error, location },
attributes,
Expand Down Expand Up @@ -68,6 +69,7 @@ fn ident_to_pattern(ident: Ident, mutable: bool) -> Pattern {
#[cfg(test)]
mod tests {
use acvm::FieldElement;
use insta::assert_snapshot;

use crate::{
ast::{
Expand Down Expand Up @@ -168,7 +170,7 @@ mod tests {
let (src, span) = get_source_with_error_span(src);
let (_, errors) = parse_program_with_dummy_file(&src);
let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a ';' but found end of input");
assert_snapshot!(error.to_string(), @"Expected a ';' but found end of input");
}

#[test]
Expand Down
17 changes: 9 additions & 8 deletions compiler/noirc_frontend/src/parser/parser/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use noirc_errors::Location;

use crate::{
ast::{
Documented, Expression, ExpressionKind, Ident, ItemVisibility, NoirFunction, NoirTraitImpl,
Documented, Expression, ExpressionKind, ItemVisibility, NoirFunction, NoirTraitImpl,
TraitImplItem, TraitImplItemKind, TypeImpl, UnresolvedGeneric, UnresolvedType,
UnresolvedTypeData,
},
Expand Down Expand Up @@ -156,10 +156,9 @@ impl Parser<'_> {
self.expected_identifier();
self.eat_semicolons();
let location = self.location_at_previous_token_end();
return Some(TraitImplItemKind::Type {
name: Ident::default(),
alias: UnresolvedType { typ: UnresolvedTypeData::Error, location },
});
let name = self.empty_ident_at_previous_token_end();
let alias = UnresolvedType { typ: UnresolvedTypeData::Error, location };
return Some(TraitImplItemKind::Type { name, alias });
};

let alias = if self.eat_assign() {
Expand All @@ -184,7 +183,7 @@ impl Parser<'_> {
Some(name) => name,
None => {
self.expected_identifier();
Ident::default()
self.empty_ident_at_previous_token_end()
}
};

Expand Down Expand Up @@ -235,6 +234,8 @@ impl Parser<'_> {

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use crate::{
ast::{
ItemVisibility, NoirTraitImpl, Pattern, TraitImplItemKind, TypeImpl, UnresolvedTypeData,
Expand Down Expand Up @@ -549,7 +550,7 @@ mod tests {
assert_eq!(type_impl.methods.len(), 1);

let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a function but found 'hello'");
assert_snapshot!(error.to_string(), @"Expected a function but found 'hello'");
}

#[test]
Expand All @@ -569,7 +570,7 @@ mod tests {
assert_eq!(trait_imp.items.len(), 1);

let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a trait impl item but found 'hello'");
assert_snapshot!(error.to_string(), @"Expected a trait impl item but found 'hello'");
}

#[test]
Expand Down
6 changes: 4 additions & 2 deletions compiler/noirc_frontend/src/parser/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ impl<'a> Parser<'a> {

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use crate::{
parse_program_with_dummy_file,
parser::{
Expand All @@ -279,7 +281,7 @@ mod tests {
let (module, errors) = parse_program_with_dummy_file(&src);
assert_eq!(module.items.len(), 2);
let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected an item but found 'hello'");
assert_snapshot!(error.to_string(), @"Expected an item but found 'hello'");
}

#[test]
Expand All @@ -292,7 +294,7 @@ mod tests {
let (module, errors) = parse_program_with_dummy_file(&src);
assert_eq!(module.items.len(), 1);
let error = get_single_error(&errors, span);
assert_eq!(error.to_string(), "Expected a '}' but found end of input");
assert_snapshot!(error.to_string(), @"Expected a '}' but found end of input");
}

#[test]
Expand Down
8 changes: 5 additions & 3 deletions compiler/noirc_frontend/src/parser/parser/item_visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl Parser<'_> {

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use crate::{
ast::ItemVisibility,
parser::{
Expand Down Expand Up @@ -73,7 +75,7 @@ mod tests {
let visibility = parser.parse_item_visibility();
assert_eq!(visibility, ItemVisibility::Public);
let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a 'crate' but found end of input");
assert_snapshot!(error.to_string(), @"Expected a 'crate' but found end of input");
}

#[test]
Expand All @@ -87,7 +89,7 @@ mod tests {
let visibility = parser.parse_item_visibility();
assert_eq!(visibility, ItemVisibility::Public);
let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a 'crate' but found 'hello'");
assert_snapshot!(error.to_string(), @"Expected a 'crate' but found 'hello'");
}
#[test]
fn parses_public_visibility_missing_paren_after_pub_crate() {
Expand All @@ -100,7 +102,7 @@ mod tests {
let visibility = parser.parse_item_visibility();
assert_eq!(visibility, ItemVisibility::PublicCrate);
let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a ')' but found end of input");
assert_snapshot!(error.to_string(), @"Expected a ')' but found end of input");
}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/parser/parser/module.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use noirc_errors::Location;

use crate::{
ast::{Ident, ItemVisibility, ModuleDeclaration},
ast::{ItemVisibility, ModuleDeclaration},
parser::{ItemKind, ParsedSubModule},
token::{Attribute, Token},
};
Expand All @@ -23,7 +23,7 @@ impl Parser<'_> {
self.expected_identifier();
return ItemKind::ModuleDecl(ModuleDeclaration {
visibility,
ident: Ident::default(),
ident: self.empty_ident_at_previous_token_end(),
outer_attributes,
has_semicolon: false,
});
Expand Down
Loading
Loading