mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Display human readable type name in conversion error message
This commit is contained in:
parent
f2c930588c
commit
4b7ed2d47a
@ -1842,7 +1842,7 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(
|
|||||||
_functionCall.location(),
|
_functionCall.location(),
|
||||||
ssl,
|
ssl,
|
||||||
"Explicit type conversion not allowed from non-payable \"address\" to \"" +
|
"Explicit type conversion not allowed from non-payable \"address\" to \"" +
|
||||||
resultType->toString() +
|
resultType->humanReadableName() +
|
||||||
"\", which has a payable fallback function."
|
"\", which has a payable fallback function."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1856,9 +1856,9 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(
|
|||||||
5030_error,
|
5030_error,
|
||||||
_functionCall.location(),
|
_functionCall.location(),
|
||||||
"Explicit type conversion not allowed from \"" +
|
"Explicit type conversion not allowed from \"" +
|
||||||
argType->toString() +
|
argType->humanReadableName() +
|
||||||
"\" to \"" +
|
"\" to \"" +
|
||||||
resultType->toString() +
|
resultType->humanReadableName() +
|
||||||
"\". To obtain the address of the contract of the function, " +
|
"\". To obtain the address of the contract of the function, " +
|
||||||
"you can use the .address member of the function."
|
"you can use the .address member of the function."
|
||||||
);
|
);
|
||||||
@ -1867,9 +1867,9 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(
|
|||||||
9640_error,
|
9640_error,
|
||||||
_functionCall.location(),
|
_functionCall.location(),
|
||||||
"Explicit type conversion not allowed from \"" +
|
"Explicit type conversion not allowed from \"" +
|
||||||
argType->toString() +
|
argType->humanReadableName() +
|
||||||
"\" to \"" +
|
"\" to \"" +
|
||||||
resultType->toString() +
|
resultType->humanReadableName() +
|
||||||
"\".",
|
"\".",
|
||||||
result.message()
|
result.message()
|
||||||
);
|
);
|
||||||
|
@ -110,6 +110,14 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa
|
|||||||
return transformed;
|
return transformed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string toStringInParentheses(TypePointers const& _types, bool _short)
|
||||||
|
{
|
||||||
|
return '(' + util::joinHumanReadable(
|
||||||
|
_types | ranges::views::transform([&](auto const* _type) { return _type->toString(_short); }),
|
||||||
|
","
|
||||||
|
) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::Member::Member(Declaration const* _declaration, Type const* _type):
|
MemberList::Member::Member(Declaration const* _declaration, Type const* _type):
|
||||||
@ -3090,6 +3098,19 @@ string FunctionType::canonicalName() const
|
|||||||
return "function";
|
return "function";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string FunctionType::humanReadableName() const
|
||||||
|
{
|
||||||
|
switch (m_kind)
|
||||||
|
{
|
||||||
|
case Kind::Error:
|
||||||
|
return "error " + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _short */ true);
|
||||||
|
case Kind::Event:
|
||||||
|
return "event " + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _short */ true);
|
||||||
|
default:
|
||||||
|
return toString(/* _short */ false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string FunctionType::toString(bool _short) const
|
string FunctionType::toString(bool _short) const
|
||||||
{
|
{
|
||||||
string name = "function ";
|
string name = "function ";
|
||||||
@ -3101,20 +3122,15 @@ string FunctionType::toString(bool _short) const
|
|||||||
name += *contract->annotation().canonicalName + ".";
|
name += *contract->annotation().canonicalName + ".";
|
||||||
name += functionDefinition->name();
|
name += functionDefinition->name();
|
||||||
}
|
}
|
||||||
name += '(';
|
name += toStringInParentheses(m_parameterTypes, _short);
|
||||||
for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)
|
|
||||||
name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ",");
|
|
||||||
name += ")";
|
|
||||||
if (m_stateMutability != StateMutability::NonPayable)
|
if (m_stateMutability != StateMutability::NonPayable)
|
||||||
name += " " + stateMutabilityToString(m_stateMutability);
|
name += " " + stateMutabilityToString(m_stateMutability);
|
||||||
if (m_kind == Kind::External)
|
if (m_kind == Kind::External)
|
||||||
name += " external";
|
name += " external";
|
||||||
if (!m_returnParameterTypes.empty())
|
if (!m_returnParameterTypes.empty())
|
||||||
{
|
{
|
||||||
name += " returns (";
|
name += " returns ";
|
||||||
for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
|
name += toStringInParentheses(m_returnParameterTypes, _short);
|
||||||
name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
|
|
||||||
name += ")";
|
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -339,6 +339,7 @@ public:
|
|||||||
std::string toString() const { return toString(false); }
|
std::string toString() const { return toString(false); }
|
||||||
/// @returns the canonical name of this type for use in library function signatures.
|
/// @returns the canonical name of this type for use in library function signatures.
|
||||||
virtual std::string canonicalName() const { return toString(true); }
|
virtual std::string canonicalName() const { return toString(true); }
|
||||||
|
virtual std::string humanReadableName() const { return toString(); }
|
||||||
/// @returns the signature of this type in external functions, i.e. `uint256` for integers
|
/// @returns the signature of this type in external functions, i.e. `uint256` for integers
|
||||||
/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
|
/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
|
||||||
/// structs are given by canonical name like `ContractName.StructName[2]`.
|
/// structs are given by canonical name like `ContractName.StructName[2]`.
|
||||||
@ -1378,6 +1379,7 @@ public:
|
|||||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||||
TypeResult binaryOperatorResult(Token, Type const*) const override;
|
TypeResult binaryOperatorResult(Token, Type const*) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
|
std::string humanReadableName() const override;
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
unsigned calldataEncodedSize(bool _padded) const override;
|
unsigned calldataEncodedSize(bool _padded) const override;
|
||||||
bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
|
bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
interface MyInterface {
|
||||||
|
error MyCustomError(uint256, bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Test {
|
||||||
|
function test() public returns(bytes4) {
|
||||||
|
return bytes4(MyInterface.MyCustomError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9640: (143-176): Explicit type conversion not allowed from "error MyCustomError(uint256,bool)" to "bytes4".
|
@ -0,0 +1,9 @@
|
|||||||
|
contract Test {
|
||||||
|
event MyCustomEvent(uint256);
|
||||||
|
|
||||||
|
function test() public returns(bytes4) {
|
||||||
|
return bytes4(MyCustomEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9640: (111-132): Explicit type conversion not allowed from "event MyCustomEvent(uint256)" to "bytes4".
|
@ -0,0 +1,28 @@
|
|||||||
|
interface MyInterface {
|
||||||
|
enum MyEnum { E1, E2 }
|
||||||
|
error CustomError1(
|
||||||
|
uint256,
|
||||||
|
bool,
|
||||||
|
bool[],
|
||||||
|
address payable,
|
||||||
|
MyInterface,
|
||||||
|
MyEnum,
|
||||||
|
function (string memory) external returns (uint)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Test {
|
||||||
|
function testFunction(string memory) external returns (uint) {}
|
||||||
|
|
||||||
|
function test() public {
|
||||||
|
MyInterface instance = MyInterface(msg.sender);
|
||||||
|
bool[] calldata arr;
|
||||||
|
address payable addr;
|
||||||
|
bytes4(MyInterface.CustomEror1);
|
||||||
|
bytes4(MyInterface.CustomError1());
|
||||||
|
bytes4(MyInterface.CustomError1(1, true, arr, addr, instance, MyInterface.MyEnum.E1, this.testFunction));
|
||||||
|
address(MyInterface.CustomError1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9582: (495-518): Member "CustomEror1" not found or not visible after argument-dependent lookup in type(contract MyInterface).
|
@ -0,0 +1,34 @@
|
|||||||
|
interface MyInterface {
|
||||||
|
enum MyEnum { E1, E2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Test {
|
||||||
|
function testFunction(string memory) external returns (uint) {}
|
||||||
|
|
||||||
|
event CustomEvent1(
|
||||||
|
uint256,
|
||||||
|
bool,
|
||||||
|
bool[],
|
||||||
|
address payable,
|
||||||
|
MyInterface,
|
||||||
|
MyInterface.MyEnum,
|
||||||
|
function (string memory) external returns (uint)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
function test() public {
|
||||||
|
MyInterface instance = MyInterface(msg.sender);
|
||||||
|
bool[] calldata arr;
|
||||||
|
address payable addr;
|
||||||
|
bytes4(CustomEvent1);
|
||||||
|
bytes4(CustomEvent1());
|
||||||
|
bytes4(CustomEvent1(1, true, arr, addr, instance, MyInterface.MyEnum.E1, this.testFunction));
|
||||||
|
address(CustomEvent1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9640: (502-522): Explicit type conversion not allowed from "event CustomEvent1(uint256,bool,bool[],address payable,contract MyInterface,enum MyInterface.MyEnum,function (string) external returns (uint256))" to "bytes4".
|
||||||
|
// TypeError 6160: (539-553): Wrong argument count for function call: 0 arguments given but expected 7.
|
||||||
|
// TypeError 9640: (532-554): Explicit type conversion not allowed from "tuple()" to "bytes4".
|
||||||
|
// TypeError 9640: (564-656): Explicit type conversion not allowed from "tuple()" to "bytes4".
|
||||||
|
// TypeError 9640: (666-687): Explicit type conversion not allowed from "event CustomEvent1(uint256,bool,bool[],address payable,contract MyInterface,enum MyInterface.MyEnum,function (string) external returns (uint256))" to "address".
|
Loading…
Reference in New Issue
Block a user