Merge pull request #7349 from ethereum/payable_conversion

Conversion from address to address payable
This commit is contained in:
Leonardo 2019-09-10 12:26:18 +02:00 committed by GitHub
commit c037d7845c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 248 additions and 172 deletions

View File

@ -13,6 +13,7 @@ Breaking changes:
Language Features: Language Features:
* Allow global enums and structs. * Allow global enums and structs.
* Allow underscores as delimiters in hex strings. * Allow underscores as delimiters in hex strings.
* Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``.
Compiler Features: Compiler Features:

View File

@ -16,6 +16,8 @@ This section lists purely syntactic changes that do not affect the behavior of e
* Conversions from external function types to ``address`` are now disallowed. Instead external * Conversions from external function types to ``address`` are now disallowed. Instead external
function types have a member called ``address``, similar to the existing ``selector`` member. function types have a member called ``address``, similar to the existing ``selector`` member.
* Conversions from ``address`` to ``address payable`` are now possible via ``payable(x)``, where
``x`` must be of type ``address``.
* New reserved keywords: ``virtual``. * New reserved keywords: ``virtual``.

View File

@ -128,3 +128,5 @@ As described in :ref:`address_literals`, hex literals of the correct size that p
test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type. test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type.
Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``. Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``.
An ``address a`` can be converted to ``address payable`` via ``payable(a)``.

View File

@ -171,18 +171,20 @@ while a plain ``address`` cannot be sent Ether.
Type conversions: Type conversions:
Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable`` are Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable``
not possible (the only way to perform such a conversion is by using an intermediate conversion to ``uint160``). must be explicit via ``payable(<address>)``.
:ref:`Address literals<address_literals>` can be implicitly converted to ``address payable``. :ref:`Address literals<address_literals>` can be implicitly converted to ``address payable``.
Explicit conversions to and from ``address`` are allowed for integers, integer literals, ``bytes20`` and contract types with the following Explicit conversions to and from ``address`` are allowed for integers, integer literals, ``bytes20`` and contract types with the following
caveat: caveat:
Conversions of the form ``address payable(x)`` are not allowed. Instead the result of a conversion of the form ``address(x)`` The result of a conversion of the form ``address(x)``
has the type ``address payable``, if ``x`` is of integer or fixed bytes type, a literal or a contract with a payable fallback function. has the type ``address payable``, if ``x`` is of integer or fixed bytes type, a literal or a contract with a payable fallback function.
If ``x`` is a contract without payable fallback function, then ``address(x)`` will be of type ``address``. If ``x`` is a contract without payable fallback function, then ``address(x)`` will be of type ``address``.
In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type. In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type.
Only expressions of type ``address`` can be converted to type ``address payable`` via ``payable(<address>)``.
.. note:: .. note::
It might very well be that you do not need to care about the distinction between ``address`` It might very well be that you do not need to care about the distinction between ``address``
and ``address payable`` and just use ``address`` everywhere. For example, and ``address payable`` and just use ``address`` everywhere. For example,
@ -310,10 +312,12 @@ Every :ref:`contract<contracts>` defines its own type.
You can implicitly convert contracts to contracts they inherit from. You can implicitly convert contracts to contracts they inherit from.
Contracts can be explicitly converted to and from the ``address`` type. Contracts can be explicitly converted to and from the ``address`` type.
Explicit conversion to and from the ``address payable`` type Explicit conversion to and from the ``address payable`` type is only possible
is only possible if the contract type has a payable fallback function. if the contract type has a payable fallback function. The conversion is still
The conversion is still performed using ``address(x)`` and not performed using ``address(x)``. If the contract type does not have a payable
using ``address payable(x)``. You can find more information in the section about fallback function, the conversion to ``address payable`` can be done using
``payable(address(x))``.
You can find more information in the section about
the :ref:`address type<address>`. the :ref:`address type<address>`.
.. note:: .. note::

View File

@ -1527,11 +1527,14 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(
"\"." "\"."
); );
} }
if (resultType->category() == Type::Category::Address) if (auto addressType = dynamic_cast<AddressType const*>(resultType))
{ if (addressType->stateMutability() != StateMutability::Payable)
bool const payable = argType->isExplicitlyConvertibleTo(*TypeProvider::payableAddress()); {
resultType = payable ? TypeProvider::payableAddress() : TypeProvider::address(); bool payable = false;
} if (argType->category() != Type::Category::Address)
payable = argType->isExplicitlyConvertibleTo(*TypeProvider::payableAddress());
resultType = payable ? TypeProvider::payableAddress() : TypeProvider::address();
}
} }
return resultType; return resultType;
} }
@ -2423,7 +2426,7 @@ bool TypeChecker::visit(Identifier const& _identifier)
void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr)
{ {
_expr.annotation().type = TypeProvider::typeType(TypeProvider::fromElementaryTypeName(_expr.typeName())); _expr.annotation().type = TypeProvider::typeType(TypeProvider::fromElementaryTypeName(_expr.type().typeName(), _expr.type().stateMutability()));
_expr.annotation().isPure = true; _expr.annotation().isPure = true;
} }

View File

