Merge pull request #13210 from timweri/display_human_readable_type_name_in_conversion

Display human readable type name in error messages
This commit is contained in:
Mathias L. Baumann 2022-07-06 17:31:53 +02:00 committed by GitHub
commit b2ac0dada4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 654 additions and 137 deletions

View File

@ -9,6 +9,7 @@ Compiler Features:
* Yul Optimizer: Add rule to convert `mod(mul(X, Y), A)` into `mulmod(X, Y, A)`, if `A` is a power of two.
* Yul Optimizer: Add rule to convert `mod(add(X, Y), A)` into `addmod(X, Y, A)`, if `A` is a power of two.
* Code Generator: More efficient code for checked addition and subtraction.
* Error Reporter: More readable and informative error/warning messages.
Bugfixes:
* Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``.

View File

@ -214,7 +214,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c
arguments.front()->location(),
"The first argument to \"abi.decode\" must be implicitly convertible to "
"bytes memory or bytes calldata, but is of type " +
type(*arguments.front())->toString() +
type(*arguments.front())->humanReadableName() +
"."
);
@ -258,7 +258,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c
m_errorReporter.typeError(
9611_error,
typeArgument->location(),
"Decoding type " + actualType->toString(false) + " not supported."
"Decoding type " + actualType->humanReadableName() + " not supported."
);
if (auto referenceType = dynamic_cast<ReferenceType const*>(actualType))
@ -318,7 +318,7 @@ TypePointers TypeChecker::typeCheckMetaTypeFunctionAndRetrieveReturnType(Functio
arguments.front()->location(),
"Invalid type for argument in the function call. "
"An enum type, contract type or an integer type is required, but " +
type(*arguments.front())->toString(true) + " provided."
type(*arguments.front())->humanReadableName() + " provided."
);
return {TypeProvider::meta(dynamic_cast<TypeType const&>(*firstArgType).actualType())};
@ -367,9 +367,9 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance)
(*arguments)[i]->location(),
"Invalid type for argument in constructor call. "
"Invalid implicit conversion from " +
type(*(*arguments)[i])->toString() +
type(*(*arguments)[i])->humanReadableName() +
" to " +
parameterTypes[i]->toString() +
parameterTypes[i]->humanReadableName() +
" requested.",
result.message()
);
@ -623,7 +623,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
m_errorReporter.fatalTypeError(
4061_error,
_variable.location(),
"Type " + varType->toString(true) + " is only valid in storage because it contains a (nested) mapping."
"Type " + varType->humanReadableName() + " is only valid in storage because it contains a (nested) mapping."
);
}
else if (_variable.visibility() >= Visibility::Public)
@ -634,7 +634,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
vector<string> unsupportedTypes;
for (auto const& param: getter.parameterTypes() + getter.returnParameterTypes())
if (!typeSupportedByOldABIEncoder(*param, false /* isLibrary */))
unsupportedTypes.emplace_back(param->toString());
unsupportedTypes.emplace_back(param->humanReadableName());
if (!unsupportedTypes.empty())
m_errorReporter.typeError(
2763_error,
@ -776,9 +776,9 @@ void TypeChecker::visitManually(
arguments[i]->location(),
"Invalid type for argument in modifier invocation. "
"Invalid implicit conversion from " +
type(*arguments[i])->toString() +
type(*arguments[i])->humanReadableName() +
" to " +
type(*(*parameters)[i])->toString() +
type(*(*parameters)[i])->humanReadableName() +
" requested.",
result.message()
);
@ -1115,9 +1115,9 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement)
6509_error,
parameter->location(),
"Invalid type, expected " +
returnType->toString(false) +
returnType->humanReadableName() +
" but got " +
parameter->annotation().type->toString() +
parameter->annotation().type->humanReadableName() +
"."
);
}
@ -1258,9 +1258,9 @@ void TypeChecker::endVisit(Return const& _return)
5992_error,
_return.expression()->location(),
"Return argument type " +
type(*_return.expression())->toString() +
type(*_return.expression())->humanReadableName() +
" is not implicitly convertible to expected type " +
TupleType(returnTypes).toString(false) + ".",
TupleType(returnTypes).humanReadableName() + ".",
result.message()
);
}
@ -1276,9 +1276,9 @@ void TypeChecker::endVisit(Return const& _return)
6359_error,
_return.expression()->location(),
"Return argument type " +
type(*_return.expression())->toString() +
type(*_return.expression())->humanReadableName() +
" is not implicitly convertible to expected type (type of first return variable) " +
expected->toString() + ".",
expected->humanReadableName() + ".",
result.message()
);
}
@ -1382,9 +1382,9 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
if (!result)
{
auto errorMsg = "Type " +
valueComponentType->toString() +
valueComponentType->humanReadableName() +
" is not implicitly convertible to expected type " +
var.annotation().type->toString();
var.annotation().type->humanReadableName();
if (
valueComponentType->category() == Type::Category::RationalNumber &&
dynamic_cast<RationalNumberType const&>(*valueComponentType).isFractional() &&
@ -1403,7 +1403,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
_statement.location(),
errorMsg +
". Try converting to type " +
valueComponentType->mobileType()->toString() +
valueComponentType->mobileType()->humanReadableName() +
" or use an explicit conversion."
);
}
@ -1486,9 +1486,9 @@ bool TypeChecker::visit(Conditional const& _conditional)
1080_error,
_conditional.location(),
"True expression's type " +
trueType->toString() +
trueType->humanReadableName() +
" does not match false expression's type " +
falseType->toString() +
falseType->humanReadableName() +
"."
);
// even we can't find a common type, we have to set a type here,
@ -1598,9 +1598,9 @@ bool TypeChecker::visit(Assignment const& _assignment)
"Operator " +
string(TokenTraits::toString(_assignment.assignmentOperator())) +
" not compatible with types " +
t->toString() +
t->humanReadableName() +
" and " +
type(_assignment.rightHandSide())->toString()
type(_assignment.rightHandSide())->humanReadableName()
);
}
return false;
@ -1691,7 +1691,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
m_errorReporter.fatalTypeError(
1545_error,
_tuple.location(),
"Type " + inlineArrayType->toString(true) + " is only valid in storage."
"Type " + inlineArrayType->humanReadableName() + " is only valid in storage."
);
_tuple.annotation().type = TypeProvider::array(DataLocation::Memory, inlineArrayType, types.size());
@ -1722,7 +1722,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
TypeResult result = type(_operation.subExpression())->unaryOperatorResult(op);
if (!result)
{
string description = "Unary operator " + string(TokenTraits::toString(op)) + " cannot be applied to type " + subExprType->toString();
string description = "Unary operator " + string(TokenTraits::toString(op)) + " cannot be applied to type " + subExprType->humanReadableName();
if (!result.message().empty())
description += ". " + result.message();
if (modifying)
@ -1756,9 +1756,9 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
"Operator " +
string(TokenTraits::toString(_operation.getOperator())) +
" not compatible with types " +
leftType->toString() +
leftType->humanReadableName() +
" and " +
rightType->toString() +
rightType->humanReadableName() +
(!result.message().empty() ? ". " + result.message() : "")
);
commonType = leftType;
@ -1800,9 +1800,9 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
"The result type of the " +
operation +
" operation is equal to the type of the first operand (" +
commonType->toString() +
commonType->humanReadableName() +
") ignoring the (larger) type of the second operand (" +
rightType->toString() +
rightType->humanReadableName() +
") which might be unexpected. Silence this warning by either converting "
"the first or the second operand to the type of the other."
);
@ -2183,7 +2183,7 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
5511_error,
arguments.front()->location(),
"Expected first argument to be a function pointer, not \"" +
type(*arguments.front())->toString() +
type(*arguments.front())->humanReadableName() +
"\"."
);
return;
@ -2272,9 +2272,9 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
"Cannot implicitly convert component at position " +
to_string(i) +
" from \"" +
argType.toString() +
argType.humanReadableName() +
"\" to \"" +
externalFunctionType->parameterTypes()[i]->toString() +
externalFunctionType->parameterTypes()[i]->humanReadableName() +
"\"" +
(result.message().empty() ? "." : ": " + result.message())
);
@ -2334,7 +2334,7 @@ void TypeChecker::typeCheckBytesConcatFunction(
argument->location(),
"Invalid type for argument in the bytes.concat function call. "
"bytes or fixed bytes type is required, but " +
argumentType->toString(true) + " provided."
argumentType->humanReadableName() + " provided."
);
}
}
@ -2519,9 +2519,9 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
string msg =
"Invalid type for argument in function call. "
"Invalid implicit conversion from " +
type(*paramArgMap[i])->toString() +
type(*paramArgMap[i])->humanReadableName() +
" to " +
parameterTypes[i]->toString() +
parameterTypes[i]->humanReadableName() +
" requested.";
if (!result.message().empty())
msg += " " + result.message();
@ -2583,7 +2583,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
m_errorReporter.typeError(
2443_error,
paramArgMap[i]->location(),
"The type of this parameter, " + parameterTypes[i]->toString(true) + ", "
"The type of this parameter, " + parameterTypes[i]->humanReadableName() + ", "
"is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature."
);
@ -2597,7 +2597,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
m_errorReporter.typeError(
2428_error,
_functionCall.location(),
"The type of return parameter " + toString(i + 1) + ", " + returnParameterTypes[i]->toString(true) + ", "
"The type of return parameter " + toString(i + 1) + ", " + returnParameterTypes[i]->humanReadableName() + ", "
"is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature."
);
@ -2896,7 +2896,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
_functionCallOptions.location(),
kind == FunctionType::Kind::Creation ?
"Cannot set option \"value\", since the constructor of " +
expressionFunctionType->returnParameterTypes().front()->toString() +
expressionFunctionType->returnParameterTypes().front()->humanReadableName() +
" is not payable." :
"Cannot set option \"value\" on a non-payable function type."
);
@ -3036,14 +3036,14 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
4994_error,
_memberAccess.location(),
"Member \"" + memberName + "\" is not available in " +
exprType->toString() +
exprType->humanReadableName() +
" outside of storage."
);
}
auto [errorId, description] = [&]() -> tuple<ErrorId, string> {
string errorMsg = "Member \"" + memberName + "\" not found or not visible "
"after argument-dependent lookup in " + exprType->toString() + ".";
"after argument-dependent lookup in " + exprType->humanReadableName() + ".";
if (auto const* funType = dynamic_cast<FunctionType const*>(exprType))
{
@ -3054,7 +3054,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
if (funType->kind() == FunctionType::Kind::Creation)
return {
8827_error,
"Constructor for " + t.front()->toString() + " must be payable for member \"value\" to be available."
"Constructor for " + t.front()->humanReadableName() + " must be payable for member \"value\" to be available."
};
else if (
funType->kind() == FunctionType::Kind::DelegateCall ||
@ -3093,7 +3093,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
"Expected address not-payable as members were not found"
);
return { 9862_error, "\"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"" + exprType->toString() + "\"." };
return { 9862_error, "\"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"" + exprType->humanReadableName() + "\"." };
}
}
@ -3111,7 +3111,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
6675_error,
_memberAccess.location(),
"Member \"" + memberName + "\" not unique "
"after argument-dependent lookup in " + exprType->toString() +
"after argument-dependent lookup in " + exprType->humanReadableName() +
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : ".")
);
@ -3125,7 +3125,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
solAssert(
!funType->bound() || exprType->isImplicitlyConvertibleTo(*funType->selfType()),
"Function \"" + memberName + "\" cannot be called on an object of type " +
exprType->toString() + " (expected " + funType->selfType()->toString() + ")."
exprType->humanReadableName() + " (expected " + funType->selfType()->humanReadableName() + ")."
);
if (
@ -3388,7 +3388,7 @@ bool TypeChecker::visit(IndexAccess const& _access)
m_errorReporter.fatalTypeError(
2614_error,
_access.baseExpression().location(),
"Indexed expression has to be a type, mapping or array (is " + baseType->toString() + ")"
"Indexed expression has to be a type, mapping or array (is " + baseType->humanReadableName() + ")"
);
}
_access.annotation().type = resultType;
@ -3543,7 +3543,7 @@ bool TypeChecker::visit(Identifier const& _identifier)
// Try to re-construct function definition
string description;
for (auto const& param: declaration->functionType(true)->parameterTypes())
description += (description.empty() ? "" : ", ") + param->toString(false);
description += (description.empty() ? "" : ", ") + param->humanReadableName();
description = "function " + _identifier.name() + "(" + description + ")";
ssl.append("Candidate: " + description, declaration->location());
@ -3764,7 +3764,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
path->location(),
"The function \"" + joinHumanReadable(path->path(), ".") + "\" " +
"does not have any parameters, and therefore cannot be bound to the type \"" +
(normalizedType ? normalizedType->toString(true) : "*") + "\"."
(normalizedType ? normalizedType->humanReadableName() : "*") + "\"."
);
FunctionType const* functionType = dynamic_cast<FunctionType const&>(*functionDefinition.type()).asBoundFunction();
@ -3777,9 +3777,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
3100_error,
path->location(),
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
"cannot be bound to the type \"" + _usingFor.typeName()->annotation().type->toString() +
"cannot be bound to the type \"" + _usingFor.typeName()->annotation().type->humanReadableName() +
"\" because the type cannot be implicitly converted to the first argument" +
" of the function (\"" + functionType->selfType()->toString() + "\")" +
" of the function (\"" + functionType->selfType()->humanReadableName() + "\")" +
(
result.message().empty() ?
"." :
@ -3834,9 +3834,9 @@ bool TypeChecker::expectType(Expression const& _expression, Type const& _expecte
if (!result)
{
auto errorMsg = "Type " +
type(_expression)->toString() +
type(_expression)->humanReadableName() +
" is not implicitly convertible to expected type " +
_expectedType.toString();
_expectedType.humanReadableName();
if (
type(_expression)->category() == Type::Category::RationalNumber &&
dynamic_cast<RationalNumberType const*>(type(_expression))->isFractional() &&
@ -3855,7 +3855,7 @@ bool TypeChecker::expectType(Expression const& _expression, Type const& _expecte
_expression.location(),
errorMsg +
". Try converting to type " +
type(_expression)->mobileType()->toString() +
type(_expression)->mobileType()->humanReadableName() +
" or use an explicit conversion.",
result.message()
);

View File

@ -143,10 +143,10 @@ string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath
return boost::algorithm::join(_namePath, ".");
}
Json::Value ASTJsonExporter::typePointerToJson(Type const* _tp, bool _short)
Json::Value ASTJsonExporter::typePointerToJson(Type const* _tp, bool _withoutDataLocation)
{
Json::Value typeDescriptions(Json::objectValue);
typeDescriptions["typeString"] = _tp ? Json::Value(_tp->toString(_short)) : Json::nullValue;
typeDescriptions["typeString"] = _tp ? Json::Value(_tp->toString(_withoutDataLocation)) : Json::nullValue;
typeDescriptions["typeIdentifier"] = _tp ? Json::Value(_tp->identifier()) : Json::nullValue;
return typeDescriptions;

View File

@ -184,7 +184,7 @@ private:
return json;
}
static Json::Value typePointerToJson(Type const* _tp, bool _short = false);
static Json::Value typePointerToJson(Type const* _tp, bool _withoutDataLocation = false);
static Json::Value typePointerToJson(std::optional<FuncCallArguments> const& _tps);
void appendExpressionAttributes(
std::vector<std::pair<std::string, Json::Value>> &_attributes,

View File

@ -110,10 +110,10 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa
return transformed;
}
string toStringInParentheses(TypePointers const& _types, bool _short)
string toStringInParentheses(TypePointers const& _types, bool _withoutDataLocation)
{
return '(' + util::joinHumanReadable(
_types | ranges::views::transform([&](auto const* _type) { return _type->toString(_short); }),
_types | ranges::views::transform([&](auto const* _type) { return _type->toString(_withoutDataLocation); }),
","
) + ')';
}
@ -1789,7 +1789,7 @@ vector<tuple<string, Type const*>> ArrayType::makeStackItems() const
solAssert(false, "");
}
string ArrayType::toString(bool _short) const
string ArrayType::toString(bool _withoutDataLocation) const
{
string ret;
if (isString())
@ -1798,16 +1798,34 @@ string ArrayType::toString(bool _short) const
ret = "bytes";
else
{
ret = baseType()->toString(_short) + "[";
ret = baseType()->toString(_withoutDataLocation) + "[";
if (!isDynamicallySized())
ret += length().str();
ret += "]";
}
if (!_short)
if (!_withoutDataLocation)
ret += " " + stringForReferencePart();
return ret;
}
string ArrayType::humanReadableName() const
{
string ret;
if (isString())
ret = "string";
else if (isByteArrayOrString())
ret = "bytes";
else
{
ret = baseType()->toString(true) + "[";
if (!isDynamicallySized())
ret += length().str();
ret += "]";
}
ret += " " + stringForReferencePart();
return ret;
}
string ArrayType::canonicalName() const
{
string ret;
@ -1990,9 +2008,14 @@ bool ArraySliceType::operator==(Type const& _other) const
return false;
}
string ArraySliceType::toString(bool _short) const
string ArraySliceType::toString(bool _withoutDataLocation) const
{
return m_arrayType.toString(_short) + " slice";
return m_arrayType.toString(_withoutDataLocation) + " slice";
}
string ArraySliceType::humanReadableName() const
{
return m_arrayType.humanReadableName() + " slice";
}
Type const* ArraySliceType::mobileType() const
@ -2256,10 +2279,10 @@ bool StructType::containsNestedMapping() const
return m_struct.annotation().containsNestedMapping.value();
}
string StructType::toString(bool _short) const
string StructType::toString(bool _withoutDataLocation) const
{
string ret = "struct " + *m_struct.annotation().canonicalName;
if (!_short)
if (!_withoutDataLocation)
ret += " " + stringForReferencePart();
return ret;
}
@ -2611,7 +2634,7 @@ bool UserDefinedValueType::operator==(Type const& _other) const
return other.definition() == definition();
}
string UserDefinedValueType::toString(bool /* _short */) const
string UserDefinedValueType::toString(bool /* _withoutDataLocation */) const
{
return *definition().annotation().canonicalName;
}
@ -2659,13 +2682,24 @@ bool TupleType::operator==(Type const& _other) const
return false;
}
string TupleType::toString(bool _short) const
string TupleType::toString(bool _withoutDataLocation) const
{
if (components().empty())
return "tuple()";
string str = "tuple(";
for (auto const& t: components())
str += (t ? t->toString(_short) : "") + ",";
str += (t ? t->toString(_withoutDataLocation) : "") + ",";
str.pop_back();
return str + ")";
}
string TupleType::humanReadableName() const
{
if (components().empty())
return "tuple()";
string str = "tuple(";
for (auto const& t: components())
str += (t ? t->humanReadableName() : "") + ",";
str.pop_back();
return str + ")";
}
@ -3103,15 +3137,15 @@ string FunctionType::humanReadableName() const
switch (m_kind)
{
case Kind::Error:
return "error " + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _short */ true);
return "error " + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _withoutDataLocation */ true);
case Kind::Event:
return "event " + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _short */ true);
return "event " + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _withoutDataLocation */ true);
default:
return toString(/* _short */ false);
return toString(/* _withoutDataLocation */ false);
}
}
string FunctionType::toString(bool _short) const
string FunctionType::toString(bool _withoutDataLocation) const
{
string name = "function ";
if (m_kind == Kind::Declaration)
@ -3122,7 +3156,7 @@ string FunctionType::toString(bool _short) const
name += *contract->annotation().canonicalName + ".";
name += functionDefinition->name();
}
name += toStringInParentheses(m_parameterTypes, _short);
name += toStringInParentheses(m_parameterTypes, _withoutDataLocation);
if (m_stateMutability != StateMutability::NonPayable)
name += " " + stateMutabilityToString(m_stateMutability);
if (m_kind == Kind::External)
@ -3130,7 +3164,7 @@ string FunctionType::toString(bool _short) const
if (!m_returnParameterTypes.empty())
{
name += " returns ";
name += toStringInParentheses(m_returnParameterTypes, _short);
name += toStringInParentheses(m_returnParameterTypes, _withoutDataLocation);
}
return name;
}
@ -3722,9 +3756,9 @@ bool MappingType::operator==(Type const& _other) const
return *other.m_keyType == *m_keyType && *other.m_valueType == *m_valueType;
}
string MappingType::toString(bool _short) const
string MappingType::toString(bool _withoutDataLocation) const
{
return "mapping(" + keyType()->toString(_short) + " => " + valueType()->toString(_short) + ")";
return "mapping(" + keyType()->toString(_withoutDataLocation) + " => " + valueType()->toString(_withoutDataLocation) + ")";
}
string MappingType::canonicalName() const
@ -3949,11 +3983,11 @@ bool ModifierType::operator==(Type const& _other) const
return true;
}
string ModifierType::toString(bool _short) const
string ModifierType::toString(bool _withoutDataLocation) const
{
string name = "modifier (";
for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)
name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ",");
name += (*it)->toString(_withoutDataLocation) + (it + 1 == m_parameterTypes.end() ? "" : ",");
return name + ")";
}
@ -4149,7 +4183,7 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
return {};
}
string MagicType::toString(bool _short) const
string MagicType::toString(bool _withoutDataLocation) const
{
switch (m_kind)
{
@ -4163,7 +4197,7 @@ string MagicType::toString(bool _short) const
return "abi";
case Kind::MetaType:
solAssert(m_typeArgument, "");
return "type(" + m_typeArgument->toString(_short) + ")";
return "type(" + m_typeArgument->toString(_withoutDataLocation) + ")";
}
solAssert(false, "Unknown kind of magic.");
return {};

View File

@ -335,7 +335,7 @@ public:
return members(_currentScope).memberType(_name);
}
virtual std::string toString(bool _short) const = 0;
virtual std::string toString(bool _withoutDataLocation) const = 0;
std::string toString() const { return toString(false); }
/// @returns the canonical name of this type for use in library function signatures.
virtual std::string canonicalName() const { return toString(true); }
@ -428,7 +428,7 @@ public:
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
u256 literalValue(Literal const* _literal) const override;
@ -471,7 +471,7 @@ public:
bool isValueType() const override { return true; }
bool nameable() const override { return true; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
Type const* encodingType() const override { return this; }
TypeResult interfaceType(bool) const override { return this; }
@ -518,7 +518,7 @@ public:
bool isValueType() const override { return true; }
bool nameable() const override { return true; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
Type const* encodingType() const override { return this; }
TypeResult interfaceType(bool) const override { return this; }
@ -568,7 +568,7 @@ public:
bool canBeStored() const override { return false; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
u256 literalValue(Literal const* _literal) const override;
Type const* mobileType() const override;
@ -832,7 +832,8 @@ public:
bool containsNestedMapping() const override { return m_baseType->containsNestedMapping(); }
bool nameable() const override { return true; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string humanReadableName() const override;
std::string canonicalName() const override;
std::string signatureInExternalFunction(bool _structsByName) const override;
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
@ -896,7 +897,8 @@ public:
unsigned calldataEncodedTailSize() const override { return 32; }
bool isDynamicallySized() const override { return true; }
bool isDynamicallyEncoded() const override { return true; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string humanReadableName() const override;
Type const* mobileType() const override;
BoolResult validForLocation(DataLocation _loc) const override { return m_arrayType.validForLocation(_loc); }
@ -940,7 +942,7 @@ public:
bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
bool isValueType() const override { return !isSuper(); }
bool nameable() const override { return !isSuper(); }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
@ -1002,7 +1004,7 @@ public:
u256 storageSize() const override;
bool containsNestedMapping() const override;
bool nameable() const override { return true; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
@ -1064,7 +1066,7 @@ public:
}
unsigned storageBytes() const override;
bool leftAligned() const override { return false; }
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
bool isValueType() const override { return true; }
bool nameable() const override { return true; }
@ -1151,7 +1153,7 @@ public:
return false;
}
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
std::string signatureInExternalFunction(bool) const override { solAssert(false, ""); }
@ -1177,7 +1179,8 @@ public:
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;
TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
std::string toString(bool) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string humanReadableName() const override;
bool canBeStored() const override { return false; }
u256 storageSize() const override;
bool hasSimpleZeroValueInMemory() const override { return false; }
@ -1380,7 +1383,7 @@ public:
TypeResult binaryOperatorResult(Token, Type const*) const override;
std::string canonicalName() const override;
std::string humanReadableName() const override;
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
unsigned calldataEncodedSize(bool _padded) const override;
bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
u256 storageSize() const override;
@ -1514,7 +1517,7 @@ public:
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
bool containsNestedMapping() const override { return true; }
TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
@ -1555,7 +1558,7 @@ public:
bool canBeStored() const override { return false; }
u256 storageSize() const override;
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
std::string toString(bool _withoutDataLocation) const override { return "type(" + m_actualType->toString(_withoutDataLocation) + ")"; }
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
@ -1582,7 +1585,7 @@ public:
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
protected:
std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }
private:
@ -1608,7 +1611,7 @@ public:
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
protected:
std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }
@ -1647,7 +1650,7 @@ public:
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
std::string toString(bool _short) const override;
std::string toString(bool _withoutDataLocation) const override;
Kind kind() const { return m_kind; }

View File

@ -18,4 +18,4 @@ contract Test {
}
}
// ----
// TypeError 2443: (B:91-100): The type of this parameter, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2443: (B:91-100): The type of this parameter, struct C.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -18,4 +18,4 @@ contract Test {
}
}
// ----
// TypeError 2443: (B:119-129): The type of this parameter, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2443: (B:119-129): The type of this parameter, struct C.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -20,4 +20,4 @@ contract Test {
}
}
// ----
// TypeError 2443: (B:166-175): The type of this parameter, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2443: (B:166-175): The type of this parameter, struct C.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -14,4 +14,4 @@ contract D {
}
}
// ----
// TypeError 2428: (B:85-105): The type of return parameter 1, string[], is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:85-105): The type of return parameter 1, string[] memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -18,4 +18,4 @@ contract Test {
}
}
// ----
// TypeError 2428: (B:90-112): The type of return parameter 1, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:90-112): The type of return parameter 1, struct C.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -18,4 +18,4 @@ contract Test {
}
}
// ----
// TypeError 2428: (B:90-112): The type of return parameter 1, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:90-112): The type of return parameter 1, struct C.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -17,4 +17,4 @@ contract Test {
}
}
// ----
// TypeError 2443: (B:94-104): The type of this parameter, struct L.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2443: (B:94-104): The type of this parameter, struct L.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -20,4 +20,4 @@ contract D {
}
}
// ----
// TypeError 2428: (B:106-117): The type of return parameter 1, struct L.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:106-117): The type of return parameter 1, struct L.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -18,4 +18,4 @@ contract Test {
}
}
// ----
// TypeError 2428: (B:90-97): The type of return parameter 1, struct L.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:90-97): The type of return parameter 1, struct L.Item memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -10,4 +10,4 @@ contract C {
// ====
// EVMVersion: <byzantium
// ----
// TypeError 9574: (166-196): Type inaccessible dynamic type is not implicitly convertible to expected type uint256[] memory[] memory.
// TypeError 9574: (166-196): Type inaccessible dynamic type is not implicitly convertible to expected type uint256[][] memory.

