0

I have a contract that implements an interface, the contract has a state variable mapping(address => bytes32[]) public usersLists, I defined a getter function signature in the interface for this state variable, but I'm getting the following compiler error:

TypeError: Data location must be "memory" or "calldata" for return parameter in function, but none was given.
  --> interfaces/IPool.sol:42:65:
   |
42 |   function usersLists(address user) external view returns (bytes32[]);
   |                                                                 ^^^^^^^^^

The interface and contract are as follows:

interface IA {
  function usersLists(address user) external view returns (bytes32[]);
}

contract A is IA {
  mapping(address => bytes32[]) public override usersLists;
}

Could someone please help me resolve this issue? It seems to be an issue with the list and not bytes32 as removing [] making it a mapping(address => bytes32) removes the compiler error, but from this answer it should be possible to return bytes32[].

1 Answer 1

1

For dynamic types you need to defined the storage location.

In your case function usersLists(address user) external view returns (bytes32[] memory);

See more information in the Solidity docs: https://docs.soliditylang.org/en/v0.8.10/types.html#data-location

Edit:

The question you linked used an older Solidity version, therefore it was not required there.

Edit 2:

The method in the interface does not correspond to the automatically generated getter for mapping(address => bytes32[]). Solidity automatically adds all "key-lookups" as a parameter to the getter function.

Here an example with the default getter that will return a bytes32 and the custom getter that returns the whole array:

interface IA {
  // Getter that will be generated automatically
  function usersLists(address user, uint256 index) external view returns (bytes32);
  // Custom getter
  function getUsersLists(address user) external view returns (bytes32[] memory);
}

contract A is IA {
  mapping(address => bytes32[]) public override usersLists;

  function getUsersLists(address user) external override view returns (bytes32[] memory) {
        return usersLists[user];
  }
}
2
  • Appreciate the answer, however I have tried adding both memory and calldata and I still get compiler errors, you can verify in Remix using my example interface and contract.
    – MShakeG
    Commented Jan 8, 2022 at 20:30
  • The default getter generated for a mapping to an array is different. I will adjust my answer
    – Richard
    Commented Jan 8, 2022 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.