mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #13227 from ethereum/functions_taking_calldata_args_should_be_assignable_to_function_pointer_of_same_type
functions taking calldata args should be assignable to function pointers of same type
This commit is contained in:
commit
05c457181e
@ -789,6 +789,18 @@ This includes private, internal and public functions of both contracts and libra
|
||||
functions.
|
||||
External function types, on the other hand, are only compatible with public and external contract
|
||||
functions.
|
||||
|
||||
.. note::
|
||||
External functions with ``calldata`` parameters are incompatible with external function types with ``calldata`` parameters.
|
||||
They are compatible with the corresponding types with ``memory`` parameters instead.
|
||||
For example, there is no function that can be pointed at by a value of type ``function (string calldata) external`` while
|
||||
``function (string memory) external`` can point at both ``function f(string memory) external {}`` and
|
||||
``function g(string calldata) external {}``.
|
||||
This is because for both locations the arguments are passed to the function in the same way.
|
||||
The caller cannot pass its calldata directly to an external function and always ABI-encodes the arguments into memory.
|
||||
Marking the parameters as ``calldata`` only affects the implementation of the external function and is
|
||||
meaningless in a function pointer on the caller's side.
|
||||
|
||||
Libraries are excluded because they require a ``delegatecall`` and use :ref:`a different ABI
|
||||
convention for their selectors <library-selectors>`.
|
||||
Functions declared in interfaces do not have definitions so pointing at them does not make sense either.
|
||||
|
@ -0,0 +1,10 @@
|
||||
contract C {
|
||||
function g(string calldata) external returns (bool) { return true; }
|
||||
|
||||
function main() external returns (bool) {
|
||||
function (string memory) external returns (bool) ptr = this.g;
|
||||
return ptr("testString");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// main() -> true
|
@ -0,0 +1,14 @@
|
||||
contract C {
|
||||
function f(function (string calldata) external) external {}
|
||||
function g(string calldata) external {}
|
||||
|
||||
function main() external {
|
||||
function (string calldata) external ptr = this.g;
|
||||
abi.encodeCall(this.f, (this.g));
|
||||
this.f(this.g);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (161-209): Type function (string memory) external is not implicitly convertible to expected type function (string calldata) external.
|
||||
// TypeError 5407: (242-250): Cannot implicitly convert component at position 0 from "function (string memory) external" to "function (string calldata) external".
|
||||
// TypeError 9553: (268-274): Invalid type for argument in function call. Invalid implicit conversion from function (string memory) external to function (string calldata) external requested.
|
@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function g(string calldata) external {}
|
||||
|
||||
function main() view external {
|
||||
function (string memory) external ptr = this.g;
|
||||
ptr;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function g(bytes calldata b) pure internal {}
|
||||
|
||||
function main() pure external {
|
||||
function (bytes calldata) internal ptr = g;
|
||||
ptr;
|
||||
}
|
||||
}
|
||||
// ----
|
Loading…
Reference in New Issue
Block a user