View File

@ -29,4 +29,4 @@ contract C is B {
{}
}
// ----
// TypeError 2428: (B:80-102): The type of return parameter 1, struct Data, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:80-102): The type of return parameter 1, struct Data memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -30,4 +30,4 @@ contract C is B {
{}
}
// ----
// TypeError 2428: (B:80-102): The type of return parameter 1, struct Data, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
// TypeError 2428: (B:80-102): The type of return parameter 1, struct Data memory, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.

View File

@ -5,4 +5,4 @@ contract C {
}
}
// ----
// TypeError 4259: (93-98): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(bytes) provided.
// TypeError 4259: (93-98): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(bytes storage pointer) provided.

View File

@ -9,6 +9,6 @@ contract C {
}
}
// ----
// TypeError 8015: (233-236): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[] provided.
// TypeError 8015: (248-249): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes1[] provided.
// TypeError 8015: (251-253): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but string provided.
// TypeError 8015: (233-236): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[] memory provided.
// TypeError 8015: (248-249): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes1[] memory provided.
// TypeError 8015: (251-253): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but string calldata provided.

View File

@ -32,9 +32,9 @@ contract C {
// TypeError 8015: (438-440): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address payable provided.
// TypeError 8015: (442-446): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () external provided.
// TypeError 8015: (448-452): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
// TypeError 8015: (454-462): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[] provided.
// TypeError 8015: (464-471): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[2] provided.
// TypeError 8015: (454-462): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[] memory provided.
// TypeError 8015: (464-471): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[2] memory provided.
// TypeError 8015: (473-474): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.
// TypeError 8015: (476-477): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S provided.
// TypeError 8015: (476-477): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S memory provided.
// TypeError 8015: (479-480): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.
// TypeError 8015: (482-483): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but mapping(uint256 => enum C.E) provided.

View File

@ -46,13 +46,13 @@ contract C {
// TypeError 8015: (404-448): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 2494...(42 digits omitted)...0497 provided.
// TypeError 8015: (495-561): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 3027...(66 digits omitted)...5855 provided.
// TypeError 8015: (596-663): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const -1 provided.
// TypeError 8015: (697-782): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes slice provided.
// TypeError 8015: (697-782): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes memory slice provided.
// TypeError 8015: (796-797): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
// TypeError 8015: (811-813): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple() provided.
// TypeError 8015: (827-833): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple(int_const 0,int_const 0) provided.
// TypeError 8015: (847-850): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] provided.
// TypeError 8015: (864-870): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] slice provided.
// TypeError 8015: (847-850): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] memory provided.
// TypeError 8015: (864-870): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] memory slice provided.
// TypeError 8015: (884-890): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.
// TypeError 8015: (904-911): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.
// TypeError 8015: (925-929): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S provided.
// TypeError 8015: (925-929): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S memory provided.
// TypeError 8015: (943-946): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.

View File

@ -3,4 +3,4 @@ library L {
function f(mapping(uint => uint)[2] memory a) external pure returns (mapping(uint => uint)[2] memory) {}
}
// ----
// TypeError 4061: (61-94): Type mapping(uint256 => uint256)[2] is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (61-94): Type mapping(uint256 => uint256)[2] memory is only valid in storage because it contains a (nested) mapping.

View File

@ -0,0 +1,12 @@
interface MyInterface {
error MyCustomError(uint256, bool);
}
contract MyContract {
function f(bytes4 arg) public {}
function test() public {
f(MyInterface.MyCustomError);
}
}
// ----
// TypeError 9553: (165-190): Invalid type for argument in function call. Invalid implicit conversion from error MyCustomError(uint256,bool) to bytes4 requested.

View File

@ -0,0 +1,11 @@
interface MyInterface {
error MyCustomError(uint256, bool);
}
contract Test {
function test() public returns(bytes4) {
return (MyInterface.MyCustomError);
}
}
// ----
// TypeError 6359: (143-170): Return argument type error MyCustomError(uint256,bool) is not implicitly convertible to expected type (type of first return variable) bytes4.

View File

@ -0,0 +1,9 @@
contract MyContract {
event MyCustomEvent(uint256);
function f(bytes4 arg) public {}
function test() public {
f(MyCustomEvent);
}
}
// ----
// TypeError 9553: (132-145): Invalid type for argument in function call. Invalid implicit conversion from event MyCustomEvent(uint256) to bytes4 requested.

View File

@ -0,0 +1,9 @@
contract Test {
event MyCustomEvent(uint256);
function test() public returns(bytes4) {
return (MyCustomEvent);
}
}
// ----
// TypeError 6359: (111-126): Return argument type event MyCustomEvent(uint256) is not implicitly convertible to expected type (type of first return variable) bytes4.

View File

@ -6,4 +6,4 @@ contract C {
}
}
// ----
// TypeError 6359: (122-147): Return argument type string memory[5] memory is not implicitly convertible to expected type (type of first return variable) string calldata[5] calldata.
// TypeError 6359: (122-147): Return argument type string[5] memory is not implicitly convertible to expected type (type of first return variable) string[5] calldata.

View File

@ -0,0 +1,9 @@
error MyCustomError(uint, bool);
contract C {
function f() public {
bytes memory a;
bytes memory b = type(MyCustomError).concat(a);
}
}
// ----
// TypeError 4259: (126-139): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but error MyCustomError(uint256,bool) provided.

View File

@ -0,0 +1,8 @@
error MyCustomError(uint, bool);
contract Test {
function f() public {
abi.decode(MyCustomError, (bool));
}
}
// ----
// TypeError 1956: (94-107): The first argument to "abi.decode" must be implicitly convertible to bytes memory or bytes calldata, but is of type error MyCustomError(uint256,bool).

View File

@ -0,0 +1,10 @@
error MyCustomError(uint, bool);
contract C {
function f() pure public {
bytes.concat(MyCustomError, MyCustomError);
}
}
// ----
// TypeError 8015: (99-112): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but error MyCustomError(uint256,bool) provided.
// TypeError 8015: (114-127): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but error MyCustomError(uint256,bool) provided.

View File

@ -0,0 +1,40 @@
error MyCustomError(uint, bool);
contract C {
enum testEnum { choice1, choice2, choice3 }
function f1(uint8, uint8) external {}
function f2(uint32) external {}
function f3(uint) external {}
function g1(bytes memory) external {}
function g2(bytes32) external {}
function h(string memory) external {}
function i(bool) external {}
function j(address) external {}
function k(address payable) external {}
function l(testEnum) external {}
function f() pure public {
abi.encodeCall(this.f1, (MyCustomError, MyCustomError));
abi.encodeCall(this.f2, (MyCustomError));
abi.encodeCall(this.f3, (MyCustomError));
abi.encodeCall(this.g1, (MyCustomError));
abi.encodeCall(this.g2, (MyCustomError));
abi.encodeCall(this.h, (MyCustomError));
abi.encodeCall(this.i, (MyCustomError));
abi.encodeCall(this.j, (MyCustomError));
abi.encodeCall(this.k, (MyCustomError));
abi.encodeCall(this.l, (MyCustomError));
}
}
// ----
// TypeError 5407: (543-556): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "uint8".
// TypeError 5407: (558-571): Cannot implicitly convert component at position 1 from "error MyCustomError(uint256,bool)" to "uint8".
// TypeError 5407: (607-622): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "uint32".
// TypeError 5407: (657-672): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "uint256".
// TypeError 5407: (707-722): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "bytes memory".
// TypeError 5407: (757-772): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "bytes32".
// TypeError 5407: (806-821): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "string memory".
// TypeError 5407: (855-870): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "bool".
// TypeError 5407: (904-919): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "address".
// TypeError 5407: (953-968): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "address payable".
// TypeError 5407: (1002-1017): Cannot implicitly convert component at position 0 from "error MyCustomError(uint256,bool)" to "enum C.testEnum".

View File

@ -0,0 +1,47 @@
error MyCustomError(uint, bool);
contract C {
function f() pure public {
MyCustomError << MyCustomError;
MyCustomError >> MyCustomError;
MyCustomError ^ MyCustomError;
MyCustomError | MyCustomError;
MyCustomError & MyCustomError;
MyCustomError * MyCustomError;
MyCustomError / MyCustomError;
MyCustomError % MyCustomError;
MyCustomError + MyCustomError;
MyCustomError - MyCustomError;
MyCustomError == MyCustomError;
MyCustomError != MyCustomError;
MyCustomError >= MyCustomError;
MyCustomError <= MyCustomError;
MyCustomError < MyCustomError;
MyCustomError > MyCustomError;
MyCustomError || MyCustomError;
MyCustomError && MyCustomError;
}
}
// ----
// TypeError 2271: (86-116): Operator << not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (126-156): Operator >> not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (166-195): Operator ^ not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (205-234): Operator | not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (244-273): Operator & not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (284-313): Operator * not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (323-352): Operator / not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (362-391): Operator % not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (401-430): Operator + not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (440-469): Operator - not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (480-510): Operator == not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (520-550): Operator != not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (560-590): Operator >= not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (600-630): Operator <= not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (640-669): Operator < not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (679-708): Operator > not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (719-749): Operator || not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)
// TypeError 2271: (759-789): Operator && not compatible with types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool)

View File

@ -0,0 +1,19 @@
error MyCustomError(uint, bool);
contract C {
function f() pure public {
uint a;
MyCustomError += 1;
MyCustomError -= 1;
a += MyCustomError;
a -= MyCustomError;
}
}
// ----
// TypeError 4247: (102-115): Expression has to be an lvalue.
// TypeError 7366: (102-120): Operator += not compatible with types error MyCustomError(uint256,bool) and int_const 1
// TypeError 4247: (130-143): Expression has to be an lvalue.
// TypeError 7366: (130-148): Operator -= not compatible with types error MyCustomError(uint256,bool) and int_const 1
// TypeError 7366: (158-176): Operator += not compatible with types uint256 and error MyCustomError(uint256,bool)
// TypeError 7366: (186-204): Operator -= not compatible with types uint256 and error MyCustomError(uint256,bool)

View File

@ -0,0 +1,11 @@
error MyCustomError(uint, bool);
contract C {
function f() pure public {
MyCustomError++;
}
}
// ----
// TypeError 4247: (86-99): Expression has to be an lvalue.
// TypeError 9767: (86-101): Unary operator ++ cannot be applied to type error MyCustomError(uint256,bool)

View File

@ -0,0 +1,9 @@
error MyCustomError(uint, bool);
contract B {
function f() mod1(MyCustomError) public { }
modifier mod1(uint a) { if (a > 0) _; }
}
// ----
// TypeError 4649: (69-82): Invalid type for argument in modifier invocation. Invalid implicit conversion from error MyCustomError(uint256,bool) to uint256 requested.

View File

@ -0,0 +1,10 @@
error MyCustomError(uint, bool);
contract C {
function f() public returns (uint8, uint8, int) {
return ((MyCustomError, 8, MyCustomError));
}
}
// ----
// TypeError 5992: (116-151): Return argument type tuple(error MyCustomError(uint256,bool),int_const 8,error MyCustomError(uint256,bool)) is not implicitly convertible to expected type tuple(uint8,uint8,int256).

View File

@ -0,0 +1,18 @@
error MyCustomError(uint, bool);
error MyCustomError2(uint, bool);
error MyCustomError3(uint, bool, bool);
contract C {
function f() pure public {
true ? MyCustomError : MyCustomError;
true ? MyCustomError : MyCustomError2;
true ? MyCustomError : MyCustomError3;
true ? MyCustomError : true;
true ? true : MyCustomError;
}
}
// ----
// TypeError 1080: (253-290): True expression's type error MyCustomError(uint256,bool) does not match false expression's type error MyCustomError3(uint256,bool,bool).
// TypeError 1080: (300-327): True expression's type error MyCustomError(uint256,bool) does not match false expression's type bool.
// TypeError 1080: (337-364): True expression's type bool does not match false expression's type error MyCustomError(uint256,bool).

View File

@ -0,0 +1,7 @@
error E();
contract C {
function() internal pure x = E;
}
// ----
// TypeError 7407: (58-59): Type error E() is not implicitly convertible to expected type function () pure. Special functions can not be converted to function types.

View File

@ -0,0 +1,10 @@
error MyCustomError(uint, bool);
contract C {
function f() public {
bytes4 a = MyCustomError;
}
}
// ----
// TypeError 9574: (81-105): Type error MyCustomError(uint256,bool) is not implicitly convertible to expected type bytes4.

View File

@ -0,0 +1,10 @@
error MyCustomError(uint, bool);
contract Base {
constructor(uint8) {}
}
contract Derived is Base(MyCustomError) {}
// ----
// TypeError 9827: (104-117): Invalid type for argument in constructor call. Invalid implicit conversion from error MyCustomError(uint256,bool) to uint8 requested.

View File

@ -9,4 +9,4 @@ contract C {
}
}
// ----
// TypeError 9582: (133-136): Member "f" not found or not visible after argument-dependent lookup in function (uint256) pure.
// TypeError 9582: (133-136): Member "f" not found or not visible after argument-dependent lookup in error E(uint256).

