solidity icon indicating copy to clipboard operation
solidity copied to clipboard

File level functionname shadows functionname in Interface

Open gitpusha opened this issue 4 years ago • 4 comments

Solidity version 0.7.4

image

Should the compiler warn about such name clashes even if one of them is a file-level function and the other one a function declared inside an interface?

gitpusha avatar Oct 29 '20 15:10 gitpusha

The compiler does not warn because MemoryInterface::getUint is external. It is impossible to refer to it just via getUint, you always need a contract type for it.

chriseth avatar Oct 29 '20 15:10 chriseth

But the compiler does warn: This declaration shadows an existing declaration.

This is the file:

pragma solidity 0.7.4;

interface MemoryInterface {
    function getUint(uint256 _id) external returns (uint256);
}

function getUint(uint256 getId, uint256 val) returns (uint256 returnVal) {
    returnVal = getId == 0
        ? val
        : MemoryInterface(getMemoryAddr()).getUint(getId);
}

gitpusha avatar Oct 29 '20 15:10 gitpusha

Ah sorry about that! You can can maybe get around this by moving the function into its own file and importing the file as a module.

chriseth avatar Oct 29 '20 15:10 chriseth

Yep I did that. Fine for now :)

Btw I enjoy this new file-level function feature a lot.

gitpusha avatar Oct 29 '20 15:10 gitpusha

Just ran into it myself. We really need to fix it.

interface I {
    function f(uint) external returns (uint);
}

function f(uint) returns (uint) {}

cameel avatar Mar 23 '23 10:03 cameel

I have a proposed fix witch assumes that the issue is more general and that any declaration inside an interface can not shadow file-level declaration, not only function declaration. However, tests with this fix fails on error_selector_syntax.sol which warns that an error declaration in an Interface shadows a file-level error declaration.

I am not sure whether my approach is wrong or whether the existing test is wrong. For example:

interface I {
        error Er(bool);
}
error Er(bytes4);
contract C1 {
        function g() public pure {
                revert Er(Er.selector);
        }
}
contract C3 is I {
        function g() public pure {
                revert Er(true);
        }
}

Warning: This declaration shadows an existing declaration.
 --> <stdin>:2:2:
  |
2 |     error Er(bool);
  |     ^^^^^^^^^^^^^^^
Note: The shadowed declaration is here:
 --> <stdin>:4:1:
  |
4 | error Er(bytes4);
  | ^^^^^^^^^^^^^^^^^

There are no compilation errors about type conversion when Er() is used, meaning that as expected C1 uses the file-level Er() declaration and C3 is I is using the Er() declaration from I.

Is my approach correct (and error_selector_syntax.sol should be modified)? Is the issue only for functions? Is it about a subset of declarations in an Interface, e.g. only function, struct, enum?

davidBar-On avatar May 27 '23 18:05 davidBar-On