@@ -1178,15 +1178,16 @@ class ParserBase {
11781178 scope ()->scope_type () == REPL_MODE_SCOPE) &&
11791179 !scope ()->is_nonlinear ());
11801180 }
1181- bool IsNextUsingKeyword (Token::Value token_after_using, bool is_await_using) {
1181+ bool IsNextUsingKeyword (bool is_await_using) {
11821182 // using and await using declarations in for-of statements must be followed
1183- // by a non-pattern ForBinding. In the case of synchronous `using`, `of` is
1184- // disallowed as well with a negative lookahead.
1183+ // by a non-pattern ForBinding.
11851184 //
11861185 // `of`: for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using]
11871186 // of AssignmentExpression[+In, ?Yield, ?Await] )
11881187 //
11891188 // If `using` is not considered a keyword, it is parsed as an identifier.
1189+ Token::Value token_after_using =
1190+ is_await_using ? PeekAheadAhead () : PeekAhead ();
11901191 if (v8_flags.js_explicit_resource_management ) {
11911192 switch (token_after_using) {
11921193 case Token::kIdentifier :
@@ -1201,7 +1202,16 @@ class ParserBase {
12011202 case Token::kAsync :
12021203 return true ;
12031204 case Token::kOf :
1204- return is_await_using;
1205+ if (is_await_using) {
1206+ return true ;
1207+ } else {
1208+ // In the case of synchronous `using`, `of` is disallowed as well
1209+ // with a negative lookahead for for-of loops. But, cursedly,
1210+ // `using of` is allowed as the initializer of C-style for loops,
1211+ // e.g. `for (using of = null;;)` parses.
1212+ Token::Value token_after_of = PeekAheadAhead ();
1213+ return token_after_of == Token::kAssign ;
1214+ }
12051215 case Token::kFutureStrictReservedWord :
12061216 case Token::kEscapedStrictReservedWord :
12071217 return is_sloppy (language_mode ());
@@ -1220,12 +1230,12 @@ class ParserBase {
12201230 // LineTerminator here] ForBinding[?Yield, +Await, ~Pattern]
12211231 return ((peek () == Token::kUsing &&
12221232 !scanner ()->HasLineTerminatorAfterNext () &&
1223- IsNextUsingKeyword (PeekAhead (), /* is_await_using */ false )) ||
1233+ IsNextUsingKeyword (/* is_await_using */ false )) ||
12241234 (is_await_allowed () && peek () == Token::kAwait &&
12251235 !scanner ()->HasLineTerminatorAfterNext () &&
12261236 PeekAhead () == Token::kUsing &&
12271237 !scanner ()->HasLineTerminatorAfterNextNext () &&
1228- IsNextUsingKeyword (PeekAheadAhead (), /* is_await_using */ true )));
1238+ IsNextUsingKeyword (/* is_await_using */ true )));
12291239 }
12301240 const PendingCompilationErrorHandler* pending_error_handler () const {
12311241 return pending_error_handler_;
0 commit comments