Skip to content

Commit

Permalink
Fix issue where compiler doesn't reject method call on storage struct
Browse files Browse the repository at this point in the history
(cherry picked from commit 2a1cd2aa974570ec86314700ec09feba26d0f6b6)
  • Loading branch information
cburgdorf committed May 2, 2023
1 parent 7054185 commit 40f7a0b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 3 deletions.
5 changes: 2 additions & 3 deletions crates/analyzer/src/traversal/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1654,10 +1654,9 @@ fn expr_call_method(
method: *method,
generic_type: inner,
},
ty => {
_ => {
let method = method.function(context.db()).unwrap();

if let Type::SPtr(inner) = ty {
if let Type::SPtr(inner) = target_attributes.typ.typ(context.db()) {
if matches!(
inner.typ(context.db()),
Type::Struct(_) | Type::Tuple(_) | Type::Array(_)
Expand Down
2 changes: 2 additions & 0 deletions crates/analyzer/tests/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ test_file! { init_call_on_external_contract }
test_file! { call_wrong_return_type }
test_file! { call_duplicate_def }
test_file! { call_call_on_self }

test_file! { call_method_in_storage }
test_file! { call_call_on_external_contract }
test_file! { call_with_pub_fns }
test_file! { abi_encode_u256 }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
source: crates/analyzer/tests/errors.rs
assertion_line: 323
expression: "error_string(&path, test_files::fixture(path))"
---
error: struct functions can only be called on struct in memory
┌─ compile_errors/call_method_in_storage.fe:16:9
16self.bar.get_x()
^^^^^^^^ ----- hint: copy the struct to memory with `.to_mem()`
│ │
this value is in storage


Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
struct Bar {
pub x: u256

pub fn get_x(self) -> u256{
return self.x
}
}

contract Foo {
bar: Bar

pub fn __init__(mut self) {
self.bar = Bar( x: 2 )
}
fn yay(self) {
self.bar.get_x()
}
}
26 changes: 26 additions & 0 deletions newsfragments/881.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Fixed a regression where the compiler would not reject a method call on a struct in storage.

E.g. the follwing code should be rejected as it is missing a `to_mem()` call:

```
struct Bar {
pub x: u256
pub fn get_x(self) -> u256{
return self.x
}
}
contract Foo {
bar: Bar
pub fn __init__(mut self) {
self.bar = Bar( x: 2 )
}
fn yay(self) {
self.bar.get_x()
}
}
```

The compiler will now reject the code and suggest a `to_mem()` before calling`get_x()`.

0 comments on commit 40f7a0b

Please sign in to comment.