View File

@ -0,0 +1,9 @@
contract C {
event MyCustomEvent(uint);
function f() public {
bytes memory a;
bytes memory b = type(MyCustomEvent).concat(a);
}
}
// ----
// TypeError 4259: (124-137): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but event MyCustomEvent(uint256) provided.

View File

@ -0,0 +1,8 @@
contract Test {
event E(uint);
function f() public {
abi.decode(E, (bool));
}
}
// ----
// TypeError 1956: (80-81): The first argument to "abi.decode" must be implicitly convertible to bytes memory or bytes calldata, but is of type event E(uint256).

View File

@ -0,0 +1,9 @@
contract C {
event MyCustomEvent(uint);
function f() pure public {
bytes.concat(MyCustomEvent, MyCustomEvent);
}
}
// ----
// TypeError 8015: (96-109): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but event MyCustomEvent(uint256) provided.
// TypeError 8015: (111-124): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but event MyCustomEvent(uint256) provided.

View File

@ -0,0 +1,41 @@
contract C {
event MyCustomEvent(uint);
enum testEnum { choice1, choice2, choice3 }
function f1(uint8, uint8) external {}
function f2(uint32) external {}
function f3(uint) external {}
function g1(bytes memory) external {}
function g2(bytes32) external {}
function h(string memory) external {}
function i(bool) external {}
function j(address) external {}
function k(address payable) external {}
function l(testEnum) external {}
function f() pure public {
abi.encodeCall(this.f1, (MyCustomEvent, MyCustomEvent));
abi.encodeCall(this.f2, (MyCustomEvent));
abi.encodeCall(this.f3, (MyCustomEvent));
abi.encodeCall(this.g1, (MyCustomEvent));
abi.encodeCall(this.g2, (MyCustomEvent));
abi.encodeCall(this.h, (MyCustomEvent));
abi.encodeCall(this.i, (MyCustomEvent));
abi.encodeCall(this.j, (MyCustomEvent));
abi.encodeCall(this.k, (MyCustomEvent));
abi.encodeCall(this.l, (MyCustomEvent));
}
}
// ----
// TypeError 5407: (542-555): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "uint8".
// TypeError 5407: (557-570): Cannot implicitly convert component at position 1 from "event MyCustomEvent(uint256)" to "uint8".
// TypeError 5407: (606-621): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "uint32".
// TypeError 5407: (656-671): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "uint256".
// TypeError 5407: (706-721): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "bytes memory".
// TypeError 5407: (756-771): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "bytes32".
// TypeError 5407: (805-820): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "string memory".
// TypeError 5407: (854-869): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "bool".
// TypeError 5407: (903-918): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "address".
// TypeError 5407: (952-967): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "address payable".
// TypeError 5407: (1001-1016): Cannot implicitly convert component at position 0 from "event MyCustomEvent(uint256)" to "enum C.testEnum".

