Merge pull request #1222 from Zokrates/optional-return
Make return statement optional
This commit is contained in:
commit
909c3e0f24
11 changed files with 61 additions and 34 deletions
|
@ -51,5 +51,5 @@ We enforce strict formatting of `.{js,json,ts}` files in CI. This check is not i
|
|||
|
||||
```
|
||||
npm i -g prettier
|
||||
prettier --write ./**/*.{js,ts,json}
|
||||
prettier --write "./**/*.{js,ts,json}"
|
||||
```
|
||||
|
|
1
changelogs/unreleased/1222-dark64
Normal file
1
changelogs/unreleased/1222-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Make return statement optional if no returns are expected
|
|
@ -752,6 +752,12 @@ pub enum TypedExpression<'ast, T> {
|
|||
Int(IntExpression<'ast, T>),
|
||||
}
|
||||
|
||||
impl<'ast, T> TypedExpression<'ast, T> {
|
||||
pub fn empty_tuple() -> TypedExpression<'ast, T> {
|
||||
TypedExpression::Tuple(TupleExpressionInner::Value(vec![]).annotate(TupleType::new(vec![])))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> From<BooleanExpression<'ast, T>> for TypedExpression<'ast, T> {
|
||||
fn from(e: BooleanExpression<'ast, T>) -> TypedExpression<T> {
|
||||
TypedExpression::Boolean(e)
|
||||
|
|
|
@ -895,6 +895,10 @@ impl<S> GType<S> {
|
|||
pub fn uint<W: Into<UBitwidth>>(b: W) -> Self {
|
||||
GType::Uint(b.into())
|
||||
}
|
||||
|
||||
pub fn is_empty_tuple(&self) -> bool {
|
||||
matches!(self, GType::Tuple(ty) if ty.elements.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display + PartialEq + fmt::Debug> Type<'ast, T> {
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
## Functions
|
||||
|
||||
Functions are declared using the `def` keyword. A function's signature has to be explicitly provided.
|
||||
Its arguments are type annotated, just like variables, and, if the function returns a value,
|
||||
the return type must be specified after an arrow `->`.
|
||||
|
||||
A function has to be declared at the top level before it is called.
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/function_declaration.zok}}
|
||||
```
|
||||
|
||||
A function's signature has to be explicitly provided.
|
||||
|
||||
A function can be generic over any number of values of type `u32`.
|
||||
|
||||
```zokrates
|
||||
|
@ -18,4 +20,10 @@ The generic parameters can be provided explicitly, especially when they cannot b
|
|||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/explicit_generic_parameters.zok}}
|
||||
```
|
||||
|
||||
If the return type of a function is the empty tuple `()`, the return type as well as the return statement can be omitted.
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/no_return.zok}}
|
||||
```
|
1
zokrates_cli/examples/book/no_return.zok
Normal file
1
zokrates_cli/examples/book/no_return.zok
Normal file
|
@ -0,0 +1 @@
|
|||
def main() {}
|
|
@ -1,5 +1 @@
|
|||
def foo() {}
|
||||
|
||||
def main() {
|
||||
return;
|
||||
}
|
||||
def main() -> field {}
|
|
@ -1204,10 +1204,16 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
}
|
||||
|
||||
if !found_return {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: "Expected a return statement".to_string(),
|
||||
});
|
||||
match (&*s.output).is_empty_tuple() {
|
||||
true => statements_checked
|
||||
.push(TypedStatement::Return(TypedExpression::empty_tuple())),
|
||||
false => {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: "Expected a return statement".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signature = Some(s);
|
||||
|
@ -1843,11 +1849,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
}
|
||||
.map_err(|e| vec![e])
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
Ok(TupleExpressionInner::Value(vec![])
|
||||
.annotate(TupleType::new(vec![]))
|
||||
.into())
|
||||
})?;
|
||||
.unwrap_or_else(|| Ok(TypedExpression::empty_tuple()))?;
|
||||
|
||||
let res = match TypedExpression::align_to_type(e_checked.clone(), &return_type)
|
||||
.map_err(|e| {
|
||||
|
@ -4735,11 +4737,7 @@ mod tests {
|
|||
10u32.into(),
|
||||
for_statements_checked,
|
||||
),
|
||||
TypedStatement::Return(
|
||||
TupleExpressionInner::Value(vec![])
|
||||
.annotate(TupleType::new(vec![]))
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Return(TypedExpression::empty_tuple()),
|
||||
];
|
||||
|
||||
let foo = Function {
|
||||
|
|
4
zokrates_core_test/tests/tests/no_return.json
Normal file
4
zokrates_core_test/tests/tests/no_return.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/no_return.zok",
|
||||
"tests": []
|
||||
}
|
9
zokrates_core_test/tests/tests/no_return.zok
Normal file
9
zokrates_core_test/tests/tests/no_return.zok
Normal file
|
@ -0,0 +1,9 @@
|
|||
def foo() {
|
||||
return;
|
||||
}
|
||||
|
||||
def bar() {
|
||||
return foo();
|
||||
}
|
||||
|
||||
def main() {}
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/shadowing.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": []
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": ["2", "84"]
|
||||
}
|
||||
}
|
||||
"entry_point": "./tests/tests/shadowing.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": []
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": ["2", "84"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue