mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4431 from ethereum/tupleDeclaration
Disallow multi variable declarations with mismatching number of values.
This commit is contained in:
commit
052f19c6b0
@ -38,6 +38,7 @@ Breaking Changes:
|
||||
* Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode.
|
||||
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
|
||||
* Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode.
|
||||
* Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode.
|
||||
* Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode.
|
||||
* Type Checker: Disallow calling constructor with wrong argument count. This was already the case in the experimental 0.5.0 mode.
|
||||
* Type Checker: Disallow uninitialized storage variables. This was already the case in the experimental 0.5.0 mode.
|
||||
|
@ -297,9 +297,9 @@ These can then either be assigned to newly declared variables or to pre-existing
|
||||
}
|
||||
|
||||
.. note::
|
||||
Prior to version 0.4.24 it was possible to assign to tuples of smaller size, either
|
||||
Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either
|
||||
filling up on the left or on the right side (which ever was empty). This is
|
||||
now deprecated, both sides have to have the same number of components.
|
||||
now disallowed, so both sides have to have the same number of components.
|
||||
|
||||
Complications for Arrays and Structs
|
||||
------------------------------------
|
||||
|
@ -1043,10 +1043,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
|
||||
@ -1058,9 +1058,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)
|
||||
@ -1080,7 +1080,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.
|
||||
@ -1119,82 +1118,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(
|
||||
m_errorReporter.typeError(
|
||||
_statement.location(),
|
||||
"Not enough components (" +
|
||||
"Different number of components on the left hand side (" +
|
||||
toString(variables.size()) +
|
||||
") than on the right hand side (" +
|
||||
toString(valueTypes.size()) +
|
||||
") in value to assign all variables (" +
|
||||
toString(minNumValues) + ")."
|
||||
")."
|
||||
);
|
||||
if (valueTypes.size() > variables.size() && variables.front() && variables.back())
|
||||
m_errorReporter.fatalTypeError(
|
||||
_statement.location(),
|
||||
"Too many components (" +
|
||||
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, "");
|
||||
@ -1284,7 +1228,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. "
|
||||
@ -1294,7 +1238,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."
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -535,13 +535,6 @@ ReturnAnnotation& Return::annotation() const
|
||||
return dynamic_cast<ReturnAnnotation&>(*m_annotation);
|
||||
}
|
||||
|
||||
VariableDeclarationStatementAnnotation& VariableDeclarationStatement::annotation() const
|
||||
{
|
||||
if (!m_annotation)
|
||||
m_annotation = new VariableDeclarationStatementAnnotation();
|
||||
return dynamic_cast<VariableDeclarationStatementAnnotation&>(*m_annotation);
|
||||
}
|
||||
|
||||
ExpressionAnnotation& Expression::annotation() const
|
||||
{
|
||||
if (!m_annotation)
|
||||
|
@ -1270,8 +1270,6 @@ public:
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
VariableDeclarationStatementAnnotation& annotation() const override;
|
||||
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& declarations() const { return m_variables; }
|
||||
Expression const* initialValue() const { return m_initialValue.get(); }
|
||||
|
||||
|
@ -164,13 +164,6 @@ struct UserDefinedTypeNameAnnotation: TypeNameAnnotation
|
||||
ContractDefinition const* contractScope = nullptr;
|
||||
};
|
||||
|
||||
struct VariableDeclarationStatementAnnotation: StatementAnnotation
|
||||
{
|
||||
/// Information about which component of the value is assigned to which variable.
|
||||
/// The pointer can be null to signify that the component is discarded.
|
||||
std::vector<VariableDeclaration const*> assignments;
|
||||
};
|
||||
|
||||
struct ExpressionAnnotation: ASTAnnotation
|
||||
{
|
||||
/// Inferred type of the expression.
|
||||
|
@ -555,8 +555,8 @@ bool ASTJsonConverter::visit(EmitStatement const& _node)
|
||||
bool ASTJsonConverter::visit(VariableDeclarationStatement const& _node)
|
||||
{
|
||||
Json::Value varDecs(Json::arrayValue);
|
||||
for (auto const& v: _node.annotation().assignments)
|
||||
appendMove(varDecs, idOrNull(v));
|
||||
for (auto const& v: _node.declarations())
|
||||
appendMove(varDecs, idOrNull(v.get()));
|
||||
setJsonNode(_node, "VariableDeclarationStatement", {
|
||||
make_pair("assignments", std::move(varDecs)),
|
||||
make_pair("declarations", toJson(_node.declarations())),
|
||||
|
@ -833,20 +833,19 @@ bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclar
|
||||
valueTypes = tupleType->components();
|
||||
else
|
||||
valueTypes = TypePointers{expression->annotation().type};
|
||||
auto const& assignments = _variableDeclarationStatement.annotation().assignments;
|
||||
solAssert(assignments.size() == valueTypes.size(), "");
|
||||
for (size_t i = 0; i < assignments.size(); ++i)
|
||||
auto const& declarations = _variableDeclarationStatement.declarations();
|
||||
solAssert(declarations.size() == valueTypes.size(), "");
|
||||
for (size_t i = 0; i < declarations.size(); ++i)
|
||||
{
|
||||
size_t j = assignments.size() - i - 1;
|
||||
size_t j = declarations.size() - i - 1;
|
||||
solAssert(!!valueTypes[j], "");
|
||||
VariableDeclaration const* varDecl = assignments[j];
|
||||
if (!varDecl)
|
||||
utils.popStackElement(*valueTypes[j]);
|
||||
else
|
||||
if (VariableDeclaration const* varDecl = declarations[j].get())
|
||||
{
|
||||
utils.convertType(*valueTypes[j], *varDecl->annotation().type);
|
||||
utils.moveToStackVariable(*varDecl);
|
||||
}
|
||||
else
|
||||
utils.popStackElement(*valueTypes[j]);
|
||||
}
|
||||
}
|
||||
checker.check();
|
||||
|
@ -8091,17 +8091,36 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration)
|
||||
function g() public returns (uint a, uint b, uint c) {
|
||||
a = 1; b = 2; c = 3;
|
||||
}
|
||||
function f() public returns (bool) {
|
||||
function h() public returns (uint a, uint b, uint c, uint d) {
|
||||
a = 1; b = 2; c = 3; d = 4;
|
||||
}
|
||||
function f1() public returns (bool) {
|
||||
(uint x, uint y, uint z) = g();
|
||||
if (x != 1 || y != 2 || z != 3) return false;
|
||||
(, uint a,) = g();
|
||||
if (a != 2) return false;
|
||||
(uint b,) = g();
|
||||
(uint b, , ) = g();
|
||||
if (b != 1) return false;
|
||||
(, uint c) = g();
|
||||
(, , uint c) = g();
|
||||
if (c != 3) return false;
|
||||
return true;
|
||||
}
|
||||
function f2() public returns (bool) {
|
||||
(uint a1, , uint a3, ) = h();
|
||||
if (a1 != 1 || a3 != 3) return false;
|
||||
(uint b1, uint b2, , ) = h();
|
||||
if (b1 != 1 || b2 != 2) return false;
|
||||
(, uint c2, uint c3, ) = h();
|
||||
if (c2 != 2 || c3 != 3) return false;
|
||||
(, , uint d3, uint d4) = h();
|
||||
if (d3 != 3 || d4 != 4) return false;
|
||||
(uint e1, , uint e3, uint e4) = h();
|
||||
if (e1 != 1 || e3 != 3 || e4 != 4) return false;
|
||||
return true;
|
||||
}
|
||||
function f() public returns (bool) {
|
||||
return f1() && f2();
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
|
@ -0,0 +1,25 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
uint a = (1,2);
|
||||
uint b = (1,2,3);
|
||||
uint c = (1,2,3,4);
|
||||
}
|
||||
function g() public {
|
||||
(uint a1, uint b1, uint c1, uint d1) = 1;
|
||||
(uint a2, uint b2, uint c2) = 1;
|
||||
(uint a3, uint b3) = 1;
|
||||
}
|
||||
function h() public {
|
||||
(uint a1, uint b1, uint c1, uint d1) = (1,2,3);
|
||||
(uint a2, uint b2, uint c2) = (1,2,3,4);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (47-61): Different number of components on the left hand side (1) than on the right hand side (2).
|
||||
// TypeError: (71-87): Different number of components on the left hand side (1) than on the right hand side (3).
|
||||
// TypeError: (97-115): Different number of components on the left hand side (1) than on the right hand side (4).
|
||||
// TypeError: (157-197): Different number of components on the left hand side (4) than on the right hand side (1).
|
||||
// TypeError: (207-238): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (248-270): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError: (312-358): Different number of components on the left hand side (4) than on the right hand side (3).
|
||||
// TypeError: (368-407): Different number of components on the left hand side (3) than on the right hand side (4).
|
@ -0,0 +1,29 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
uint a = two();
|
||||
uint b = three();
|
||||
uint c = four();
|
||||
}
|
||||
function g() public {
|
||||
(uint a1, uint b1, uint c1, uint d1) = one();
|
||||
(uint a2, uint b2, uint c2) = one();
|
||||
(uint a3, uint b3) = one();
|
||||
}
|
||||
function h() public {
|
||||
(uint a1, uint b1, uint c1, uint d1) = three();
|
||||
(uint a2, uint b2, uint c2) = four();
|
||||
}
|
||||
function one() public pure returns (uint);
|
||||
function two() public pure returns (uint, uint);
|
||||
function three() public pure returns (uint, uint, uint);
|
||||
function four() public pure returns (uint, uint, uint, uint);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (47-61): Different number of components on the left hand side (1) than on the right hand side (2).
|
||||
// TypeError: (71-87): Different number of components on the left hand side (1) than on the right hand side (3).
|
||||
// TypeError: (97-112): Different number of components on the left hand side (1) than on the right hand side (4).
|
||||
// TypeError: (154-198): Different number of components on the left hand side (4) than on the right hand side (1).
|
||||
// TypeError: (208-243): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (253-279): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError: (321-367): Different number of components on the left hand side (4) than on the right hand side (3).
|
||||
// TypeError: (377-413): Different number of components on the left hand side (3) than on the right hand side (4).
|
@ -0,0 +1,24 @@
|
||||
contract C {
|
||||
function fn() public pure {
|
||||
(uint a,) = (1,2,3);
|
||||
(,uint b) = (1,2,3);
|
||||
(,uint c,) = (1,2,3,4,5);
|
||||
(uint d, uint e,) = (1,2,3,4);
|
||||
(,uint f, uint g) = (1,2,3,4);
|
||||
(,uint h, uint i,) = (1,2,3);
|
||||
(uint j,) = 1;
|
||||
(,uint k) = 1;
|
||||
(,uint l,) = 1;
|
||||
a;b;c;d;e;f;g;h;i;j;k;l;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (53-72): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// TypeError: (82-101): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// TypeError: (111-135): Different number of components on the left hand side (3) than on the right hand side (5).
|
||||
// TypeError: (145-174): Different number of components on the left hand side (3) than on the right hand side (4).
|
||||
// TypeError: (184-213): Different number of components on the left hand side (3) than on the right hand side (4).
|
||||
// TypeError: (223-251): Different number of components on the left hand side (4) than on the right hand side (3).
|
||||
// TypeError: (261-274): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError: (284-297): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError: (307-321): Different number of components on the left hand side (3) than on the right hand side (1).
|
@ -0,0 +1,31 @@
|
||||
contract C {
|
||||
function fn() public pure {
|
||||
(uint a,) = three();
|
||||
(,uint b) = three();
|
||||
(,uint c,) = five();
|
||||
(uint d, uint e,) = four();
|
||||
(,uint f, uint g) = four();
|
||||
(,uint h, uint i,) = three();
|
||||
(uint j,) = one();
|
||||
(,uint k) = one();
|
||||
(,uint l,) = one();
|
||||
(,uint m, uint n,) = five();
|
||||
a;b;c;d;e;f;g;h;i;j;k;l;m;n;
|
||||
}
|
||||
function one() public pure returns (uint);
|
||||
function two() public pure returns (uint, uint);
|
||||
function three() public pure returns (uint, uint, uint);
|
||||
function four() public pure returns (uint, uint, uint, uint);
|
||||
function five() public pure returns (uint, uint, uint, uint, uint);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (53-72): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// TypeError: (82-101): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// TypeError: (111-130): Different number of components on the left hand side (3) than on the right hand side (5).
|
||||
// TypeError: (140-166): Different number of components on the left hand side (3) than on the right hand side (4).
|
||||
// TypeError: (176-202): Different number of components on the left hand side (3) than on the right hand side (4).
|
||||
// TypeError: (212-240): Different number of components on the left hand side (4) than on the right hand side (3).
|
||||
// TypeError: (250-267): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError: (277-294): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError: (304-322): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (332-359): Different number of components on the left hand side (4) than on the right hand side (5).
|
@ -2,10 +2,10 @@ contract D {
|
||||
struct S { uint a; uint b; }
|
||||
}
|
||||
contract C {
|
||||
function f() internal returns (uint, uint, uint, D.S[20] storage, uint) {
|
||||
(,,,D.S[10*2] storage x,) = f();
|
||||
function f() internal pure {
|
||||
(,,,D.S[10*2] storage x,) = g();
|
||||
x;
|
||||
}
|
||||
}
|
||||
function g() internal pure returns (uint, uint, uint, D.S[20] storage x, uint) { x = x; }
|
||||
}
|
||||
// ----
|
||||
// Warning: (110-117): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning.
|
||||
|
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
(uint a, uint b) = f();
|
||||
(uint c) = f();
|
||||
uint d = f();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (52-74): Different number of components on the left hand side (2) than on the right hand side (0).
|
||||
// TypeError: (84-98): Different number of components on the left hand side (1) than on the right hand side (0).
|
||||
// TypeError: (108-120): Different number of components on the left hand side (1) than on the right hand side (0).
|
@ -1,12 +1,12 @@
|
||||
contract C {
|
||||
function f() internal returns (uint, uint, uint, uint) {
|
||||
function f() internal pure returns (uint, uint, uint, uint) {
|
||||
(uint a, uint b,,) = f();
|
||||
a; b;
|
||||
}
|
||||
function g() internal returns (bytes memory, string storage) {
|
||||
(bytes memory a, string storage b) = g();
|
||||
function g() internal pure {
|
||||
(bytes memory a, string storage b) = h();
|
||||
a; b;
|
||||
}
|
||||
}
|
||||
function h() internal pure returns (bytes memory, string storage s) { s = s; }
|
||||
}
|
||||
// ----
|
||||
// Warning: (163-169): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning.
|
||||
|
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
(uint a,) = (1,);
|
||||
a;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (59-63): Tuple component cannot be empty.
|
@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
(uint a1, uint b1, uint c1, uint d1) = (1,2,3,4);
|
||||
(uint a2, uint b2, uint c2) = (1,2,3);
|
||||
(uint a3, uint b3) = (1,2);
|
||||
a1; b1; c1; d1; a2; b2; c2; a3; b3;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -1,21 +0,0 @@
|
||||
contract C {
|
||||
function three() public returns (uint, uint, uint);
|
||||
function two() public returns (uint, uint);
|
||||
function none() public;
|
||||
function f() public {
|
||||
(uint a,) = three();
|
||||
(uint b, uint c,) = two();
|
||||
(,uint d) = three();
|
||||
(,uint e, uint g) = two();
|
||||
var (,,) = three();
|
||||
var () = none();
|
||||
a;b;c;d;e;g;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// SyntaxError: (307-325): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// SyntaxError: (335-350): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// Warning: (179-198): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// Warning: (208-233): Different number of components on the left hand side (3) than on the right hand side (2).
|
||||
// Warning: (243-262): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// Warning: (272-297): Different number of components on the left hand side (3) than on the right hand side (2).
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
function one() public returns (uint);
|
||||
function f() public { (uint a, uint b, ) = one(); }
|
||||
}
|
||||
// ----
|
||||
// Warning: (81-107): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (81-107): Not enough components (1) in value to assign all variables (2).
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
function one() public returns (uint);
|
||||
function f() public { (uint a, , ) = one(); }
|
||||
}
|
||||
// ----
|
||||
// Warning: (81-101): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (81-101): Not enough components (1) in value to assign all variables (2).
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
function one() public returns (uint);
|
||||
function f() public { (, , uint a) = one(); }
|
||||
}
|
||||
// ----
|
||||
// Warning: (81-101): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (81-101): Not enough components (1) in value to assign all variables (2).
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
function one() public returns (uint);
|
||||
function f() public { (, uint a, uint b) = one(); }
|
||||
}
|
||||
// ----
|
||||
// Warning: (81-107): Different number of components on the left hand side (3) than on the right hand side (1).
|
||||
// TypeError: (81-107): Not enough components (1) in value to assign all variables (2).
|
@ -1,13 +1,10 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
function f() public pure {
|
||||
uint a = (1);
|
||||
(uint b,) = uint8(1);
|
||||
(uint b,) = (uint8(1),2);
|
||||
(uint c, uint d) = (uint32(1), 2 + a);
|
||||
(uint e,) = (uint64(1), 2, b);
|
||||
(uint e, ,) = (uint64(1), 2, b);
|
||||
a;b;c;d;e;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (69-89): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// Warning: (146-175): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// Warning: (17-201): Function state mutability can be restricted to pure
|
||||
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
function one() public returns (uint);
|
||||
function f() public { var (,) = one(); }
|
||||
}
|
||||
// ----
|
||||
// SyntaxError: (81-96): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// TypeError: (81-96): Wildcard both at beginning and end of variable declaration list is only allowed if the number of components is equal.
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
function two() public returns (uint, uint);
|
||||
function f() public { (uint a, uint b, uint c) = two(); }
|
||||
}
|
||||
// ----
|
||||
// Warning: (87-119): Different number of components on the left hand side (3) than on the right hand side (2).
|
||||
// TypeError: (87-119): Not enough components (2) in value to assign all variables (3).
|
@ -2,8 +2,8 @@ contract C {
|
||||
function f() pure public {
|
||||
(uint a, uint b, uint c) = g();
|
||||
(uint d) = 2;
|
||||
(, uint e) = 3;
|
||||
(uint h,) = 4;
|
||||
(, uint e) = (3,4);
|
||||
(uint h,) = (4,5);
|
||||
(uint x,,) = g();
|
||||
(, uint y,) = g();
|
||||
a; b; c; d; e; h; x; y;
|
||||
@ -11,5 +11,3 @@ contract C {
|
||||
function g() pure public returns (uint, uint, uint) {}
|
||||
}
|
||||
// ----
|
||||
// Warning: (93-107): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// Warning: (111-124): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
|
@ -1,16 +1,11 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
function f() public pure {
|
||||
uint a = (1);
|
||||
(uint b,) = 1;
|
||||
(uint b,) = (1,2);
|
||||
(uint c, uint d) = (1, 2 + a);
|
||||
(uint e,) = (1, 2, b);
|
||||
(uint e,) = (1, b);
|
||||
(a) = 3;
|
||||
a;b;c;d;e;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (54-67): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// Warning: (104-125): Different number of components on the left hand side (2) than on the right hand side (3).
|
||||
// Warning: (72-78): Unused local variable.
|
||||
// Warning: (80-86): Unused local variable.
|
||||
// Warning: (105-111): Unused local variable.
|
||||
// Warning: (14-140): Function state mutability can be restricted to pure
|
||||
|
@ -1,8 +0,0 @@
|
||||
contract C {
|
||||
function f() public pure returns (uint, uint, uint, uint) {
|
||||
(uint a, uint b,) = f();
|
||||
a; b;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (76-99): Different number of components on the left hand side (3) than on the right hand side (4).
|
@ -16,4 +16,3 @@ contract C {
|
||||
// SyntaxError: (249-261): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// SyntaxError: (271-283): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// SyntaxError: (293-306): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// TypeError: (271-283): Too many components (1) in value for variable assignment (0) needed
|
||||
|
Loading…
Reference in New Issue
Block a user