View File

@ -0,0 +1,46 @@
contract C {
event MyCustomEvent(uint);
function f() pure public {
MyCustomEvent << MyCustomEvent;
MyCustomEvent >> MyCustomEvent;
MyCustomEvent ^ MyCustomEvent;
MyCustomEvent | MyCustomEvent;
MyCustomEvent & MyCustomEvent;
MyCustomEvent * MyCustomEvent;
MyCustomEvent / MyCustomEvent;
MyCustomEvent % MyCustomEvent;
MyCustomEvent + MyCustomEvent;
MyCustomEvent - MyCustomEvent;
MyCustomEvent == MyCustomEvent;
MyCustomEvent != MyCustomEvent;
MyCustomEvent >= MyCustomEvent;
MyCustomEvent <= MyCustomEvent;
MyCustomEvent < MyCustomEvent;
MyCustomEvent > MyCustomEvent;
MyCustomEvent || MyCustomEvent;
MyCustomEvent && MyCustomEvent;
}
}
// ----
// TypeError 2271: (83-113): Operator << not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (123-153): Operator >> not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (163-192): Operator ^ not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (202-231): Operator | not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (241-270): Operator & not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (281-310): Operator * not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (320-349): Operator / not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (359-388): Operator % not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (398-427): Operator + not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (437-466): Operator - not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (477-507): Operator == not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (517-547): Operator != not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (557-587): Operator >= not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (597-627): Operator <= not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (637-666): Operator < not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (676-705): Operator > not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (716-746): Operator || not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)
// TypeError 2271: (756-786): Operator && not compatible with types event MyCustomEvent(uint256) and event MyCustomEvent(uint256)

