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.