mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11859 from ethereum/revert-making-error-a-keyword
Revert making `error` a keyword
This commit is contained in:
commit
359bc09ada
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
=================
|
=================
|
||||||
|
@ -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';
|
||||||
|
@ -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;
|
||||||
|
@ -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) \
|
||||||
|
@ -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({});
|
||||||
|
11
test/libsolidity/semanticTests/errors/weird_name.sol
Normal file
11
test/libsolidity/semanticTests/errors/weird_name.sol
Normal 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"
|
18
test/libsolidity/semanticTests/reverts/error_struct.sol
Normal file
18
test/libsolidity/semanticTests/reverts/error_struct.sol
Normal 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
|
@ -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'
|
|
||||||
|
@ -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'
|
|
Loading…
Reference in New Issue
Block a user