View File

@ -0,0 +1,18 @@
contract C {
event MyCustomEvent(uint);
function f() pure public {
uint a;
MyCustomEvent += 1;
MyCustomEvent -= 1;
a += MyCustomEvent;
a -= MyCustomEvent;
}
}
// ----
// TypeError 4247: (99-112): Expression has to be an lvalue.
// TypeError 7366: (99-117): Operator += not compatible with types event MyCustomEvent(uint256) and int_const 1
// TypeError 4247: (127-140): Expression has to be an lvalue.
// TypeError 7366: (127-145): Operator -= not compatible with types event MyCustomEvent(uint256) and int_const 1
// TypeError 7366: (155-173): Operator += not compatible with types uint256 and event MyCustomEvent(uint256)
// TypeError 7366: (183-201): Operator -= not compatible with types uint256 and event MyCustomEvent(uint256)

View File

@ -0,0 +1,10 @@
contract C {
event MyCustomEvent(uint);
function f() pure public {
MyCustomEvent++;
}
}
// ----
// TypeError 4247: (83-96): Expression has to be an lvalue.
// TypeError 9767: (83-98): Unary operator ++ cannot be applied to type event MyCustomEvent(uint256)

View File

@ -0,0 +1,8 @@
contract B {
event MyCustomEvent(uint);
function f() mod1(MyCustomEvent) public { }
modifier mod1(uint a) { if (a > 0) _; }
}
// ----
// TypeError 4649: (66-79): Invalid type for argument in modifier invocation. Invalid implicit conversion from event MyCustomEvent(uint256) to uint256 requested.

