Revert "Change error from directive to keyword."

This reverts commit 9d5b1b279e.
This commit is contained in:
Kamil Śliwak 2021-08-30 16:37:58 +02:00 committed by chriseth
parent e6b642699b
commit b5f90c6248
10 changed files with 51 additions and 22 deletions

View File

@ -1,7 +1,6 @@
### 0.9.0 (unreleased) ### 0.9.0 (unreleased)
Breaking changes: Breaking changes:
* `error` is now a keyword that can only be used for defining errors.
* Inline Assembly: Consider functions, function parameters and return variables for shadowing checks. * Inline Assembly: Consider functions, function parameters and return variables for shadowing checks.

View File

@ -15,7 +15,7 @@ Silent Changes of the Semantics
New Restrictions New Restrictions
================ ================
- `error` is now a keyword and cannot be used as identifier anymore. ...
Interface Changes Interface Changes
================= =================

View File

@ -29,7 +29,7 @@ Do: 'do';
Else: 'else'; Else: 'else';
Emit: 'emit'; Emit: 'emit';
Enum: 'enum'; Enum: 'enum';
Error: 'error'; Error: 'error'; // not a real keyword
Revert: 'revert'; // not a real keyword Revert: 'revert'; // not a real keyword
Event: 'event'; Event: 'event';
External: 'external'; External: 'external';

View File

@ -13,7 +13,6 @@ sourceUnit: (
pragmaDirective pragmaDirective
| importDirective | importDirective
| contractDefinition | contractDefinition
| errorDefinition
| interfaceDefinition | interfaceDefinition
| libraryDefinition | libraryDefinition
| functionDefinition | functionDefinition
@ -380,9 +379,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' can also be used as identifiers. * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers.
*/ */
identifier: Identifier | From | Revert; identifier: Identifier | From | Error | Revert;
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
booleanLiteral: True | False; booleanLiteral: True | False;

View File

@ -156,7 +156,6 @@ 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

@ -116,12 +116,17 @@ ASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)
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.
if (variableDeclarationStart() && m_scanner->peekNextToken() != Token::EOS) else if (variableDeclarationStart() && m_scanner->peekNextToken() != Token::EOS)
{ {
VarDeclParserOptions options; VarDeclParserOptions options;
options.kind = VarDeclKind::FileLevel; options.kind = VarDeclKind::FileLevel;
@ -359,7 +364,13 @@ 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 (currentTokenValue == Token::Error) else if (
// 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())
{ {
@ -930,7 +941,7 @@ ASTPointer<ErrorDefinition> Parser::parseErrorDefinition()
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation(); ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
expectToken(Token::Error); solAssert(*expectIdentifierToken() == "error", "");
auto&& [name, nameLocation] = expectIdentifierWithLocation(); auto&& [name, nameLocation] = expectIdentifierWithLocation();
ASTPointer<ParameterList> parameters = parseParameterList({}); ASTPointer<ParameterList> parameters = parseParameterList({});

View File

@ -0,0 +1,11 @@
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

@ -0,0 +1,18 @@
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

@ -1,8 +0,0 @@
error error(uint a);
contract C {
function f() public pure {
revert error(2);
}
}
// ----
// ParserError 2314: (6-11): Expected identifier but got 'error'