diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 3f50f915b..fc6e8a5b5 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2171,7 +2171,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks( for (size_t i = 0; i < paramArgMap.size(); ++i) { solAssert(!!paramArgMap[i], "unmapped parameter"); - if (!type(*paramArgMap[i])->isImplicitlyConvertibleTo(*parameterTypes[i])) + BoolResult result = type(*paramArgMap[i])->isImplicitlyConvertibleTo(*parameterTypes[i]); + if (!result) { auto [errorId, description] = [&]() -> tuple { string msg = @@ -2181,6 +2182,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks( " to " + parameterTypes[i]->toString() + " requested."; + if (!result.message().empty()) + msg += " " + result.message(); if ( _functionType->kind() == FunctionType::Kind::BareCall || _functionType->kind() == FunctionType::Kind::BareCallCode || diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f883496d7..ed3686b36 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3111,6 +3111,13 @@ BoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const FunctionType const& convertTo = dynamic_cast(_convertTo); + // These two checks are duplicated in equalExcludingStateMutability, but are added here for error reporting. + if (convertTo.bound() != bound()) + return BoolResult::err("Bound functions can not be converted to non-bound functions."); + + if (convertTo.kind() != kind()) + return BoolResult::err("Special functions can not be converted to function types."); + if (!equalExcludingStateMutability(convertTo)) return false; diff --git a/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol b/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol index 0a7919261..5682ede4d 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol @@ -22,4 +22,4 @@ contract Test { } } // ---- -// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external. +// 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. diff --git a/test/libsolidity/syntaxTests/events/event_library_function.sol b/test/libsolidity/syntaxTests/events/event_library_function.sol index 4eba5202f..382786faa 100644 --- a/test/libsolidity/syntaxTests/events/event_library_function.sol +++ b/test/libsolidity/syntaxTests/events/event_library_function.sol @@ -30,6 +30,6 @@ contract E { } } // ---- -// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. -// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. -// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested. +// 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. +// 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. +// 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. diff --git a/test/libsolidity/syntaxTests/functionTypes/assign_bound.sol b/test/libsolidity/syntaxTests/functionTypes/assign_bound.sol index eac080e53..37322114d 100644 --- a/test/libsolidity/syntaxTests/functionTypes/assign_bound.sol +++ b/test/libsolidity/syntaxTests/functionTypes/assign_bound.sol @@ -12,4 +12,4 @@ contract C { } } // ---- -// TypeError 9574: (209-280): Type function (uint256,uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). +// 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. diff --git a/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol b/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol index 0fa43aa76..cb795fede 100644 --- a/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol +++ b/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError 9574: (42-103): Type function (uint256) view returns (bytes32) is not implicitly convertible to expected type function (uint256) view returns (bytes32). +// 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. diff --git a/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol index dbc873b39..0d7030606 100644 --- a/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol +++ b/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol @@ -10,5 +10,5 @@ contract C { } } // ---- -// 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. -// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256). +// 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. +// 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. diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol index cb2ee61c5..08b1b26e3 100644 --- a/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol @@ -3,4 +3,4 @@ contract test { function(bytes memory) external internal a = fa; } // ---- -// TypeError 7407: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external. +// 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. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol index 699a0b551..2463bee5e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol @@ -9,5 +9,5 @@ contract C { } } // ---- -// 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). +// 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. // TypeError 6160: (298-302): Wrong argument count for function call: 1 arguments given but expected 2. diff --git a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol index b3bff7849..9b988bb6e 100644 --- a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol +++ b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol @@ -10,5 +10,5 @@ contract B is A { } } // ---- -// TypeError 9574: (133-160): Type function A.f() is not implicitly convertible to expected type function () external. -// TypeError 9574: (170-202): Type function A.g() pure is not implicitly convertible to expected type function () pure external. +// 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. +// 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. diff --git a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol index 655493d08..682a7a110 100644 --- a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol +++ b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol @@ -10,5 +10,5 @@ contract B { } } // ---- -// TypeError 9574: (128-155): Type function A.f() is not implicitly convertible to expected type function () external. -// TypeError 9574: (165-197): Type function A.g() pure is not implicitly convertible to expected type function () pure external. +// 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. +// 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.