View File

@ -0,0 +1,9 @@
contract C {
event MyCustomEvent(uint);
function f() public returns (uint8, uint8, int) {
return ((MyCustomEvent, 8, MyCustomEvent));
}
}
// ----
// TypeError 5992: (113-148): Return argument type tuple(event MyCustomEvent(uint256),int_const 8,event MyCustomEvent(uint256)) is not implicitly convertible to expected type tuple(uint8,uint8,int256).

View File

@ -8,4 +8,4 @@ contract D {
}
}
// ----
// TypeError 9582: (123-135): Member "selector" not found or not visible after argument-dependent lookup in function ().
// TypeError 9582: (123-135): Member "selector" not found or not visible after argument-dependent lookup in event E().

View File

@ -10,4 +10,4 @@ contract C {
}
}
// ----
// TypeError 9582: (70-82): Member "selector" not found or not visible after argument-dependent lookup in function ().
// TypeError 9582: (70-82): Member "selector" not found or not visible after argument-dependent lookup in event E().

View File

@ -0,0 +1,17 @@
contract C {
event MyCustomEvent(uint);
event MyCustomEvent2(uint);
event MyCustomEvent3(uint, bool);
function f() pure public {
true ? MyCustomEvent : MyCustomEvent;
true ? MyCustomEvent : MyCustomEvent2;
true ? MyCustomEvent : MyCustomEvent3;
true ? MyCustomEvent : true;
true ? true : MyCustomEvent;
}
}
// ----
// TypeError 1080: (246-283): True expression's type event MyCustomEvent(uint256) does not match false expression's type event MyCustomEvent3(uint256,bool).
// TypeError 1080: (293-320): True expression's type event MyCustomEvent(uint256) does not match false expression's type bool.
// TypeError 1080: (330-357): True expression's type bool does not match false expression's type event MyCustomEvent(uint256).

