Skip to content

Commit

Permalink
Require KWargs for struct initialization
Browse files Browse the repository at this point in the history
Fixes #234
  • Loading branch information
cburgdorf committed Feb 20, 2021
1 parent 27ad463 commit 13d74ef
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 2 deletions.
9 changes: 9 additions & 0 deletions analyzer/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use fe_parser::span::Span;
pub enum ErrorKind {
BreakWithoutLoop,
ContinueWithoutLoop,
KeyWordArgsRequired,
MissingReturn,
NotSubscriptable,
NumericCapacityMismatch,
Expand Down Expand Up @@ -48,6 +49,14 @@ impl SemanticError {
}
}

/// Create a new error with kind `KeyWordArgsRequired`
pub fn kw_args_required() -> Self {
SemanticError {
kind: ErrorKind::KeyWordArgsRequired,
context: vec![],
}
}

/// Create a new error with kind `MissingReturn`
pub fn missing_return() -> Self {
SemanticError {
Expand Down
12 changes: 12 additions & 0 deletions analyzer/src/traversal/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ fn expr_call_struct_constructor(
typ: Struct,
args: &Spanned<Vec<Spanned<fe::CallArg>>>,
) -> Result<ExpressionAttributes, SemanticError> {
validate_are_kw_args(&args.node)?;
let argument_attributes = expr_call_args(Rc::clone(&scope), Rc::clone(&context), args)?;

if typ.get_field_types() != expression_attributes_to_types(argument_attributes) {
Expand Down Expand Up @@ -888,6 +889,17 @@ fn expr_attribute_call_type(
unreachable!()
}

fn validate_are_kw_args(args: &[Spanned<fe::CallArg>]) -> Result<(), SemanticError> {
if args
.iter()
.any(|arg| matches!(arg.node, fe::CallArg::Arg(_)))
{
return Err(SemanticError::kw_args_required());
}

Ok(())
}

fn validate_is_numeric_literal(call_arg: &fe::CallArg) -> Result<String, SemanticError> {
if let fe::CallArg::Arg(fe::Expr::UnaryOperation { operand, op: _ }) = call_arg {
if let fe::Expr::Num(num) = (*operand).node {
Expand Down
1 change: 1 addition & 0 deletions compiler/tests/compile_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use std::fs;
case("type_constructor_from_variable.fe", "NumericLiteralExpected"),
case("needs_mem_copy.fe", "CannotMove"),
case("string_capacity_mismatch.fe", "StringCapacityMismatch"),
case("struct_call_without_kw_args.fe", "KeyWordArgsRequired"),
case("numeric_capacity_mismatch/u8_neg.fe", "NumericCapacityMismatch"),
case("numeric_capacity_mismatch/u8_pos.fe", "NumericCapacityMismatch"),
case("numeric_capacity_mismatch/u16_neg.fe", "NumericCapacityMismatch"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct House:
vacant: bool
price: u256

contract Foo:

pub def bar():
my_house: House = House(true, price=1000000)
4 changes: 2 additions & 2 deletions compiler/tests/fixtures/structs.fe
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ contract Foo:
my_house: House

pub def create_house():
self.my_house = House(1,2,false)
self.my_house = House(price=1, size=2, vacant=false)
assert self.my_house.price == 1
assert self.my_house.size == 2
assert self.my_house.vacant == false
Expand All @@ -25,7 +25,7 @@ contract Foo:


pub def bar() -> u256:
building: House = House(300, 500, true)
building: House = House(price=300, size=500, vacant=true)
assert building.size == 500
assert building.price == 300
assert building.vacant
Expand Down
15 changes: 15 additions & 0 deletions newsfragments/260.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Require structs to be initialized using keyword arguments.

Example:

```
struct House:
vacant: bool
price: u256
```

Previously, `House` could be instantiated as `House(true, 1000000)`.
With this change it is required to be instantiated like `House(vacant=true, price=1000000)`

This ensures property assignment is less prone to get mixed up. It also makes struct
initialization visually stand out more from function calls.

0 comments on commit 13d74ef

Please sign in to comment.