@ -1682,16 +1682,21 @@ private:
class ElementaryTypeNameExpression: public PrimaryExpression class ElementaryTypeNameExpression: public PrimaryExpression
{ {
public: public:
ElementaryTypeNameExpression(SourceLocation const& _location, ElementaryTypeNameToken const& _type): ElementaryTypeNameExpression(
PrimaryExpression(_location), m_typeToken(_type) SourceLocation const& _location,
{} ASTPointer<ElementaryTypeName> const& _type
):
PrimaryExpression(_location),
m_type(_type)
{
}
void accept(ASTVisitor& _visitor) override; void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override; void accept(ASTConstVisitor& _visitor) const override;
ElementaryTypeNameToken const& typeName() const { return m_typeToken; } ElementaryTypeName const& type() const { return *m_type; }
private: private:
ElementaryTypeNameToken m_typeToken; ASTPointer<ElementaryTypeName> m_type;
}; };
/** /**

View File

@ -712,7 +712,7 @@ bool ASTJsonConverter::visit(Identifier const& _node)
bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node)
{ {
std::vector<pair<string, Json::Value>> attributes = { std::vector<pair<string, Json::Value>> attributes = {
make_pair(m_legacy ? "value" : "typeName", _node.typeName().toString()) make_pair(m_legacy ? "value" : "typeName", _node.type().typeName().toString())
}; };
appendExpressionAttributes(attributes, _node.annotation()); appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "ElementaryTypeNameExpression", std::move(attributes)); setJsonNode(_node, "ElementaryTypeNameExpression", std::move(attributes));

View File

@ -200,7 +200,7 @@ inline T const* TypeProvider::createAndGet(Args&& ... _args)
return static_cast<T const*>(instance().m_generalTypes.back().get()); return static_cast<T const*>(instance().m_generalTypes.back().get());
} }
Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& _type) Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& _type, boost::optional<StateMutability> _stateMutability)
{ {
solAssert( solAssert(
TokenTraits::isElementaryTypeName(_type.token()), TokenTraits::isElementaryTypeName(_type.token()),
@ -233,7 +233,14 @@ Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const&
case Token::UFixed: case Token::UFixed:
return fixedPoint(128, 18, FixedPointType::Modifier::Unsigned); return fixedPoint(128, 18, FixedPointType::Modifier::Unsigned);
case Token::Address: case Token::Address:
{
if (_stateMutability)
{
solAssert(*_stateMutability == StateMutability::Payable, "");
return payableAddress();
}
return address(); return address();
}
case Token::Bool: case Token::Bool:
return boolean(); return boolean();
case Token::Bytes: case Token::Bytes:

View File

@ -54,7 +54,7 @@ public:
/// @name Factory functions /// @name Factory functions
/// Factory functions that convert an AST @ref TypeName to a Type. /// Factory functions that convert an AST @ref TypeName to a Type.
static Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type); static Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type, boost::optional<StateMutability> _stateMutability = {});
/// Converts a given elementary type name with optional data location /// Converts a given elementary type name with optional data location
/// suffix " storage", " calldata" or " memory" to a type pointer. If suffix not given, defaults to " storage". /// suffix " storage", " calldata" or " memory" to a type pointer. If suffix not given, defaults to " storage".

View File

@ -412,7 +412,9 @@ BoolResult AddressType::isImplicitlyConvertibleTo(Type const& _other) const
BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{ {
if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo)) if (_convertTo.category() == category())
return true;
else if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable(); return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
return isImplicitlyConvertibleTo(_convertTo) || return isImplicitlyConvertibleTo(_convertTo) ||
_convertTo.category() == Category::Integer || _convertTo.category() == Category::Integer ||

View File

@ -1585,6 +1585,17 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expression = nodeFactory.createNode<NewExpression>(typeName); expression = nodeFactory.createNode<NewExpression>(typeName);
} }
else if (m_scanner->currentToken() == Token::Payable)
{
expectToken(Token::Payable);
nodeFactory.markEndPosition();
auto expressionType = nodeFactory.createNode<ElementaryTypeName>(
ElementaryTypeNameToken(Token::Address, 160, 0),
boost::make_optional(StateMutability::Payable)
);
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(expressionType);
expectToken(Token::LParen, false);
}
else else
expression = parsePrimaryExpression(); expression = parsePrimaryExpression();
@ -1725,8 +1736,10 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
unsigned firstSize; unsigned firstSize;
unsigned secondSize; unsigned secondSize;
tie(firstSize, secondSize) = m_scanner->currentTokenInfo(); tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), firstSize, secondSize); auto expressionType = nodeFactory.createNode<ElementaryTypeName>(
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(elementaryExpression); ElementaryTypeNameToken(m_scanner->currentToken(), firstSize, secondSize)
);
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(expressionType);
m_scanner->next(); m_scanner->next();
} }
else else
@ -1838,8 +1851,10 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
unsigned firstNum; unsigned firstNum;
unsigned secondNum; unsigned secondNum;
tie(firstNum, secondNum) = m_scanner->currentTokenInfo(); tie(firstNum, secondNum) = m_scanner->currentTokenInfo();
ElementaryTypeNameToken elemToken(m_scanner->currentToken(), firstNum, secondNum); auto expressionType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(
iap.path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(elemToken)); ElementaryTypeNameToken(m_scanner->currentToken(), firstNum, secondNum)
);
iap.path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(expressionType));
m_scanner->next(); m_scanner->next();
} }
while (m_scanner->currentToken() == Token::LBrack) while (m_scanner->currentToken() == Token::LBrack)
@ -1872,7 +1887,7 @@ ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAcces
if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_iap.path.front().get())) if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_iap.path.front().get()))
{ {
solAssert(_iap.path.size() == 1, ""); solAssert(_iap.path.size() == 1, "");
type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeName()); type = nodeFactory.createNode<ElementaryTypeName>(typeName->type().typeName());
} }
else else
{ {

View File

@ -4,10 +4,10 @@
{ {
"C" : "C" :
[ [
37 39
] ]
}, },
"id" : 38, "id" : 40,
"nodeType" : "SourceUnit", "nodeType" : "SourceUnit",
"nodes" : "nodes" :
[ [
@ -17,10 +17,10 @@
"contractKind" : "contract", "contractKind" : "contract",
"documentation" : null, "documentation" : null,
"fullyImplemented" : true, "fullyImplemented" : true,
"id" : 37, "id" : 39,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
37 39
], ],
"name" : "C", "name" : "C",
"nodeType" : "ContractDefinition", "nodeType" : "ContractDefinition",
@ -32,7 +32,7 @@
"name" : "m", "name" : "m",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 37, "scope" : 39,
"src" : "17:44:1", "src" : "17:44:1",
"stateVariable" : true, "stateVariable" : true,
"storageLocation" : "default", "storageLocation" : "default",
@ -83,7 +83,7 @@
{ {
"body" : "body" :
{ {
"id" : 35, "id" : 37,
"nodeType" : "Block", "nodeType" : "Block",
"src" : "134:122:1", "src" : "134:122:1",
"statements" : "statements" :
@ -101,7 +101,7 @@
"name" : "a", "name" : "a",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 35, "scope" : 37,
"src" : "144:17:1", "src" : "144:17:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
@ -242,7 +242,7 @@
"name" : "c", "name" : "c",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 35, "scope" : 37,
"src" : "197:9:1", "src" : "197:9:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
@ -268,7 +268,7 @@
"visibility" : "internal" "visibility" : "internal"
} }
], ],
"id" : 26, "id" : 27,
"initialValue" : "initialValue" :
{ {
"argumentTypes" : null, "argumentTypes" : null,
@ -276,15 +276,15 @@
[ [
{ {
"argumentTypes" : null, "argumentTypes" : null,
"id" : 24, "id" : 25,
"name" : "this", "name" : "this",
"nodeType" : "Identifier", "nodeType" : "Identifier",
"overloadedDeclarations" : [], "overloadedDeclarations" : [],
"referencedDeclaration" : 66, "referencedDeclaration" : 68,
"src" : "217:4:1", "src" : "217:4:1",
"typeDescriptions" : "typeDescriptions" :
{ {
"typeIdentifier" : "t_contract$_C_$37", "typeIdentifier" : "t_contract$_C_$39",
"typeString" : "contract C" "typeString" : "contract C"
} }
} }
@ -294,11 +294,11 @@
"argumentTypes" : "argumentTypes" :
[ [
{ {
"typeIdentifier" : "t_contract$_C_$37", "typeIdentifier" : "t_contract$_C_$39",
"typeString" : "contract C" "typeString" : "contract C"
} }
], ],
"id" : 23, "id" : 24,
"isConstant" : false, "isConstant" : false,
"isLValue" : false, "isLValue" : false,
"isPure" : true, "isPure" : true,
@ -312,7 +312,7 @@
}, },
"typeName" : "address" "typeName" : "address"
}, },
"id" : 25, "id" : 26,
"isConstant" : false, "isConstant" : false,
"isLValue" : false, "isLValue" : false,
"isPure" : false, "isPure" : false,
@ -334,7 +334,7 @@
"expression" : "expression" :
{ {
"argumentTypes" : null, "argumentTypes" : null,
"id" : 33, "id" : 35,
"isConstant" : false, "isConstant" : false,
"isLValue" : false, "isLValue" : false,
"isPure" : false, "isPure" : false,
@ -345,7 +345,7 @@
"baseExpression" : "baseExpression" :
{ {
"argumentTypes" : null, "argumentTypes" : null,
"id" : 27, "id" : 28,
"name" : "m", "name" : "m",
"nodeType" : "Identifier", "nodeType" : "Identifier",
"overloadedDeclarations" : [], "overloadedDeclarations" : [],
@ -357,11 +357,11 @@
"typeString" : "mapping(address => address payable)" "typeString" : "mapping(address => address payable)"
} }
}, },
"id" : 29, "id" : 30,
"indexExpression" : "indexExpression" :
{ {
"argumentTypes" : null, "argumentTypes" : null,
"id" : 28, "id" : 29,
"name" : "c", "name" : "c",
"nodeType" : "Identifier", "nodeType" : "Identifier",
"overloadedDeclarations" : [], "overloadedDeclarations" : [],
@ -395,7 +395,7 @@
{ {
"argumentTypes" : null, "argumentTypes" : null,
"hexValue" : "30", "hexValue" : "30",
"id" : 31, "id" : 33,
"isConstant" : false, "isConstant" : false,
"isLValue" : false, "isLValue" : false,
"isPure" : true, "isPure" : true,
@ -421,7 +421,7 @@
"typeString" : "int_const 0" "typeString" : "int_const 0"
} }
], ],
"id" : 30, "id" : 32,
"isConstant" : false, "isConstant" : false,
"isLValue" : false, "isLValue" : false,
"isPure" : true, "isPure" : true,
@ -435,7 +435,7 @@
}, },
"typeName" : "address" "typeName" : "address"
}, },
"id" : 32, "id" : 34,
"isConstant" : false, "isConstant" : false,
"isLValue" : false, "isLValue" : false,
"isPure" : true, "isPure" : true,
@ -457,14 +457,14 @@
"typeString" : "address payable" "typeString" : "address payable"
} }
}, },
"id" : 34, "id" : 36,
"nodeType" : "ExpressionStatement", "nodeType" : "ExpressionStatement",
"src" : "232:17:1" "src" : "232:17:1"
} }
] ]
}, },
"documentation" : null, "documentation" : null,
"id" : 36, "id" : 38,
"implemented" : true, "implemented" : true,
"kind" : "function", "kind" : "function",
"modifiers" : [], "modifiers" : [],
@ -483,7 +483,7 @@
"name" : "arg", "name" : "arg",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 36, "scope" : 38,
"src" : "78:19:1", "src" : "78:19:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
@ -523,7 +523,7 @@
"name" : "r", "name" : "r",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 36, "scope" : 38,
"src" : "115:17:1", "src" : "115:17:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
@ -551,14 +551,14 @@
], ],
"src" : "114:19:1" "src" : "114:19:1"
}, },
"scope" : 37, "scope" : 39,
"src" : "67:189:1", "src" : "67:189:1",
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
} }
], ],
"scope" : 38, "scope" : 40,
"src" : "0:258:1" "src" : "0:258:1"
} }
], ],

View File

@ -6,7 +6,7 @@
{ {
"C" : "C" :
[ [
37 39
] ]
} }
}, },
@ -28,10 +28,10 @@
"fullyImplemented" : true, "fullyImplemented" : true,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
37 39
], ],
"name" : "C", "name" : "C",
"scope" : 38 "scope" : 40
}, },
"children" : "children" :
[ [
@ -41,7 +41,7 @@
"constant" : false, "constant" : false,
"name" : "m", "name" : "m",
"overrides" : null, "overrides" : null,
"scope" : 37, "scope" : 39,
"stateVariable" : true, "stateVariable" : true,
"storageLocation" : "default", "storageLocation" : "default",
"type" : "mapping(address => address payable)", "type" : "mapping(address => address payable)",
@ -101,7 +101,7 @@
], ],
"name" : "f", "name" : "f",
"overrides" : null, "overrides" : null,
"scope" : 37, "scope" : 39,
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
@ -117,7 +117,7 @@
"constant" : false, "constant" : false,
"name" : "arg", "name" : "arg",
"overrides" : null, "overrides" : null,
"scope" : 36, "scope" : 38,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
"type" : "address payable", "type" : "address payable",
@ -156,7 +156,7 @@
"constant" : false, "constant" : false,
"name" : "r", "name" : "r",
"overrides" : null, "overrides" : null,
"scope" : 36, "scope" : 38,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
"type" : "address payable", "type" : "address payable",
@ -205,7 +205,7 @@
"constant" : false, "constant" : false,
"name" : "a", "name" : "a",
"overrides" : null, "overrides" : null,
"scope" : 35, "scope" : 37,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
"type" : "address payable", "type" : "address payable",
@ -358,7 +358,7 @@
"constant" : false, "constant" : false,
"name" : "c", "name" : "c",
"overrides" : null, "overrides" : null,
"scope" : 35, "scope" : 37,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "default", "storageLocation" : "default",
"type" : "address", "type" : "address",
@ -407,7 +407,7 @@
"argumentTypes" : "argumentTypes" :
[ [
{ {
"typeIdentifier" : "t_contract$_C_$37", "typeIdentifier" : "t_contract$_C_$39",
"typeString" : "contract C" "typeString" : "contract C"
} }
], ],
@ -418,7 +418,7 @@
"type" : "type(address)", "type" : "type(address)",
"value" : "address" "value" : "address"
}, },
"id" : 23, "id" : 24,
"name" : "ElementaryTypeNameExpression", "name" : "ElementaryTypeNameExpression",
"src" : "209:7:1" "src" : "209:7:1"
}, },
@ -430,21 +430,21 @@
[ [
null null
], ],
"referencedDeclaration" : 66, "referencedDeclaration" : 68,
"type" : "contract C", "type" : "contract C",
"value" : "this" "value" : "this"
}, },
"id" : 24, "id" : 25,
"name" : "Identifier", "name" : "Identifier",
"src" : "217:4:1" "src" : "217:4:1"
} }
], ],
"id" : 25, "id" : 26,
"name" : "FunctionCall", "name" : "FunctionCall",
"src" : "209:13:1" "src" : "209:13:1"
} }
], ],
"id" : 26, "id" : 27,
"name" : "VariableDeclarationStatement", "name" : "VariableDeclarationStatement",
"src" : "197:25:1" "src" : "197:25:1"
}, },
@ -488,7 +488,7 @@
"type" : "mapping(address => address payable)", "type" : "mapping(address => address payable)",
"value" : "m" "value" : "m"
}, },
"id" : 27, "id" : 28,
"name" : "Identifier", "name" : "Identifier",
"src" : "232:1:1" "src" : "232:1:1"
}, },
@ -504,12 +504,12 @@
"type" : "address", "type" : "address",
"value" : "c" "value" : "c"
}, },
"id" : 28, "id" : 29,
"name" : "Identifier", "name" : "Identifier",
"src" : "234:1:1" "src" : "234:1:1"
} }
], ],
"id" : 29, "id" : 30,
"name" : "IndexAccess", "name" : "IndexAccess",
"src" : "232:4:1" "src" : "232:4:1"
}, },
@ -548,7 +548,7 @@
"type" : "type(address)", "type" : "type(address)",
"value" : "address" "value" : "address"
}, },
"id" : 30, "id" : 32,
"name" : "ElementaryTypeNameExpression", "name" : "ElementaryTypeNameExpression",
"src" : "239:7:1" "src" : "239:7:1"
}, },
@ -566,42 +566,42 @@
"type" : "int_const 0", "type" : "int_const 0",
"value" : "0" "value" : "0"
}, },
"id" : 31, "id" : 33,
"name" : "Literal", "name" : "Literal",
"src" : "247:1:1" "src" : "247:1:1"
} }
], ],
"id" : 32, "id" : 34,
"name" : "FunctionCall", "name" : "FunctionCall",
"src" : "239:10:1" "src" : "239:10:1"
} }
], ],
"id" : 33, "id" : 35,
"name" : "Assignment", "name" : "Assignment",
"src" : "232:17:1" "src" : "232:17:1"
} }
], ],
"id" : 34, "id" : 36,
"name" : "ExpressionStatement", "name" : "ExpressionStatement",
"src" : "232:17:1" "src" : "232:17:1"
} }
], ],
"id" : 35, "id" : 37,
"name" : "Block", "name" : "Block",
"src" : "134:122:1" "src" : "134:122:1"
} }
], ],
"id" : 36, "id" : 38,
"name" : "FunctionDefinition", "name" : "FunctionDefinition",
"src" : "67:189:1" "src" : "67:189:1"
} }
], ],
"id" : 37, "id" : 39,
"name" : "ContractDefinition", "name" : "ContractDefinition",
"src" : "0:258:1" "src" : "0:258:1"
} }
], ],
"id" : 38, "id" : 40,
"name" : "SourceUnit", "name" : "SourceUnit",
"src" : "0:259:1" "src" : "0:259:1"
} }

View File

@ -4,10 +4,10 @@
{ {
"c" : "c" :
[ [
14 15
] ]
}, },
"id" : 15, "id" : 16,
"nodeType" : "SourceUnit", "nodeType" : "SourceUnit",
"nodes" : "nodes" :
[ [
@ -17,10 +17,10 @@
"contractKind" : "contract", "contractKind" : "contract",
"documentation" : null, "documentation" : null,
"fullyImplemented" : true, "fullyImplemented" : true,
"id" : 14, "id" : 15,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
14 15
], ],
"name" : "c", "name" : "c",
"nodeType" : "ContractDefinition", "nodeType" : "ContractDefinition",
@ -32,7 +32,7 @@
"name" : "a", "name" : "a",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 14, "scope" : 15,
"src" : "13:8:1", "src" : "13:8:1",
"stateVariable" : true, "stateVariable" : true,
"storageLocation" : "default", "storageLocation" : "default",
@ -71,7 +71,7 @@
{ {
"body" : "body" :
{ {
"id" : 12, "id" : 13,
"nodeType" : "Block", "nodeType" : "Block",
"src" : "43:25:1", "src" : "43:25:1",
"statements" : "statements" :
@ -79,17 +79,17 @@
{ {
"assignments" : "assignments" :
[ [
9 10
], ],
"declarations" : "declarations" :
[ [
{ {
"constant" : false, "constant" : false,
"id" : 9, "id" : 10,
"name" : "b", "name" : "b",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 12, "scope" : 13,
"src" : "45:16:1", "src" : "45:16:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "storage", "storageLocation" : "storage",
@ -102,7 +102,7 @@
{ {
"baseType" : "baseType" :
{ {
"id" : 7, "id" : 8,
"name" : "uint", "name" : "uint",
"nodeType" : "ElementaryTypeName", "nodeType" : "ElementaryTypeName",
"src" : "45:4:1", "src" : "45:4:1",
@ -112,7 +112,7 @@
"typeString" : "uint256" "typeString" : "uint256"
} }
}, },
"id" : 8, "id" : 9,
"length" : null, "length" : null,
"nodeType" : "ArrayTypeName", "nodeType" : "ArrayTypeName",
"src" : "45:6:1", "src" : "45:6:1",
@ -126,11 +126,11 @@
"visibility" : "internal" "visibility" : "internal"
} }
], ],
"id" : 11, "id" : 12,
"initialValue" : "initialValue" :
{ {
"argumentTypes" : null, "argumentTypes" : null,
"id" : 10, "id" : 11,
"name" : "a", "name" : "a",
"nodeType" : "Identifier", "nodeType" : "Identifier",
"overloadedDeclarations" : [], "overloadedDeclarations" : [],
@ -148,7 +148,7 @@
] ]
}, },
"documentation" : null, "documentation" : null,
"id" : 13, "id" : 14,
"implemented" : true, "implemented" : true,
"kind" : "function", "kind" : "function",
"modifiers" : [], "modifiers" : [],
@ -169,14 +169,14 @@
"parameters" : [], "parameters" : [],
"src" : "43:0:1" "src" : "43:0:1"
}, },
"scope" : 14, "scope" : 15,
"src" : "23:45:1", "src" : "23:45:1",
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
} }
], ],
"scope" : 15, "scope" : 16,
"src" : "0:70:1" "src" : "0:70:1"
} }
], ],

View File

@ -6,7 +6,7 @@
{ {
"c" : "c" :
[ [
14 15
] ]
} }
}, },
@ -28,10 +28,10 @@
"fullyImplemented" : true, "fullyImplemented" : true,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
14 15
], ],
"name" : "c", "name" : "c",
"scope" : 15 "scope" : 16
}, },
"children" : "children" :
[ [
@ -41,7 +41,7 @@
"constant" : false, "constant" : false,
"name" : "a", "name" : "a",
"overrides" : null, "overrides" : null,
"scope" : 14, "scope" : 15,
"stateVariable" : true, "stateVariable" : true,
"storageLocation" : "default", "storageLocation" : "default",
"type" : "uint256[]", "type" : "uint256[]",
@ -91,7 +91,7 @@
], ],
"name" : "f", "name" : "f",
"overrides" : null, "overrides" : null,
"scope" : 14, "scope" : 15,
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
@ -132,7 +132,7 @@
{ {
"assignments" : "assignments" :
[ [
9 10
] ]
}, },
"children" : "children" :
@ -143,7 +143,7 @@
"constant" : false, "constant" : false,
"name" : "b", "name" : "b",
"overrides" : null, "overrides" : null,
"scope" : 12, "scope" : 13,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "storage", "storageLocation" : "storage",
"type" : "uint256[]", "type" : "uint256[]",
@ -166,17 +166,17 @@
"name" : "uint", "name" : "uint",
"type" : "uint256" "type" : "uint256"
}, },
"id" : 7, "id" : 8,
"name" : "ElementaryTypeName", "name" : "ElementaryTypeName",
"src" : "45:4:1" "src" : "45:4:1"
} }
], ],
"id" : 8, "id" : 9,
"name" : "ArrayTypeName", "name" : "ArrayTypeName",
"src" : "45:6:1" "src" : "45:6:1"
} }
], ],
"id" : 9, "id" : 10,
"name" : "VariableDeclaration", "name" : "VariableDeclaration",
"src" : "45:16:1" "src" : "45:16:1"
}, },
@ -192,32 +192,32 @@
"type" : "uint256[] storage ref", "type" : "uint256[] storage ref",
"value" : "a" "value" : "a"
}, },
"id" : 10, "id" : 11,
"name" : "Identifier", "name" : "Identifier",
"src" : "64:1:1" "src" : "64:1:1"
} }
], ],
"id" : 11, "id" : 12,
"name" : "VariableDeclarationStatement", "name" : "VariableDeclarationStatement",
"src" : "45:20:1" "src" : "45:20:1"
} }
], ],
"id" : 12, "id" : 13,
"name" : "Block", "name" : "Block",
"src" : "43:25:1" "src" : "43:25:1"
} }
], ],
"id" : 13, "id" : 14,
"name" : "FunctionDefinition", "name" : "FunctionDefinition",
"src" : "23:45:1" "src" : "23:45:1"
} }
], ],
"id" : 14, "id" : 15,
"name" : "ContractDefinition", "name" : "ContractDefinition",
"src" : "0:70:1" "src" : "0:70:1"
} }
], ],
"id" : 15, "id" : 16,
"name" : "SourceUnit", "name" : "SourceUnit",
"src" : "0:71:1" "src" : "0:71:1"
} }

View File

@ -4,10 +4,10 @@
{ {
"c" : "c" :
[ [
10 11
] ]
}, },
"id" : 11, "id" : 12,
"nodeType" : "SourceUnit", "nodeType" : "SourceUnit",
"nodes" : "nodes" :
[ [
@ -17,10 +17,10 @@
"contractKind" : "contract", "contractKind" : "contract",
"documentation" : null, "documentation" : null,
"fullyImplemented" : true, "fullyImplemented" : true,
"id" : 10, "id" : 11,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
10 11
], ],
"name" : "c", "name" : "c",
"nodeType" : "ContractDefinition", "nodeType" : "ContractDefinition",
@ -29,7 +29,7 @@
{ {
"body" : "body" :
{ {
"id" : 8, "id" : 9,
"nodeType" : "Block", "nodeType" : "Block",
"src" : "33:20:1", "src" : "33:20:1",
"statements" : "statements" :
@ -37,17 +37,17 @@
{ {
"assignments" : "assignments" :
[ [
6 7
], ],
"declarations" : "declarations" :
[ [
{ {
"constant" : false, "constant" : false,
"id" : 6, "id" : 7,
"name" : "x", "name" : "x",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 8, "scope" : 9,
"src" : "35:15:1", "src" : "35:15:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "memory", "storageLocation" : "memory",
@ -60,7 +60,7 @@
{ {
"baseType" : "baseType" :
{ {
"id" : 4, "id" : 5,
"name" : "uint", "name" : "uint",
"nodeType" : "ElementaryTypeName", "nodeType" : "ElementaryTypeName",
"src" : "35:4:1", "src" : "35:4:1",
@ -70,7 +70,7 @@
"typeString" : "uint256" "typeString" : "uint256"
} }
}, },
"id" : 5, "id" : 6,
"length" : null, "length" : null,
"nodeType" : "ArrayTypeName", "nodeType" : "ArrayTypeName",
"src" : "35:6:1", "src" : "35:6:1",
@ -84,7 +84,7 @@
"visibility" : "internal" "visibility" : "internal"
} }
], ],
"id" : 7, "id" : 8,
"initialValue" : null, "initialValue" : null,
"nodeType" : "VariableDeclarationStatement", "nodeType" : "VariableDeclarationStatement",
"src" : "35:15:1" "src" : "35:15:1"
@ -92,7 +92,7 @@
] ]
}, },
"documentation" : null, "documentation" : null,
"id" : 9, "id" : 10,
"implemented" : true, "implemented" : true,
"kind" : "function", "kind" : "function",
"modifiers" : [], "modifiers" : [],
@ -113,14 +113,14 @@
"parameters" : [], "parameters" : [],
"src" : "33:0:1" "src" : "33:0:1"
}, },
"scope" : 10, "scope" : 11,
"src" : "13:40:1", "src" : "13:40:1",
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
} }
], ],
"scope" : 11, "scope" : 12,
"src" : "0:55:1" "src" : "0:55:1"
} }
], ],

View File

@ -6,7 +6,7 @@
{ {
"c" : "c" :
[ [
10 11
] ]
} }
}, },
@ -28,10 +28,10 @@
"fullyImplemented" : true, "fullyImplemented" : true,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
10 11
], ],
"name" : "c", "name" : "c",
"scope" : 11 "scope" : 12
}, },
"children" : "children" :
[ [
@ -48,7 +48,7 @@
], ],
"name" : "f", "name" : "f",
"overrides" : null, "overrides" : null,
"scope" : 10, "scope" : 11,
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
@ -89,7 +89,7 @@
{ {
"assignments" : "assignments" :
[ [
6 7
], ],
"initialValue" : null "initialValue" : null
}, },
@ -101,7 +101,7 @@
"constant" : false, "constant" : false,
"name" : "x", "name" : "x",
"overrides" : null, "overrides" : null,
"scope" : 8, "scope" : 9,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "memory", "storageLocation" : "memory",
"type" : "uint256[]", "type" : "uint256[]",
@ -124,42 +124,42 @@
"name" : "uint", "name" : "uint",
"type" : "uint256" "type" : "uint256"
}, },
"id" : 4, "id" : 5,
"name" : "ElementaryTypeName", "name" : "ElementaryTypeName",
"src" : "35:4:1" "src" : "35:4:1"
} }
], ],
"id" : 5, "id" : 6,
"name" : "ArrayTypeName", "name" : "ArrayTypeName",
"src" : "35:6:1" "src" : "35:6:1"
} }
], ],
"id" : 6, "id" : 7,
"name" : "VariableDeclaration", "name" : "VariableDeclaration",
"src" : "35:15:1" "src" : "35:15:1"
} }
], ],
"id" : 7, "id" : 8,
"name" : "VariableDeclarationStatement", "name" : "VariableDeclarationStatement",
"src" : "35:15:1" "src" : "35:15:1"
} }
], ],
"id" : 8, "id" : 9,
"name" : "Block", "name" : "Block",
"src" : "33:20:1" "src" : "33:20:1"
} }
], ],
"id" : 9, "id" : 10,
"name" : "FunctionDefinition", "name" : "FunctionDefinition",
"src" : "13:40:1" "src" : "13:40:1"
} }
], ],
"id" : 10, "id" : 11,
"name" : "ContractDefinition", "name" : "ContractDefinition",
"src" : "0:55:1" "src" : "0:55:1"
} }
], ],
"id" : 11, "id" : 12,
"name" : "SourceUnit", "name" : "SourceUnit",
"src" : "0:56:1" "src" : "0:56:1"
} }

View File

@ -4,10 +4,10 @@
{ {
"c" : "c" :
[ [
11 12
] ]
}, },
"id" : 12, "id" : 13,
"nodeType" : "SourceUnit", "nodeType" : "SourceUnit",
"nodes" : "nodes" :
[ [
@ -17,10 +17,10 @@
"contractKind" : "contract", "contractKind" : "contract",
"documentation" : null, "documentation" : null,
"fullyImplemented" : true, "fullyImplemented" : true,
"id" : 11, "id" : 12,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
11 12
], ],
"name" : "c", "name" : "c",
"nodeType" : "ContractDefinition", "nodeType" : "ContractDefinition",
@ -29,7 +29,7 @@
{ {
"body" : "body" :
{ {
"id" : 9, "id" : 10,
"nodeType" : "Block", "nodeType" : "Block",
"src" : "33:25:1", "src" : "33:25:1",
"statements" : "statements" :
@ -37,17 +37,17 @@
{ {
"assignments" : "assignments" :
[ [
7 8
], ],
"declarations" : "declarations" :
[ [
{ {
"constant" : false, "constant" : false,
"id" : 7, "id" : 8,
"name" : "rows", "name" : "rows",
"nodeType" : "VariableDeclaration", "nodeType" : "VariableDeclaration",
"overrides" : null, "overrides" : null,
"scope" : 9, "scope" : 10,
"src" : "35:20:1", "src" : "35:20:1",
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "memory", "storageLocation" : "memory",
@ -62,7 +62,7 @@
{ {
"baseType" : "baseType" :
{ {
"id" : 4, "id" : 5,
"name" : "uint", "name" : "uint",
"nodeType" : "ElementaryTypeName", "nodeType" : "ElementaryTypeName",
"src" : "35:4:1", "src" : "35:4:1",
@ -72,7 +72,7 @@
"typeString" : "uint256" "typeString" : "uint256"
} }
}, },
"id" : 5, "id" : 6,
"length" : null, "length" : null,
"nodeType" : "ArrayTypeName", "nodeType" : "ArrayTypeName",
"src" : "35:6:1", "src" : "35:6:1",
@ -82,7 +82,7 @@
"typeString" : "uint256[]" "typeString" : "uint256[]"
} }
}, },
"id" : 6, "id" : 7,
"length" : null, "length" : null,
"nodeType" : "ArrayTypeName", "nodeType" : "ArrayTypeName",
"src" : "35:8:1", "src" : "35:8:1",
@ -96,7 +96,7 @@
"visibility" : "internal" "visibility" : "internal"
} }
], ],
"id" : 8, "id" : 9,
"initialValue" : null, "initialValue" : null,
"nodeType" : "VariableDeclarationStatement", "nodeType" : "VariableDeclarationStatement",
"src" : "35:20:1" "src" : "35:20:1"
@ -104,7 +104,7 @@
] ]
}, },
"documentation" : null, "documentation" : null,
"id" : 10, "id" : 11,
"implemented" : true, "implemented" : true,
"kind" : "function", "kind" : "function",
"modifiers" : [], "modifiers" : [],
@ -125,14 +125,14 @@
"parameters" : [], "parameters" : [],
"src" : "33:0:1" "src" : "33:0:1"
}, },
"scope" : 11, "scope" : 12,
"src" : "13:45:1", "src" : "13:45:1",
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
} }
], ],
"scope" : 12, "scope" : 13,
"src" : "0:60:1" "src" : "0:60:1"
} }
], ],

View File

@ -6,7 +6,7 @@
{ {
"c" : "c" :
[ [
11 12
] ]
} }
}, },
@ -28,10 +28,10 @@
"fullyImplemented" : true, "fullyImplemented" : true,
"linearizedBaseContracts" : "linearizedBaseContracts" :
[ [
11 12
], ],
"name" : "c", "name" : "c",
"scope" : 12 "scope" : 13
}, },
"children" : "children" :
[ [
@ -48,7 +48,7 @@
], ],
"name" : "f", "name" : "f",
"overrides" : null, "overrides" : null,
"scope" : 11, "scope" : 12,
"stateMutability" : "nonpayable", "stateMutability" : "nonpayable",
"superFunction" : null, "superFunction" : null,
"visibility" : "public" "visibility" : "public"
@ -89,7 +89,7 @@
{ {
"assignments" : "assignments" :
[ [
7 8
], ],
"initialValue" : null "initialValue" : null
}, },
@ -101,7 +101,7 @@
"constant" : false, "constant" : false,
"name" : "rows", "name" : "rows",
"overrides" : null, "overrides" : null,
"scope" : 9, "scope" : 10,
"stateVariable" : false, "stateVariable" : false,
"storageLocation" : "memory", "storageLocation" : "memory",
"type" : "uint256[][]", "type" : "uint256[][]",
@ -132,47 +132,47 @@
"name" : "uint", "name" : "uint",
"type" : "uint256" "type" : "uint256"
}, },
"id" : 4, "id" : 5,
"name" : "ElementaryTypeName", "name" : "ElementaryTypeName",
"src" : "35:4:1" "src" : "35:4:1"
} }
], ],
"id" : 5, "id" : 6,
"name" : "ArrayTypeName", "name" : "ArrayTypeName",
"src" : "35:6:1" "src" : "35:6:1"
} }
], ],
"id" : 6, "id" : 7,
"name" : "ArrayTypeName", "name" : "ArrayTypeName",
"src" : "35:8:1" "src" : "35:8:1"
} }
], ],
"id" : 7, "id" : 8,
"name" : "VariableDeclaration", "name" : "VariableDeclaration",
"src" : "35:20:1" "src" : "35:20:1"
} }
], ],
"id" : 8, "id" : 9,
"name" : "VariableDeclarationStatement", "name" : "VariableDeclarationStatement",
"src" : "35:20:1" "src" : "35:20:1"
} }
], ],
"id" : 9, "id" : 10,
"name" : "Block", "name" : "Block",
"src" : "33:25:1" "src" : "33:25:1"
} }
], ],
"id" : 10, "id" : 11,
"name" : "FunctionDefinition", "name" : "FunctionDefinition",
"src" : "13:45:1" "src" : "13:45:1"
} }
], ],
"id" : 11, "id" : 12,
"name" : "ContractDefinition", "name" : "ContractDefinition",
"src" : "0:60:1" "src" : "0:60:1"
} }
], ],
"id" : 12, "id" : 13,
"name" : "SourceUnit", "name" : "SourceUnit",
"src" : "0:61:1" "src" : "0:61:1"
} }

View File

@ -0,0 +1,11 @@
contract C {
function g(address payable _p) internal pure returns (uint) {
return 1;
}
function f(address _a) public pure {
uint x = g(payable(_a));
uint y = g(_a);
}
}
// ----
// TypeError: (169-171): Invalid type for argument in function call. Invalid implicit conversion from address to address payable requested.

View File

@ -0,0 +1,9 @@
contract C {
function f() public view {
address payable p = payable(msg.sender);
address payable q = payable(address(msg.sender));
}
}
// ----
// Warning: (43-60): Unused local variable.
// Warning: (86-103): Unused local variable.

View File

@ -0,0 +1,8 @@
contract C {
function f() public pure {
address payable p = payable(this);
address payable q = payable(address(this));
}
}
// ----
// TypeError: (63-76): Explicit type conversion not allowed from "contract C" to "address payable".

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
address payable q = payable;
}
}
// ----
// ParserError: (70-71): Expected '(' but got ';'