View File

@ -1,7 +1,7 @@
error E();
contract C {
event E(uint);
function() internal pure x = E;
}
// ----
// TypeError 7407: (58-59): Type function () pure is not implicitly convertible to expected type function () pure. Special functions can not be converted to function types.
// TypeError 7407: (66-67): Type event E(uint256) is not implicitly convertible to expected type function () pure. Special functions can not be converted to function types.

View File

@ -0,0 +1,9 @@
contract C {
event MyCustomEvent(uint);
function f() public {
bytes4 a = MyCustomEvent;
}
}
// ----
// TypeError 9574: (78-102): Type event MyCustomEvent(uint256) is not implicitly convertible to expected type bytes4.

View File

@ -0,0 +1,9 @@
contract Base {
event MyCustomEvent(uint);
constructor(uint8) {}
}
contract Derived is Base(Base.MyCustomEvent) {}
// ----
// TypeError 9827: (101-119): Invalid type for argument in constructor call. Invalid implicit conversion from event MyCustomEvent(uint256) to uint8 requested.

View File

@ -4,4 +4,4 @@
}
}
// ----
// TypeError 4061: (91-136): Type mapping(string => uint24)[1] is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (91-136): Type mapping(string => uint24)[1] memory is only valid in storage because it contains a (nested) mapping.

