Skip to content

Commit

Permalink
Merge 244ec08 into 22771e7
Browse files Browse the repository at this point in the history
  • Loading branch information
cburgdorf authored Apr 23, 2021
2 parents 22771e7 + 244ec08 commit 009fe76
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 6 deletions.
21 changes: 15 additions & 6 deletions analyzer/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,26 @@ use fe_parser::node::Span;
/// Errors for things that may arise in a valid Fe AST.
#[derive(Debug, PartialEq)]
pub enum ErrorKind {
AlreadyDefined,
BreakWithoutLoop,
CannotMove,
CircularDependency,
ContinueWithoutLoop,
EventInvocationExpected,
KeyWordArgsRequired,
MissingEventDefinition,
MissingReturn,
MoreThanThreeIndexedParams,
NotCallable,
NotSubscriptable,
NumericCapacityMismatch,
NumericLiteralExpected,
SignedExponentNotAllowed,
StringCapacityMismatch,
TypeError,
UndefinedValue,
UnexpectedReturn,
TypeError,
CannotMove,
NotCallable,
NumericLiteralExpected,
MoreThanThreeIndexedParams,
WrongNumberOfParams,
AlreadyDefined,
}

#[derive(Debug, PartialEq)]
Expand All @@ -44,6 +45,14 @@ impl SemanticError {
}
}

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

/// Create a new error with kind `ContinueWithoutLoop`
pub fn continue_without_loop() -> Self {
SemanticError {
Expand Down
9 changes: 9 additions & 0 deletions analyzer/src/traversal/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,13 +713,18 @@ fn expr_call_type_attribute(
args: &Node<Vec<Node<fe::CallArg>>>,
) -> Result<ExpressionAttributes, SemanticError> {
let arg_attributes = expr_call_args(Rc::clone(&scope), context, args)?;
let contract_name = scope.borrow().contract_scope().borrow().name.clone();

match (typ, ContractTypeMethod::from_str(func_name)) {
(Type::Contract(contract), Ok(ContractTypeMethod::Create2)) => {
if arg_attributes.len() != 2 {
return Err(SemanticError::wrong_number_of_params());
}

if contract_name == contract.name {
return Err(SemanticError::circular_dependency());
}

if matches!(
(&arg_attributes[0].typ, &arg_attributes[1].typ),
(Type::Base(Base::Numeric(_)), Type::Base(Base::Numeric(_)))
Expand All @@ -743,6 +748,10 @@ fn expr_call_type_attribute(
return Err(SemanticError::wrong_number_of_params());
}

if contract_name == contract.name {
return Err(SemanticError::circular_dependency());
}

if matches!(&arg_attributes[0].typ, Type::Base(Base::Numeric(_))) {
scope
.borrow()
Expand Down
2 changes: 2 additions & 0 deletions compiler/tests/compile_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use std::fs;
case("call_undefined_function_on_external_contract.fe", "UndefinedValue"),
case("call_undefined_function_on_memory_struct.fe", "UndefinedValue"),
case("call_undefined_function_on_storage_struct.fe", "UndefinedValue"),
case("circular_dependency_create.fe", "CircularDependency"),
case("circular_dependency_create2.fe", "CircularDependency"),
case("continue_without_loop_2.fe", "ContinueWithoutLoop"),
case("continue_without_loop.fe", "ContinueWithoutLoop"),
case("duplicate_contract_in_module.fe", "AlreadyDefined"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
contract Foo:
pub def bar() -> address:
foo: Foo = Foo.create(0)

return address(foo)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
contract Foo:
pub def bar() -> address:
foo: Foo = Foo.create2(2, 0)

return address(foo)
12 changes: 12 additions & 0 deletions newsfragments/362.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Properly reject code that creates a circular dependency when using `create` or `create2`.

Example, the follwing code is now rightfully rejected because it tries to create an
instance of `Foo` from within the `Foo` contract itself.

```
contract Foo:
pub def bar()->address:
foo:Foo=Foo.create(0)
return address(foo)
```

0 comments on commit 009fe76

Please sign in to comment.