mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Deprecate wildcard assignments.
This commit is contained in:
parent
506d82796d
commit
fe12f05c08
@ -6,6 +6,7 @@ Features:
|
|||||||
* Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).
|
* Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).
|
||||||
* Type Checker: Deprecate the ``years`` unit denomination and raise a warning for it (or an error as experimental 0.5.0 feature).
|
* Type Checker: Deprecate the ``years`` unit denomination and raise a warning for it (or an error as experimental 0.5.0 feature).
|
||||||
* Type Checker: Make literals (without explicit type casting) an error for tight packing as experimental 0.5.0 feature.
|
* Type Checker: Make literals (without explicit type casting) an error for tight packing as experimental 0.5.0 feature.
|
||||||
|
* Type Checker: Warn about wildcard tuple assignments (this will turn into an error with version 0.5.0).
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Type Checker: Show proper error when trying to ``emit`` a non-event.
|
* Type Checker: Show proper error when trying to ``emit`` a non-event.
|
||||||
|
@ -1076,6 +1076,7 @@ void TypeChecker::endVisit(EmitStatement const& _emit)
|
|||||||
|
|
||||||
bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
||||||
{
|
{
|
||||||
|
bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
|
||||||
if (!_statement.initialValue())
|
if (!_statement.initialValue())
|
||||||
{
|
{
|
||||||
// No initial value is only permitted for single variables with specified type.
|
// No initial value is only permitted for single variables with specified type.
|
||||||
@ -1092,7 +1093,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
if (varDecl.referenceLocation() == VariableDeclaration::Location::Default)
|
if (varDecl.referenceLocation() == VariableDeclaration::Location::Default)
|
||||||
errorText += " Did you mean '<type> memory " + varDecl.name() + "'?";
|
errorText += " Did you mean '<type> memory " + varDecl.name() + "'?";
|
||||||
solAssert(m_scope, "");
|
solAssert(m_scope, "");
|
||||||
if (m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
|
if (v050)
|
||||||
m_errorReporter.declarationError(varDecl.location(), errorText);
|
m_errorReporter.declarationError(varDecl.location(), errorText);
|
||||||
else
|
else
|
||||||
m_errorReporter.warning(varDecl.location(), errorText);
|
m_errorReporter.warning(varDecl.location(), errorText);
|
||||||
@ -1132,12 +1133,33 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
") in value for variable assignment (0) needed"
|
") in value for variable assignment (0) needed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (valueTypes.size() != variables.size() && !variables.front() && !variables.back())
|
else if (valueTypes.size() != variables.size())
|
||||||
m_errorReporter.fatalTypeError(
|
{
|
||||||
_statement.location(),
|
if (v050)
|
||||||
"Wildcard both at beginning and end of variable declaration list is only allowed "
|
m_errorReporter.fatalTypeError(
|
||||||
"if the number of components is equal."
|
_statement.location(),
|
||||||
);
|
"Different number of components on the left hand side (" +
|
||||||
|
toString(variables.size()) +
|
||||||
|
") than on the right hand side (" +
|
||||||
|
toString(valueTypes.size()) +
|
||||||
|
")."
|
||||||
|
);
|
||||||
|
else if (!variables.front() && !variables.back())
|
||||||
|
m_errorReporter.fatalTypeError(
|
||||||
|
_statement.location(),
|
||||||
|
"Wildcard both at beginning and end of variable declaration list is only allowed "
|
||||||
|
"if the number of components is equal."
|
||||||
|
);
|
||||||
|
else
|
||||||
|
m_errorReporter.warning(
|
||||||
|
_statement.location(),
|
||||||
|
"Different number of components on the left hand side (" +
|
||||||
|
toString(variables.size()) +
|
||||||
|
") than on the right hand side (" +
|
||||||
|
toString(valueTypes.size()) +
|
||||||
|
")."
|
||||||
|
);
|
||||||
|
}
|
||||||
size_t minNumValues = variables.size();
|
size_t minNumValues = variables.size();
|
||||||
if (!variables.empty() && (!variables.back() || !variables.front()))
|
if (!variables.empty() && (!variables.back() || !variables.front()))
|
||||||
--minNumValues;
|
--minNumValues;
|
||||||
@ -1335,6 +1357,7 @@ bool TypeChecker::visit(Conditional const& _conditional)
|
|||||||
|
|
||||||
bool TypeChecker::visit(Assignment const& _assignment)
|
bool TypeChecker::visit(Assignment const& _assignment)
|
||||||
{
|
{
|
||||||
|
bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
|
||||||
requireLValue(_assignment.leftHandSide());
|
requireLValue(_assignment.leftHandSide());
|
||||||
TypePointer t = type(_assignment.leftHandSide());
|
TypePointer t = type(_assignment.leftHandSide());
|
||||||
_assignment.annotation().type = t;
|
_assignment.annotation().type = t;
|
||||||
@ -1347,11 +1370,29 @@ bool TypeChecker::visit(Assignment const& _assignment)
|
|||||||
);
|
);
|
||||||
// Sequenced assignments of tuples is not valid, make the result a "void" type.
|
// Sequenced assignments of tuples is not valid, make the result a "void" type.
|
||||||
_assignment.annotation().type = make_shared<TupleType>();
|
_assignment.annotation().type = make_shared<TupleType>();
|
||||||
|
|
||||||
expectType(_assignment.rightHandSide(), *tupleType);
|
expectType(_assignment.rightHandSide(), *tupleType);
|
||||||
|
|
||||||
// expectType does not cause fatal errors, so we have to check again here.
|
// expectType does not cause fatal errors, so we have to check again here.
|
||||||
if (dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get()))
|
if (TupleType const* rhsType = dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get()))
|
||||||
|
{
|
||||||
checkDoubleStorageAssignment(_assignment);
|
checkDoubleStorageAssignment(_assignment);
|
||||||
|
// @todo For 0.5.0, this code shoud move to TupleType::isImplicitlyConvertibleTo,
|
||||||
|
// but we cannot do it right now.
|
||||||
|
if (rhsType->components().size() != tupleType->components().size())
|
||||||
|
{
|
||||||
|
string message =
|
||||||
|
"Different number of components on the left hand side (" +
|
||||||
|
toString(tupleType->components().size()) +
|
||||||
|
") than on the right hand side (" +
|
||||||
|
toString(rhsType->components().size()) +
|
||||||
|
").";
|
||||||
|
if (v050)
|
||||||
|
m_errorReporter.typeError(_assignment.location(), message);
|
||||||
|
else
|
||||||
|
m_errorReporter.warning(_assignment.location(), message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (t->category() == Type::Category::Mapping)
|
else if (t->category() == Type::Category::Mapping)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user