Take the following code:
pragma solidity >=0.8.17;
contract Contract {
function foo(uint256 arg) internal pure returns (uint256) {
return arg;
}
function foo(uint64 arg) internal pure returns (uint64) {
return arg;
}
function ar() external returns (uint64) {
uint64 arg = foo(uint64(1));
return arg;
}
}
It does not compile:
TypeError: No unique declaration found after argument-dependent lookup.
--> contracts/Contract.sol:14:22:
|
14 | uint64 arg = foo(uint64(1));
| ^^^
Note: Candidate:
--> contracts/Contract.sol:5:5:
|
5 | function foo(uint256 arg) internal pure returns (uint256) {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Candidate:
--> contracts/Contract.sol:9:5:
|
9 | function foo(uint64 arg) internal pure returns (uint64) {
| ^ (Relevant source part starts here and spans across multiple lines).
The compiler should have all the information it needs to figure out that it should call foo(uint64)
instead of foo(uint256)
, but it doesn’t do that. However, if I update the first function like this:
function foo(address arg) internal pure returns (address) {
return arg;
}
Then the code compiles just fine. But this is odd. Why does the compiler distinguish address
and uint64
but not uint256
and uint64
? foo(uint256)
has a different function signature from foo(uint64)
:
❯ cast sig "foo(uint256)"
0x2fbebd38
❯ cast sig "foo(uint64)"
0xdecb0da1
I’m not sure if this is a bug or just an intentional limitation of function overloading in Solidity. If the former, I would be happy to open a GitHub issue to track this.