solidity icon indicating copy to clipboard operation
solidity copied to clipboard

Getters returning structs can not be defined in interfaces

Open axic opened this issue 3 years ago • 6 comments

interface I {
    struct S {
        uint a;
    }

    function s() external returns (S memory);
}

contract C is I {
    S public override s;
}

The function s can not be defined in a way this works. The problem lies in the impossibility to define a working location.

S storage is not allowed in interfaces, but that could be one option:

Error: Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.
 --> struct-interface.sol:6:36:
  |
6 |     function s() external returns (S storage);
  |                                    ^^^^^^^^^

S memory is not allowed by overriding, but that could be equally correct:

Error: Overriding public state variable return types differ.
  --> struct-interface.sol:10:5:
   |
10 |     S public override s;
   |     ^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
 --> struct-interface.sol:6:5:
  |
6 |     function s() external returns (S memory);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

axic avatar Aug 20 '21 09:08 axic

Oops, forgot that struct getters return the members, and not the struct itself. That is super unintuitive.

axic avatar Aug 20 '21 09:08 axic

Oops, forgot that struct getters return the members, and not the struct itself. That is super unintuitive.

Don't forget that if the struct has arrays those are ignored.

leonardoalt avatar Aug 20 '21 09:08 leonardoalt

Error: Overriding public state variable return types differ.
  --> struct-interface.sol:10:5:
   |
10 |     S public override s;
   |     ^^^^^^^^^^^^^^^^^^^

Could also consider displaying the return types in this error.

axic avatar Aug 20 '21 09:08 axic

Oops, forgot that struct getters return the members, and not the struct itself. That is super unintuitive.

Can we change that at some point :-)?

ekpyron avatar Aug 20 '21 13:08 ekpyron

Even weirder that this goes only one level deep. You can have a getter returning a struct if it's nested inside another struct.

For example this compiles just fine and both the function and the getter return S:

interface I {
    struct S {
        uint a;
    }
    struct WrappedS {
        S s;
    }

    function s() external returns (S memory);
}

contract C is I {
    WrappedS public override s;
}

Anyway, you should update issue the description to say what we want to do about it. Do we want to make getters return structs instead of tuples (breaking change I guess?). Or just make the message more explicit?

cameel avatar Aug 20 '21 17:08 cameel

@axic How to write Interface for such view function. What should be data type

abhijitgawai avatar Jul 28 '22 12:07 abhijitgawai

This issue has been marked as stale due to inactivity for the last 90 days. It will be automatically closed in 7 days.

github-actions[bot] avatar Mar 21 '23 12:03 github-actions[bot]

Hi everyone! This issue has been automatically closed due to inactivity. If you think this issue is still relevant in the latest Solidity version and you have something to contribute, feel free to reopen. However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the forum instead.

github-actions[bot] avatar Mar 28 '23 12:03 github-actions[bot]