Skip to content

Commit ccd1f28

Browse files
authored
Merge pull request ethereum#9360 from ethereum/rich-function-type
Improve error message when assigning builtin functions
2 parents dc5f7a7 + fa37e69 commit ccd1f28

11 files changed

+45
-13
lines changed

libsolidity/analysis/TypeChecker.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -2171,7 +2171,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
21712171
for (size_t i = 0; i < paramArgMap.size(); ++i)
21722172
{
21732173
solAssert(!!paramArgMap[i], "unmapped parameter");
2174-
if (!type(*paramArgMap[i])->isImplicitlyConvertibleTo(*parameterTypes[i]))
2174+
BoolResult result = type(*paramArgMap[i])->isImplicitlyConvertibleTo(*parameterTypes[i]);
2175+
if (!result)
21752176
{
21762177
auto [errorId, description] = [&]() -> tuple<ErrorId, string> {
21772178
string msg =
@@ -2181,6 +2182,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
21812182
" to " +
21822183
parameterTypes[i]->toString() +
21832184
" requested.";
2185+
if (!result.message().empty())
2186+
msg += " " + result.message();
21842187
if (
21852188
_functionType->kind() == FunctionType::Kind::BareCall ||
21862189
_functionType->kind() == FunctionType::Kind::BareCallCode ||

libsolidity/ast/Types.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -3111,6 +3111,13 @@ BoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const
31113111

31123112
FunctionType const& convertTo = dynamic_cast<FunctionType const&>(_convertTo);
31133113

3114+
// These two checks are duplicated in equalExcludingStateMutability, but are added here for error reporting.
3115+
if (convertTo.bound() != bound())
3116+
return BoolResult::err("Bound functions can not be converted to non-bound functions.");
3117+
3118+
if (convertTo.kind() != kind())
3119+
return BoolResult::err("Special functions can not be converted to function types.");
3120+
31143121
if (!equalExcludingStateMutability(convertTo))
31153122
return false;
31163123

test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ contract Test {
2222
}
2323
}
2424
// ----
25-
// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external.
25+
// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external. Special functions can not be converted to function types.

test/libsolidity/syntaxTests/events/event_library_function.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ contract E {
3030
}
3131
}
3232
// ----
33-
// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested.
34-
// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested.
35-
// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested.
33+
// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions can not be converted to function types.
34+
// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions can not be converted to function types.
35+
// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested. Special functions can not be converted to function types.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
library L {
2+
function foo(uint256 a, uint256 b) internal pure returns (uint256) {
3+
return a + b;
4+
}
5+
}
6+
contract C {
7+
using L for uint256;
8+
9+
function bar() public {
10+
uint256 x;
11+
function (uint256, uint256) internal pure returns (uint256) ptr = x.foo;
12+
}
13+
}
14+
// ----
15+
// TypeError 9574: (209-280): Type function (uint256,uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). Bound functions can not be converted to non-bound functions.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
contract C {
2+
function f() public {
3+
function (uint) view returns (bytes32) _blockhash = blockhash;
4+
}
5+
}
6+
// ----
7+
// TypeError 9574: (42-103): Type function (uint256) view returns (bytes32) is not implicitly convertible to expected type function (uint256) view returns (bytes32). Special functions can not be converted to function types.

test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ contract C {
1010
}
1111
}
1212
// ----
13-
// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) external returns (uint256) requested.
14-
// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256).
13+
// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) external returns (uint256) requested. Special functions can not be converted to function types.
14+
// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256). Special functions can not be converted to function types.

test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ contract test {
33
function(bytes memory) external internal a = fa;
44
}
55
// ----
6-
// TypeError 7407: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external.
6+
// TypeError 7407: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external. Special functions can not be converted to function types.

test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ contract C {
99
}
1010
}
1111
// ----
12-
// TypeError 9574: (218-271): Type function (struct D.s storage pointer,uint256) returns (uint256) is not implicitly convertible to expected type function (struct D.s storage pointer,uint256) returns (uint256).
12+
// TypeError 9574: (218-271): Type function (struct D.s storage pointer,uint256) returns (uint256) is not implicitly convertible to expected type function (struct D.s storage pointer,uint256) returns (uint256). Bound functions can not be converted to non-bound functions.
1313
// TypeError 6160: (298-302): Wrong argument count for function call: 1 arguments given but expected 2.

test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ contract B is A {
1010
}
1111
}
1212
// ----
13-
// TypeError 9574: (133-160): Type function A.f() is not implicitly convertible to expected type function () external.
14-
// TypeError 9574: (170-202): Type function A.g() pure is not implicitly convertible to expected type function () pure external.
13+
// TypeError 9574: (133-160): Type function A.f() is not implicitly convertible to expected type function () external. Special functions can not be converted to function types.
14+
// TypeError 9574: (170-202): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions can not be converted to function types.

test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ contract B {
1010
}
1111
}
1212
// ----
13-
// TypeError 9574: (128-155): Type function A.f() is not implicitly convertible to expected type function () external.
14-
// TypeError 9574: (165-197): Type function A.g() pure is not implicitly convertible to expected type function () pure external.
13+
// TypeError 9574: (128-155): Type function A.f() is not implicitly convertible to expected type function () external. Special functions can not be converted to function types.
14+
// TypeError 9574: (165-197): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions can not be converted to function types.

0 commit comments

Comments
 (0)