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

No compiler warning when declaring "same function" with different data location. #10302

Closed
Jaime-Iglesias opened this issue Nov 15, 2020 · 5 comments
Labels

Comments

@Jaime-Iglesias
Copy link
Contributor

Jaime-Iglesias commented Nov 15, 2020

Solidity 0.7.4.

contract Test
    struct Foo {
        uint a;
        uint b;
    }
    
    Foo public _f;
        
    function doStuff() external {
        Foo memory  memFoo = Foo({a: 1,  b: 2});
        foo(memFoo);
        
        Foo storage storagefoo = _f;
        foo(storagefoo); // TypeError: No unique declaration found after argument-dependent lookup.
    }
    
    function foo(Foo memory f) internal {
        f.a = f.a + 1;
    }
    
    function foo(Foo storage f) internal {
        f.a = f.a + 1;
    }
}

If data location is not part of the function selector calculation, why does the compiler allow the above declarations ? Shouldn't it throw some sort of declarationError ? Perhaps it's interpreted as function overloading by the compiler and that's why it doesn't complain until you try to use the last declaration ?
I think it's especially confusing because the compiler will only complain if you try to use the function that has been declared last.

@hrkrshnn
Copy link
Member

The compiler is not complaining because it's an internal function. Even though the selector would be the same, those functions are never part of the ABI.

@Jaime-Iglesias
Copy link
Contributor Author

The compiler is not complaining because it's an internal function. Even though the selector would be the same, those functions are never part of the ABI.

@hrkrshnn Thx for the answer, you are right (totally goofed there) - So, regardless of that, even if they are just two jumps why allow the declaration if the compiler will complain anyway when trying to use both functions ? Does it have a purpose ?

@hrkrshnn
Copy link
Member

why allow the declaration if the compiler will complain anyway when trying to use both functions

Good question.

Interestingly, the following compiles

struct Foo {uint a;}
contract C {
	function f(Foo memory foo) internal {
	}

	function f(Foo storage foo) internal {
	}

	function g() public {
		f(Foo(1));
	}
}

However, we have problems with calling the function which has storage as argument. Maybe this really is a bug.

struct Foo {uint a;}
contract C {
	Foo test;
	function f(Foo memory foo) internal {
	}

	function f(Foo storage foo) internal {
	}

	function g() public {
                // Error: No unique declaration found after argument-dependent lookup.
		f(test);
	}
}

@chriseth
Copy link
Contributor

The overload resolution allows implicit conversions. Ranking direct matches higher has been planned for a long time, but since nobody complained in years, it was not implemented: #1256

@chriseth
Copy link
Contributor

Closing as duplicate, please comment in #1256

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

No branches or pull requests

3 participants