Env: hardhat
Compiler: 0.7.4
Try to compile this code with 0.7.4 .
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
struct Task {
address[] actions;
}
struct TaskReceipt {
uint256 index;
Task[] tasks;
}
library GelatoTaskReceipt {
function task(TaskReceipt calldata _taskReceipt)
internal
pure
returns (Task memory)
{
return _taskReceipt.tasks[_taskReceipt.index];
}
}
contract Example {
using GelatoTaskReceipt for TaskReceipt;
function exec(TaskReceipt calldata _taskReceipt) external pure {
for (uint256 i = 0; i < _taskReceipt.task().actions.length; i++) {}
}
}
Accessing fields on the Task memory returned from GelatoTaskReceipt.task seems to be the issue.
for (uint256 i = 0; i < _taskReceipt.task().actions.length; i++) {}
InternalCompilerError: Internal compiler error (/Users/distiller/project/libsolidity/codegen/CompilerUtils.cpp:1057)
The problem seems to go away if you use memory data location instead.
In a previous compiler version (e.g. 0.6.12) using calldata for the same code did compile without error by the way.
The bound function seems to be the issue.
The bound function seems to be the issue.
bound function and calldata. This might be unrelated but I reported a different bug for solc 0.6.9 that also had to do with bound function and calldata before: https://github.com/ethereum/solidity/issues/9172
Yeah, looks like it's both. Below is the smallest repro I could find. It stops happening if I change the location to memory, remove using or use a type different than a struct.
It works in 0.6.9. In all the later versions it triggers an ICE.
pragma experimental ABIEncoderV2;
struct S {
uint x;
}
library L {
function f(S calldata) internal pure {}
}
contract C {
using L for S;
function run(S calldata _s) external pure {
_s.f();
}
}
Internal compiler error during compilation:
/solidity/libsolidity/codegen/CompilerUtils.cpp(1055): Throw in function void solidity::frontend::CompilerUtils::convertType(const solidity::frontend::Type&, const solidity::frontend::Type&, bool, bool, bool)
Dynamic exception type: boost::wrapexcept<solidity::langutil::InternalCompilerError>
std::exception::what:
[solidity::util::tag_comment*] =
md5-1e41b74203d5a26f66b36e02a9a59e77
Internal compiler error during compilation:
/solidity/libsolidity/codegen/CompilerUtils.cpp(1024): Throw in function void solidity::frontend::CompilerUtils::convertType(const solidity::frontend::Type&, const solidity::frontend::Type&, bool, bool, bool)
Dynamic exception type: boost::wrapexcept
std::exception::what: Invalid conversion to calldata type.
[solidity::util::tag_comment*] = Invalid conversion to calldata type.
```
The example from the issue description works on 0.6.8 and fails in the same way since 0.6.10. On 0.6.9 it triggers UnimplementedFeatureError because the struct contains a dynamic array.