From 5ecd2f22872c98b58849d4c55153c6466014ac5f Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 17 Aug 2021 16:27:29 +0200 Subject: [PATCH] Move error message somewhere else. --- libsolidity/analysis/TypeChecker.cpp | 87 +++++++--------------------- libsolidity/ast/Types.cpp | 22 +++++-- 2 files changed, 37 insertions(+), 72 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 7f36746d3..3cb8a7970 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1152,7 +1152,8 @@ void TypeChecker::endVisit(Return const& _return) "Return argument type " + type(*_return.expression())->toString() + " is not implicitly convertible to expected type " + - TupleType(returnTypes).toString(false) + ".", + TupleType(returnTypes).toString(false) + + ".", result.message() ); } @@ -1170,7 +1171,8 @@ void TypeChecker::endVisit(Return const& _return) "Return argument type " + type(*_return.expression())->toString() + " is not implicitly convertible to expected type (type of first return variable) " + - expected->toString() + ".", + expected->toString() + + ".", result.message() ); } @@ -1264,41 +1266,16 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) var.accept(*this); BoolResult result = valueComponentType->isImplicitlyConvertibleTo(*var.annotation().type); if (!result) - { - auto errorMsg = "Type " + + m_errorReporter.typeErrorConcatenateDescriptions( + 9574_error, + _statement.location(), + "Type " + valueComponentType->toString() + " is not implicitly convertible to expected type " + - var.annotation().type->toString(); - if ( - valueComponentType->category() == Type::Category::RationalNumber && - dynamic_cast(*valueComponentType).isFractional() && - valueComponentType->mobileType() - ) - { - if (var.annotation().type->operator==(*valueComponentType->mobileType())) - m_errorReporter.typeError( - 5107_error, - _statement.location(), - errorMsg + ", but it can be explicitly converted." - ); - else - m_errorReporter.typeError( - 4486_error, - _statement.location(), - errorMsg + - ". Try converting to type " + - valueComponentType->mobileType()->toString() + - " or use an explicit conversion." - ); - } - else - m_errorReporter.typeErrorConcatenateDescriptions( - 9574_error, - _statement.location(), - errorMsg + ".", - result.message() - ); - } + var.annotation().type->toString() + + ".", + result.message() + ); } if (valueTypes.size() != variables.size()) @@ -3449,40 +3426,16 @@ bool TypeChecker::expectType(Expression const& _expression, Type const& _expecte BoolResult result = type(_expression)->isImplicitlyConvertibleTo(_expectedType); if (!result) { - auto errorMsg = "Type " + + m_errorReporter.typeErrorConcatenateDescriptions( + 7407_error, + _expression.location(), + "Type " + type(_expression)->toString() + " is not implicitly convertible to expected type " + - _expectedType.toString(); - if ( - type(_expression)->category() == Type::Category::RationalNumber && - dynamic_cast(type(_expression))->isFractional() && - type(_expression)->mobileType() - ) - { - if (_expectedType.operator==(*type(_expression)->mobileType())) - m_errorReporter.typeError( - 4426_error, - _expression.location(), - errorMsg + ", but it can be explicitly converted." - ); - else - m_errorReporter.typeErrorConcatenateDescriptions( - 2326_error, - _expression.location(), - errorMsg + - ". Try converting to type " + - type(_expression)->mobileType()->toString() + - " or use an explicit conversion.", - result.message() - ); - } - else - m_errorReporter.typeErrorConcatenateDescriptions( - 7407_error, - _expression.location(), - errorMsg + ".", - result.message() - ); + _expectedType.toString() + + ".", + result.message() + ); return false; } return true; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 59540e677..6fc50296a 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -954,7 +954,7 @@ BoolResult RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) case Category::Integer: { if (isFractional()) - return false; + return BoolResult::err("Rational number is fractional, use an explicit conversion instead."); IntegerType const& targetType = dynamic_cast(_convertTo); return fitsIntegerType(m_value.numerator(), targetType); } @@ -963,14 +963,26 @@ BoolResult RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) FixedPointType const& targetType = dynamic_cast(_convertTo); // Store a negative number into an unsigned. if (isNegative() && !targetType.isSigned()) - return false; + return BoolResult::err("Rational number is negative, use a signed fixed point type instead."); if (!isFractional()) - return (targetType.minIntegerValue() <= m_value) && (m_value <= targetType.maxIntegerValue()); + { + if (m_value < targetType.minIntegerValue()) + return BoolResult::err("Number is too small for type."); + else if (m_value > targetType.maxIntegerValue()) + return BoolResult::err("Number is too large for type."); + else + return true; + } rational value = m_value * pow(bigint(10), targetType.fractionalDigits()); // Need explicit conversion since truncation will occur. if (value.denominator() != 1) - return false; - return fitsIntoBits(value.numerator(), targetType.numBits(), targetType.isSigned()); + return BoolResult::err("Conversion incurs precision loss. Use an explicit conversion instead."); + if (m_value < targetType.minValue()) + return BoolResult::err("Number is too small for type."); + else if (m_value > targetType.maxValue()) + return BoolResult::err("Number is too large for type."); + solAssert(fitsIntoBits(value.numerator(), targetType.numBits(), targetType.isSigned()), ""); + return true; } case Category::FixedBytes: return (m_value == rational(0)) || (m_compatibleBytesType && *m_compatibleBytesType == _convertTo);