Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use function overloading in libraries #13981

Closed
Sabnock01 opened this issue Feb 17, 2023 · 2 comments
Closed

Can't use function overloading in libraries #13981

Sabnock01 opened this issue Feb 17, 2023 · 2 comments

Comments

@Sabnock01
Copy link
Contributor

Description

I have a library with overloaded functions which builds without error, but when I go to use it in another file, the contract using the library only seems to recognize the first function declared. I have provided the following example to reproduce:

library Cast {
    function i128(uint256 x) internal {...}

    function i128(uint128 x) internal {...}
}

contract Caster {
    using Cast for uint256;
    using Cast for uint128;

    function castNums(uint256 a, uint128 b) public {
        int128 newA = a.i128();
        int128 newB = b.i128();
    }
}

In this example, only the first i128 may be used in the below contract. Use of the second one will give the following compiler error:

Compiler run failed
error[6675]: TypeError: Member "i128" not unique after argument-dependent lookup in type(library Cast).
  --> src/Counter.sol:24:23:
   |
24 |         int128 newB = Cast.i128(b);
   |                       ^^^^^^^^^

This is still the case if the using ... for ... syntax is removed and / or if the Cast.i128(...) syntax is used.
It is also true if the function visibility is changed from internal to external.

Is this desired behavior? It seems to me this should be doable since the function signatures are the same.

Environment

  • Compiler version: 0.8.18
  • Target EVM version (as per compiler settings):
  • Framework/IDE (e.g. Truffle or Remix): Foundry
  • EVM execution environment / backend / blockchain client: Infura
  • Operating system: Ubuntu 20.04

Steps to Reproduce

Simply running forge build on the snippet above should be enough. Moreover I even get a syntax error in VS Code on the same line.

@cameel
Copy link
Member

cameel commented Feb 17, 2023

This is not limited to libraries. All functions in Solidity work this way. The first call works because there's only one overload that can take uint256. The second one is ambiguous because uint128 is also implicitly convertible to uint256 so both candidates are viable. We already have an issue about the compiler failing to explain that clearly: #9607.

The compiler could resolve the ambiguity by choosing the more fitting overload, it just does not do that yet. That's covered by #1256.

You should also be able to work around it by attaching only a specific overload for your type with the using {L.f} for T syntax but infortunately this is not yet implemented either: #3556.

Overall, this is a valid report and the behavior should be changed, but we already have issues covering all these problems so I'm closing this one as a duplicate.

@cameel cameel closed this as not planned Won't fix, can't repro, duplicate, stale Feb 17, 2023
@Sabnock01
Copy link
Contributor Author

Awesome, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants