Merge pull request #11218 from ethereum/error-kw

Change `error` from directive to keyword.
This commit is contained in:
Harikrishnan Mulackal 2021-04-28 11:41:02 +02:00 committed by GitHub
commit 2ccdfe5456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 59 additions and 66 deletions

View File

@ -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)

View 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
=======================
...

View File

@ -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';

View File

@ -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;

View File

@ -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

View File

@ -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) \

View File

@ -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({});

View File

@ -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"

View File

@ -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

View File

@ -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'

View 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'

View File

@ -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.