View File

@ -11,4 +11,4 @@ contract Test {
}
// ----
// DeclarationError 2333: (157-198): Identifier already declared.
// TypeError 4061: (268-300): Type struct Test.RecursiveStruct[1] is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (268-300): Type struct Test.RecursiveStruct[1] memory is only valid in storage because it contains a (nested) mapping.

View File

@ -0,0 +1,11 @@
interface MyInterface {
error MyCustomError(uint256, bool);
}
contract MyContract {
function test() public {
MyInterface.MyCustomError[];
}
}
// ----
// TypeError 2614: (126-151): Indexed expression has to be a type, mapping or array (is error MyCustomError(uint256,bool))

View File

@ -0,0 +1,8 @@
contract MyContract {
event MyCustomEvent(uint256);
function test() public {
MyCustomEvent[];
}
}
// ----
// TypeError 2614: (93-106): Indexed expression has to be a type, mapping or array (is event MyCustomEvent(uint256))

View File

@ -9,4 +9,4 @@ contract Test {
}
}
// ----
// TypeError 4061: (161-172): Type struct Test.S2 is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (161-172): Type struct Test.S2 memory is only valid in storage because it contains a (nested) mapping.

View File

@ -6,4 +6,4 @@ contract Test {
}
}
// ----
// TypeError 4061: (104-114): Type struct Test.S is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (104-114): Type struct Test.S memory is only valid in storage because it contains a (nested) mapping.

View File

@ -6,4 +6,4 @@ contract Test {
}
}
// ----
// TypeError 4259: (154-155): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(struct Test.S) provided.
// TypeError 4259: (154-155): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(struct Test.S storage pointer) provided.

View File

@ -4,4 +4,4 @@ contract C {
}
}
// ----
// TypeError 4061: (47-77): Type mapping(uint256 => uint256)[] is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (47-77): Type mapping(uint256 => uint256)[] memory is only valid in storage because it contains a (nested) mapping.

View File

@ -0,0 +1,9 @@
error MyCustomError(uint, bool);
contract Test {
function f() public {
uint[] memory a;
a[MyCustomError];
}
}
// ----
// TypeError 7407: (110-123): Type error MyCustomError(uint256,bool) is not implicitly convertible to expected type uint256.

View File

@ -0,0 +1,9 @@
contract Test {
event MyCustomEvent(uint);
function f() public {
uint[] memory a;
a[MyCustomEvent];
}
}
// ----
// TypeError 7407: (108-121): Type event MyCustomEvent(uint256) is not implicitly convertible to expected type uint256.

View File

@ -5,4 +5,4 @@ contract C {
}
}
// ----
// TypeError 9611: (92-101): Decoding type uint256[] memory[3] memory not supported.
// TypeError 9611: (92-101): Decoding type uint256[][3] memory not supported.

View File

@ -3,4 +3,4 @@ contract test {
}
}
// ----
// TypeError 4061: (31-64): Type mapping(uint256 => uint256)[2] is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (31-64): Type mapping(uint256 => uint256)[2] memory is only valid in storage because it contains a (nested) mapping.

View File

@ -4,4 +4,4 @@ library L {
function f(S memory a) external pure returns (S memory) {}
}
// ----
// TypeError 4061: (103-113): Type struct L.S is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (103-113): Type struct L.S memory is only valid in storage because it contains a (nested) mapping.

View File

@ -17,4 +17,4 @@ contract Test {
}
}
// ----
// TypeError 4061: (143-153): Type struct Test.S is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (143-153): Type struct Test.S memory is only valid in storage because it contains a (nested) mapping.

View File

@ -12,4 +12,4 @@ contract Test {
}
// ----
// TypeError 4061: (172-182): Type struct Test.S is only valid in storage because it contains a (nested) mapping.
// TypeError 4061: (172-182): Type struct Test.S memory is only valid in storage because it contains a (nested) mapping.