Skip to content

Commit

Permalink
Merge pull request #2523 from AleoHQ/fix/issue-2521
Browse files Browse the repository at this point in the history
[Fix] Function calls must lead with an `Identifier.
  • Loading branch information
d0cd authored Aug 13, 2023
2 parents d654182 + 036776b commit a601ccd
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
6 changes: 6 additions & 0 deletions compiler/parser/src/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

use super::*;

use leo_errors::{ParserError, Result};

use leo_span::{sym, Symbol};

use snarkvm_console::{account::Address, network::Testnet3};

const INT_TYPES: &[Token] = &[
Expand Down Expand Up @@ -444,6 +446,10 @@ impl ParserContext<'_> {
// Eat a core struct constant or core struct function call.
expr = self.parse_associated_access_expression(expr)?;
} else if self.check(&Token::LeftParen) {
// Check that the expression is an identifier.
if !matches!(expr, Expression::Identifier(_)) {
self.emit_err(ParserError::unexpected(expr.to_string(), "an identifier", expr.span()))
}
// Parse a function call that's by itself.
let (arguments, _, span) = self.parse_paren_comma_list(|p| p.parse_expression().map(Some))?;
expr = Expression::Call(CallExpression {
Expand Down
2 changes: 1 addition & 1 deletion compiler/passes/src/code_generation/visit_expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ impl<'a> CodeGenerator<'a> {
// Lookup the function return type.
let function_name = match input.function.borrow() {
Expression::Identifier(identifier) => identifier.name,
_ => unreachable!("Parsing guarantees that all `input.function` is always an identifier."),
_ => unreachable!("Parsing guarantees that a function name is always an identifier."),
};
let return_type = &self.symbol_table.borrow().lookup_fn_symbol(function_name).unwrap().output_type;
match return_type {
Expand Down
4 changes: 3 additions & 1 deletion compiler/passes/src/type_checking/check_expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
}

fn visit_call(&mut self, input: &'a CallExpression, expected: &Self::AdditionalInput) -> Self::Output {
println!("call_expression: {}", input);
println!("input function: {:?}", input.function);
match &*input.function {
// Note that the parser guarantees that `input.function` is always an identifier.
Expression::Identifier(ident) => {
Expand Down Expand Up @@ -514,7 +516,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
None
}
}
_ => unreachable!("Parser guarantees that `input.function` is always an identifier."),
_ => unreachable!("Parsing guarantees that a function name is always an identifier."),
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
namespace: Parse
expectation: Fail
outputs:
- "Error [EPAR0370005]: expected an identifier -- found '100u8'\n --> test:5:16\n |\n 5 | return 100u8(0u8);\n | ^^^^^"
10 changes: 10 additions & 0 deletions tests/tests/parser/functions/function_name_is_not_identifier.leo
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
namespace: Parse
expectation: Fail
*/

program test.aleo {
function x(x: u32, constant y: i32) -> u8 {
return 100u8(0u8);
}
}

0 comments on commit a601ccd

Please sign in to comment.