From 0f55a4d671d2991a67f0205917600abe66150d76 Mon Sep 17 00:00:00 2001 From: wechman Date: Fri, 3 Jun 2022 07:42:25 +0200 Subject: [PATCH] Update code after review --- libsolidity/analysis/TypeChecker.cpp | 11 +-- libsolidity/ast/Types.cpp | 70 +++++++++---------- libsolidity/codegen/ABIFunctions.cpp | 3 +- .../return_tuple_not_convertible.sol | 2 +- 4 files changed, 42 insertions(+), 44 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 39023a564..f8b5b8b55 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -68,8 +68,10 @@ bool TypeChecker::typeSupportedByOldABIEncoder(Type const& _type, bool _isLibrar } if (_type.category() == Type::Category::InlineArray) { - auto const& inlineArray = dynamic_cast(_type); - return typeSupportedByOldABIEncoder(*inlineArray.mobileType(), _isLibraryCall); + auto const& mobileType = dynamic_cast(_type).mobileType(); + if (!mobileType) + return false; + return typeSupportedByOldABIEncoder(*mobileType, _isLibraryCall); } return true; } @@ -1208,7 +1210,7 @@ void TypeChecker::endVisit(Return const& _return) _return.expression()->location(), "Return argument type " + type(*_return.expression())->toString() + - " is not implicitly convertible to expected type " + + " is not implicitly convertible to expected type (type of first return variable) " + TupleType(returnTypes).toString(false) + ".", result.message() ); @@ -3259,13 +3261,12 @@ bool TypeChecker::visit(IndexAccess const& _access) } case Type::Category::InlineArray: { - InlineArrayType const& actualType = dynamic_cast(*baseType); if (!index) m_errorReporter.typeError(5093_error, _access.location(), "Index expression cannot be omitted."); else expectType(*index, *TypeProvider::uint256()); - resultType = actualType.componentsCommonMobileType(); + resultType = dynamic_cast(*baseType).componentsCommonMobileType(); break; } case Type::Category::Mapping: diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index ad33ade51..fb6cf0d78 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -316,15 +316,6 @@ Type const* Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c return encodingType; Type const* baseType = encodingType; - if (auto const inlineArray = dynamic_cast(baseType)) - { - baseType = TypeProvider::array( - DataLocation::Memory, - inlineArray->componentsCommonMobileType(), - inlineArray->components().size() - ); - } - while (auto const* arrayType = dynamic_cast(baseType)) { baseType = arrayType->baseType(); @@ -2714,26 +2705,25 @@ BoolResult InlineArrayType::isImplicitlyConvertibleTo(Type const& _other) const if (!arrayType || arrayType->isByteArrayOrString()) return BoolResult::err("Array literal can not be converted to byte array or string."); - else + + if (!arrayType->isDynamicallySized() && arrayType->length() != components().size()) + return BoolResult::err( + "Number of components in array literal (" + to_string(components().size()) + ") " + + "does not match array size (" + to_string(arrayType->length().convert_to()) + ")." + ); + + for (Type const* c: components()) { - if (!arrayType->isDynamicallySized() && arrayType->length() != components().size()) + BoolResult result = c->isImplicitlyConvertibleTo(*arrayType->baseType()); + if (!result) return BoolResult::err( - "Number of components in array literal (" + to_string(components().size()) + ") " + - "does not match array size (" + to_string(arrayType->length().convert_to()) + ")."); - - for (Type const* c: components()) - { - BoolResult result = c->isImplicitlyConvertibleTo(*arrayType->baseType()); - if (!result) - if (!result) - return BoolResult::err( - "Invalid conversion from " + c->toString(false) + - " to " + arrayType->baseType()->toString(false) + "." - + (result.message().empty() ? "" : " ") + result.message() ); - } - - return true; + "Invalid conversion from " + c->toString(false) + + " to " + arrayType->baseType()->toString(false) + "." + + (result.message().empty() ? "" : " ") + result.message() + ); } + + return true; } string InlineArrayType::richIdentifier() const @@ -2744,8 +2734,17 @@ string InlineArrayType::richIdentifier() const bool InlineArrayType::operator==(Type const& _other) const { if (auto inlineArrayType = dynamic_cast(&_other)) - // TODO: raise issue - do not compare by pointer for tuple type - return components() == inlineArrayType->components(); + { + std::vector const& otherComponents = inlineArrayType->components(); + if (m_components.size() != otherComponents.size()) + return false; + + for (unsigned i = 0; i < m_components.size(); ++i) + if (!(*m_components[i] == *otherComponents[i])) + return false; + + return true; + } else return false; } @@ -2753,11 +2752,8 @@ bool InlineArrayType::operator==(Type const& _other) const string InlineArrayType::toString(bool _short) const { vector result; - for (auto const& t: components()) result.push_back(t->toString(_short)); - - // TODO joinHumanReadable - is it fine to have a space here? return "inline_array(" + util::joinHumanReadable(result) + ")"; } @@ -2768,12 +2764,12 @@ u256 InlineArrayType::storageSize() const Type const* InlineArrayType::mobileType() const { - return TypeProvider::array( - DataLocation::Memory, - componentsCommonMobileType(), - components().size() - ); -} + Type const* baseType = componentsCommonMobileType(); + return + baseType ? + TypeProvider::array(DataLocation::Memory, baseType, components().size()) : + nullptr; + } Type const* InlineArrayType::componentsCommonMobileType() const { diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 01a7c39e5..e67c2a8e2 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -293,7 +293,8 @@ string ABIFunctions::abiEncodingFunction( return abiEncodingFunctionInlineArray( dynamic_cast(_from), dynamic_cast(_to), - _options); + _options + ); } else if (auto toArray = dynamic_cast(&to)) diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_tuple_not_convertible.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_tuple_not_convertible.sol index a6160b322..e7398bb8b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_tuple_not_convertible.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_tuple_not_convertible.sol @@ -2,4 +2,4 @@ contract test { function f() public returns (uint256 r, uint8) { return ((12, "")); } } // ---- -// TypeError 5992: (76-86): Return argument type tuple(int_const 12,literal_string "") is not implicitly convertible to expected type tuple(uint256,uint8). +// TypeError 5992: (76-86): Return argument type tuple(int_const 12,literal_string "") is not implicitly convertible to expected type (type of first return variable) tuple(uint256,uint8).