diff options
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 88 |
1 files changed, 16 insertions, 72 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f0070382..cc373e03 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1046,10 +1046,10 @@ namespace * @returns a suggested left-hand-side of a multi-variable declaration contairing * the variable declarations given in @a _decls. */ -string createTupleDecl(vector<VariableDeclaration const*> const& _decls) +string createTupleDecl(vector<ASTPointer<VariableDeclaration>> const& _decls) { vector<string> components; - for (VariableDeclaration const* decl: _decls) + for (ASTPointer<VariableDeclaration> const& decl: _decls) if (decl) components.emplace_back(decl->annotation().type->toString(false) + " " + decl->name()); else @@ -1061,9 +1061,9 @@ string createTupleDecl(vector<VariableDeclaration const*> const& _decls) return "(" + boost::algorithm::join(components, ", ") + ")"; } -bool typeCanBeExpressed(vector<VariableDeclaration const*> const& decls) +bool typeCanBeExpressed(vector<ASTPointer<VariableDeclaration>> const& decls) { - for (VariableDeclaration const* decl: decls) + for (ASTPointer<VariableDeclaration> const& decl: decls) { // skip empty tuples (they can be expressed of course) if (!decl) @@ -1083,7 +1083,6 @@ bool typeCanBeExpressed(vector<VariableDeclaration const*> const& decls) bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); if (!_statement.initialValue()) { // No initial value is only permitted for single variables with specified type. @@ -1122,82 +1121,27 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) else valueTypes = TypePointers{type(*_statement.initialValue())}; - // Determine which component is assigned to which variable. - // If numbers do not match, fill up if variables begin or end empty (not both). - vector<VariableDeclaration const*>& assignments = _statement.annotation().assignments; - assignments.resize(valueTypes.size(), nullptr); vector<ASTPointer<VariableDeclaration>> const& variables = _statement.declarations(); if (variables.empty()) - { - if (!valueTypes.empty()) - m_errorReporter.fatalTypeError( - _statement.location(), - "Too many components (" + - toString(valueTypes.size()) + - ") in value for variable assignment (0) needed" - ); - } + // We already have an error for this in the SyntaxChecker. + solAssert(m_errorReporter.hasErrors(), ""); else if (valueTypes.size() != variables.size()) - { - if (v050) - m_errorReporter.fatalTypeError( - _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(); - if (!variables.empty() && (!variables.back() || !variables.front())) - --minNumValues; - if (valueTypes.size() < minNumValues) - m_errorReporter.fatalTypeError( - _statement.location(), - "Not enough components (" + - toString(valueTypes.size()) + - ") in value to assign all variables (" + - toString(minNumValues) + ")." - ); - if (valueTypes.size() > variables.size() && variables.front() && variables.back()) - m_errorReporter.fatalTypeError( + m_errorReporter.typeError( _statement.location(), - "Too many components (" + + "Different number of components on the left hand side (" + + toString(variables.size()) + + ") than on the right hand side (" + toString(valueTypes.size()) + - ") in value for variable assignment (" + - toString(minNumValues) + - " needed)." + ")." ); - bool fillRight = !variables.empty() && (!variables.back() || variables.front()); - for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i) - if (fillRight) - assignments[i] = variables[i].get(); - else - assignments[assignments.size() - i - 1] = variables[variables.size() - i - 1].get(); bool autoTypeDeductionNeeded = false; - for (size_t i = 0; i < assignments.size(); ++i) + for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i) { - if (!assignments[i]) + if (!variables[i]) continue; - VariableDeclaration const& var = *assignments[i]; + VariableDeclaration const& var = *variables[i]; solAssert(!var.value(), "Value has to be tied to statement."); TypePointer const& valueComponentType = valueTypes[i]; solAssert(!!valueComponentType, ""); @@ -1287,7 +1231,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) if (autoTypeDeductionNeeded) { - if (!typeCanBeExpressed(assignments)) + if (!typeCanBeExpressed(variables)) m_errorReporter.syntaxError( _statement.location(), "Use of the \"var\" keyword is disallowed. " @@ -1297,7 +1241,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) m_errorReporter.syntaxError( _statement.location(), "Use of the \"var\" keyword is disallowed. " - "Use explicit declaration `" + createTupleDecl(assignments) + " = ...´ instead." + "Use explicit declaration `" + createTupleDecl(variables) + " = ...´ instead." ); } |