mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Change error
from directive to keyword.
This commit is contained in:
parent
a942e630d4
commit
9d5b1b279e
16
Changelog.md
16
Changelog.md
@ -1,16 +1,10 @@
|
|||||||
|
### 0.9.0 (unreleased)
|
||||||
|
|
||||||
|
Breaking changes:
|
||||||
|
* `error` is now a keyword that can only be used for defining errors.
|
||||||
|
|
||||||
### 0.8.5 (unreleased)
|
### 0.8.5 (unreleased)
|
||||||
|
|
||||||
Language Features:
|
|
||||||
* Allowing conversion from ``bytes`` and ``bytes`` slices to ``bytes1``/.../``bytes32``.
|
|
||||||
* Yul: Add ``verbatim`` builtin function to inject arbitrary bytecode.
|
|
||||||
|
|
||||||
|
|
||||||
Compiler Features:
|
|
||||||
* Yul Optimizer: Evaluate ``keccak256(a, c)``, when the value at memory location ``a`` is known at compile time and ``c`` is a constant ``<= 32``.
|
|
||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
|
||||||
|
|
||||||
|
|
||||||
### 0.8.4 (2021-04-21)
|
### 0.8.4 (2021-04-21)
|
||||||
|
|
||||||
|
28
docs/090-breaking-changes.rst
Normal file
28
docs/090-breaking-changes.rst
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
********************************
|
||||||
|
Solidity v0.8.0 Breaking Changes
|
||||||
|
********************************
|
||||||
|
|
||||||
|
This section highlights the main breaking changes introduced in Solidity
|
||||||
|
version 0.9.0.
|
||||||
|
For the full list check
|
||||||
|
`the release changelog <https://github.com/ethereum/solidity/releases/tag/v0.9.0>`_.
|
||||||
|
|
||||||
|
Silent Changes of the Semantics
|
||||||
|
===============================
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
New Restrictions
|
||||||
|
================
|
||||||
|
|
||||||
|
- `error` is now a keyword and cannot be used as identifier anymore.
|
||||||
|
|
||||||
|
Interface Changes
|
||||||
|
=================
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
How to update your code
|
||||||
|
=======================
|
||||||
|
|
||||||
|
...
|
@ -29,7 +29,7 @@ Do: 'do';
|
|||||||
Else: 'else';
|
Else: 'else';
|
||||||
Emit: 'emit';
|
Emit: 'emit';
|
||||||
Enum: 'enum';
|
Enum: 'enum';
|
||||||
Error: 'error'; // not a real keyword
|
Error: 'error';
|
||||||
Revert: 'revert'; // not a real keyword
|
Revert: 'revert'; // not a real keyword
|
||||||
Event: 'event';
|
Event: 'event';
|
||||||
External: 'external';
|
External: 'external';
|
||||||
|
@ -13,6 +13,7 @@ sourceUnit: (
|
|||||||
pragmaDirective
|
pragmaDirective
|
||||||
| importDirective
|
| importDirective
|
||||||
| contractDefinition
|
| contractDefinition
|
||||||
|
| errorDefinition
|
||||||
| interfaceDefinition
|
| interfaceDefinition
|
||||||
| libraryDefinition
|
| libraryDefinition
|
||||||
| functionDefinition
|
| functionDefinition
|
||||||
@ -379,9 +380,9 @@ tupleExpression: LParen (expression? ( Comma expression?)* ) RParen;
|
|||||||
inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
|
inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers.
|
* Besides regular non-keyword Identifiers, some keywords like 'from' can also be used as identifiers.
|
||||||
*/
|
*/
|
||||||
identifier: Identifier | From | Error | Revert;
|
identifier: Identifier | From | Revert;
|
||||||
|
|
||||||
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
|
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
|
||||||
booleanLiteral: True | False;
|
booleanLiteral: True | False;
|
||||||
|
@ -28,8 +28,8 @@ a 0.x version number `to indicate this fast pace of change <https://semver.org/#
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
Solidity recently released the 0.8.x version that introduced a lot of breaking
|
Solidity recently released the 0.9.x version that introduced a lot of breaking
|
||||||
changes. Make sure you read :doc:`the full list <080-breaking-changes>`.
|
changes. Make sure you read :doc:`the full list <090-breaking-changes>`.
|
||||||
|
|
||||||
Ideas for improving Solidity or this documentation are always welcome,
|
Ideas for improving Solidity or this documentation are always welcome,
|
||||||
read our :doc:`contributors guide <contributing>` for more details.
|
read our :doc:`contributors guide <contributing>` for more details.
|
||||||
@ -155,6 +155,7 @@ Contents
|
|||||||
060-breaking-changes.rst
|
060-breaking-changes.rst
|
||||||
070-breaking-changes.rst
|
070-breaking-changes.rst
|
||||||
080-breaking-changes.rst
|
080-breaking-changes.rst
|
||||||
|
090-breaking-changes.rst
|
||||||
natspec-format.rst
|
natspec-format.rst
|
||||||
security-considerations.rst
|
security-considerations.rst
|
||||||
smtchecker.rst
|
smtchecker.rst
|
||||||
@ -165,4 +166,4 @@ Contents
|
|||||||
bugs.rst
|
bugs.rst
|
||||||
contributing.rst
|
contributing.rst
|
||||||
brand-guide.rst
|
brand-guide.rst
|
||||||
language-influences.rst
|
language-influences.rst
|
||||||
|
@ -158,6 +158,7 @@ namespace solidity::langutil
|
|||||||
K(Else, "else", 0) \
|
K(Else, "else", 0) \
|
||||||
K(Enum, "enum", 0) \
|
K(Enum, "enum", 0) \
|
||||||
K(Emit, "emit", 0) \
|
K(Emit, "emit", 0) \
|
||||||
|
K(Error, "error", 0) \
|
||||||
K(Event, "event", 0) \
|
K(Event, "event", 0) \
|
||||||
K(External, "external", 0) \
|
K(External, "external", 0) \
|
||||||
K(Fallback, "fallback", 0) \
|
K(Fallback, "fallback", 0) \
|
||||||
|
@ -111,17 +111,12 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
|||||||
case Token::Function:
|
case Token::Function:
|
||||||
nodes.push_back(parseFunctionDefinition(true));
|
nodes.push_back(parseFunctionDefinition(true));
|
||||||
break;
|
break;
|
||||||
|
case Token::Error:
|
||||||
|
nodes.push_back(parseErrorDefinition());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (
|
|
||||||
// Workaround because `error` is not a keyword.
|
|
||||||
m_scanner->currentToken() == Token::Identifier &&
|
|
||||||
currentLiteral() == "error" &&
|
|
||||||
m_scanner->peekNextToken() == Token::Identifier &&
|
|
||||||
m_scanner->peekNextNextToken() == Token::LParen
|
|
||||||
)
|
|
||||||
nodes.push_back(parseErrorDefinition());
|
|
||||||
// Constant variable.
|
// Constant variable.
|
||||||
else if (variableDeclarationStart() && m_scanner->peekNextToken() != Token::EOS)
|
if (variableDeclarationStart() && m_scanner->peekNextToken() != Token::EOS)
|
||||||
{
|
{
|
||||||
VarDeclParserOptions options;
|
VarDeclParserOptions options;
|
||||||
options.kind = VarDeclKind::FileLevel;
|
options.kind = VarDeclKind::FileLevel;
|
||||||
@ -359,13 +354,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
subNodes.push_back(parseStructDefinition());
|
subNodes.push_back(parseStructDefinition());
|
||||||
else if (currentTokenValue == Token::Enum)
|
else if (currentTokenValue == Token::Enum)
|
||||||
subNodes.push_back(parseEnumDefinition());
|
subNodes.push_back(parseEnumDefinition());
|
||||||
else if (
|
else if (currentTokenValue == Token::Error)
|
||||||
// Workaround because `error` is not a keyword.
|
|
||||||
currentTokenValue == Token::Identifier &&
|
|
||||||
currentLiteral() == "error" &&
|
|
||||||
m_scanner->peekNextToken() == Token::Identifier &&
|
|
||||||
m_scanner->peekNextNextToken() == Token::LParen
|
|
||||||
)
|
|
||||||
subNodes.push_back(parseErrorDefinition());
|
subNodes.push_back(parseErrorDefinition());
|
||||||
else if (variableDeclarationStart())
|
else if (variableDeclarationStart())
|
||||||
{
|
{
|
||||||
@ -936,7 +925,7 @@ ASTPointer<ErrorDefinition> Parser::parseErrorDefinition()
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
|
ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
|
||||||
|
|
||||||
solAssert(*expectIdentifierToken() == "error", "");
|
expectToken(Token::Error);
|
||||||
auto&& [name, nameLocation] = expectIdentifierWithLocation();
|
auto&& [name, nameLocation] = expectIdentifierWithLocation();
|
||||||
|
|
||||||
ASTPointer<ParameterList> parameters = parseParameterList({});
|
ASTPointer<ParameterList> parameters = parseParameterList({});
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
error error(uint a);
|
|
||||||
contract C {
|
|
||||||
function f() public pure {
|
|
||||||
revert error(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ====
|
|
||||||
// compileViaYul: also
|
|
||||||
// compileToEwasm: also
|
|
||||||
// ----
|
|
||||||
// f() -> FAILURE, hex"b48fb6cf", hex"0000000000000000000000000000000000000000000000000000000000000002"
|
|
@ -1,18 +0,0 @@
|
|||||||
struct error { uint error; }
|
|
||||||
contract C {
|
|
||||||
error test();
|
|
||||||
error _struct;
|
|
||||||
function f() public {
|
|
||||||
revert test();
|
|
||||||
}
|
|
||||||
function g(uint x) public returns (uint) {
|
|
||||||
_struct.error = x;
|
|
||||||
return _struct.error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ====
|
|
||||||
// compileViaYul: also
|
|
||||||
// compileToEwasm: also
|
|
||||||
// ----
|
|
||||||
// f() -> FAILURE, hex"f8a8fd6d"
|
|
||||||
// g(uint256): 7 -> 7
|
|
@ -1,6 +1,6 @@
|
|||||||
// Test that the parser workaround is not breaking.
|
|
||||||
struct error {uint a;}
|
struct error {uint a;}
|
||||||
contract C {
|
contract C {
|
||||||
error x;
|
error x;
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
|
// ParserError 2314: (7-12): Expected identifier but got 'error'
|
||||||
|
8
test/libsolidity/syntaxTests/errors/weird_name.sol
Normal file
8
test/libsolidity/syntaxTests/errors/weird_name.sol
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error error(uint a);
|
||||||
|
contract C {
|
||||||
|
function f() public pure {
|
||||||
|
revert error(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// ParserError 2314: (6-11): Expected identifier but got 'error'
|
@ -4,7 +4,7 @@ contract test {
|
|||||||
|
|
||||||
} catch Error(string memory message) {
|
} catch Error(string memory message) {
|
||||||
|
|
||||||
} catch (bytes memory error) {
|
} catch (bytes memory _error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,4 +15,4 @@ contract test {
|
|||||||
// Warning 5667: (49-55): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
// Warning 5667: (49-55): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||||
// Warning 5667: (89-95): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.
|
// Warning 5667: (89-95): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.
|
||||||
// Warning 5667: (122-143): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.
|
// Warning 5667: (122-143): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.
|
||||||
// Warning 5667: (165-183): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.
|
// Warning 5667: (165-184): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.
|
||||||
|
Loading…
Reference in New Issue
Block a user