Bug 1455463 - Make calls to checkFields more explicit draft
authorDavid Teller <dteller@mozilla.com>
Fri, 20 Apr 2018 16:40:08 +0200
changeset 785628 f46a3faf0a0af88daa8d2cfd8035599f8ff4a13d
parent 784331 8522a923adf1dab707dc1d21f3602564d4ef1b22
push id107282
push userdteller@mozilla.com
push dateFri, 20 Apr 2018 14:40:38 +0000
bugs1455463
milestone61.0a1
Bug 1455463 - Make calls to checkFields more explicit Apparently, older versions of clang have difficulties with our call to checkFields. This might help. MozReview-Commit-ID: C7dn7EwcazI
js/src/frontend/BinSource-auto.cpp
js/src/frontend/binsource/src/main.rs
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -2620,17 +2620,22 @@ BinASTParser<Tok>::parseArrayExpression(
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ArrayExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Elements }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Elements };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(elements, parseListOfOptionalSpreadElementOrExpression());
 
 
     auto result = elements;
     return result;
@@ -2661,17 +2666,22 @@ BinASTParser<Tok>::parseAssertedBlockSco
 }
 
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::AssertedBlockScope);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::LexicallyDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::LexicallyDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     MOZ_TRY(parseAndUpdateScopeNames(*parseContext_->innermostScope(), DeclarationKind::Let));
     MOZ_TRY(parseAndUpdateCapturedNames());
 
 
 
     BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool());
     if (hasDirectEval) {
         parseContext_->sc()->setHasDirectEval();
@@ -2712,17 +2722,22 @@ BinASTParser<Tok>::parseAssertedParamete
 }
 
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::AssertedParameterScope);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::ParameterNames, BinField::CapturedNames, BinField::HasDirectEval }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::ParameterNames, BinField::CapturedNames, BinField::HasDirectEval };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     MOZ_TRY(parseAndUpdateScopeNames(parseContext_->functionScope(), DeclarationKind:: PositionalFormalParameter));
     MOZ_TRY(parseAndUpdateCapturedNames());
 
 
 
     BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool());
     if (hasDirectEval) {
         parseContext_->sc()->setHasDirectEval();
@@ -2764,17 +2779,22 @@ BinASTParser<Tok>::parseAssertedVarScope
 }
 
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::AssertedVarScope);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::LexicallyDeclaredNames, BinField::VarDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[4] = { BinField::LexicallyDeclaredNames, BinField::VarDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     MOZ_TRY(parseAndUpdateScopeNames(*parseContext_->innermostScope(), DeclarationKind::Let));
     MOZ_TRY(parseAndUpdateScopeNames(parseContext_->varScope(), DeclarationKind::Var));
     MOZ_TRY(parseAndUpdateCapturedNames());
 
 
 
     BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool());
     if (hasDirectEval) {
@@ -2815,17 +2835,22 @@ BinASTParser<Tok>::parseAssignmentExpres
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::AssignmentExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Binding, BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Binding, BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(binding, parseAssignmentTarget());
 
 
 
 
@@ -2859,17 +2884,22 @@ BinASTParser<Tok>::parseAssignmentTarget
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::AssignmentTargetIdentifier);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Name };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom name(cx_);
     MOZ_TRY_VAR(name, tokenizer_->readAtom());
 
 
     if (!IsIdentifier(name))
         return raiseError("Invalid identifier");
@@ -3017,17 +3047,22 @@ BinASTParser<Tok>::parseBinaryExpression
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::BinaryExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Operator, BinField::Left, BinField::Right }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Operator, BinField::Left, BinField::Right };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(operator_, parseBinaryOperator());
 
 
 
 
@@ -3158,17 +3193,22 @@ BinASTParser<Tok>::parseBindingIdentifie
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::BindingIdentifier);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Name };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom name(cx_);
     MOZ_TRY_VAR(name, tokenizer_->readAtom());
 
 
     if (!IsIdentifier(name))
         return raiseError("Invalid identifier");
@@ -3287,17 +3327,22 @@ BinASTParser<Tok>::parseBlock()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::Block);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Scope, BinField::Statements }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Scope, BinField::Statements };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     ParseContext::Statement stmt(parseContext_, StatementKind::Block);
     ParseContext::Scope currentScope(cx_, parseContext_, usedNames_);
     BINJS_TRY(currentScope.init(parseContext_));
 
 
     MOZ_TRY(parseOptionalAssertedBlockScope());
 
 
@@ -3334,17 +3379,22 @@ BinASTParser<Tok>::parseBreakStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::BreakStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Label }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Label };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     RootedAtom label(cx_);
     MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom());
 
     if (label) {
         if (!IsIdentifier(label))
             return raiseError("Invalid identifier");
 
         auto validity = parseContext_->checkBreakStatement(label->asPropertyName());
@@ -3386,17 +3436,22 @@ BinASTParser<Tok>::parseCallExpression()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::CallExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Callee, BinField::Arguments }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Callee, BinField::Arguments };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(callee, parseExpressionOrSuper());
 
 
 
 
@@ -3446,17 +3501,22 @@ BinASTParser<Tok>::parseCatchClause()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::CatchClause);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Binding, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Binding, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     ParseContext::Statement stmt(parseContext_, StatementKind::Catch);
     ParseContext::Scope currentScope(cx_, parseContext_, usedNames_);
     BINJS_TRY(currentScope.init(parseContext_));
 
 
     BINJS_MOZ_TRY_DECL(binding, parseBinding());
 
 
@@ -3591,17 +3651,22 @@ BinASTParser<Tok>::parseCompoundAssignme
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::CompoundAssignmentExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Operator, BinField::Binding, BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Operator, BinField::Binding, BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(operator_, parseCompoundAssignmentOperator());
 
 
 
 
@@ -3680,17 +3745,22 @@ BinASTParser<Tok>::parseComputedMemberAs
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ComputedMemberAssignmentTarget);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Object, BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
 
 
 
 
@@ -3725,17 +3795,22 @@ BinASTParser<Tok>::parseComputedMemberEx
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceComputedMemberExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ComputedMemberExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Object, BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
 
 
 
 
@@ -3799,17 +3874,22 @@ BinASTParser<Tok>::parseConditionalExpre
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceConditionalExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ConditionalExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Consequent, BinField::Alternate }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Test, BinField::Consequent, BinField::Alternate };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
 
 
 
@@ -3848,17 +3928,22 @@ BinASTParser<Tok>::parseContinueStatemen
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceContinueStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ContinueStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Label }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Label };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     RootedAtom label(cx_);
     MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom());
 
     if (label) {
         if (!IsIdentifier(label))
             return raiseError("ContinueStatement - Label MUST be an identifier");
 
         auto validity = parseContext_->checkContinueStatement(label ? label->asPropertyName() : nullptr);
@@ -3900,17 +3985,22 @@ BinASTParser<Tok>::parseDataProperty()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDataProperty(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::DataProperty);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name, BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Name, BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(name, parsePropertyName());
 
 
 
 
@@ -3974,17 +4064,22 @@ BinASTParser<Tok>::parseDirective()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDirective(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::Directive);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::RawValue }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::RawValue };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom rawValue(cx_);
     MOZ_TRY_VAR(rawValue, tokenizer_->readAtom());
 
 
     TokenPos pos = tokenizer_->pos(start);
     BINJS_TRY_DECL(result, factory_.newStringLiteral(rawValue, pos));
@@ -4015,17 +4110,22 @@ BinASTParser<Tok>::parseDoWhileStatement
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDoWhileStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::DoWhileStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Test, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     ParseContext::Statement stmt(parseContext_, StatementKind::DoLoop);
 
 
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
 
 
 
@@ -4097,17 +4197,22 @@ BinASTParser<Tok>::parseEagerFunctionDec
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerFunctionDeclaration);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     const auto syntax = FunctionSyntaxKind::Statement;
 
 
     BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool());
 
 
 
 
@@ -4188,17 +4293,22 @@ BinASTParser<Tok>::parseEagerFunctionExp
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerFunctionExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     const auto syntax = FunctionSyntaxKind::Expression;
 
 
     BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool());
 
 
 
 
@@ -4275,17 +4385,22 @@ BinASTParser<Tok>::parseEagerGetter()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerGetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerGetter);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::BodyScope, BinField::Name, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::BodyScope, BinField::Name, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     MOZ_TRY(parseOptionalAssertedVarScope());
 
 
 
 
@@ -4344,17 +4459,22 @@ BinASTParser<Tok>::parseEagerMethod()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerMethod);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     const auto syntax = FunctionSyntaxKind::Method;
 
 
     BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool());
 
 
 
 
@@ -4432,17 +4552,22 @@ BinASTParser<Tok>::parseEagerSetter()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerSetter);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Param, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[5] = { BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Param, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     MOZ_TRY(parseOptionalAssertedParameterScope());
 
 
 
 
@@ -4505,17 +4630,17 @@ BinASTParser<Tok>::parseEmptyStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EmptyStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields0(kind, fields));
+MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     BINJS_TRY_DECL(result, factory_.newEmptyStatement(tokenizer_->pos(start)));
     return result;
 }
 
 
 /*
  interface Export : Node {
@@ -4738,17 +4863,22 @@ BinASTParser<Tok>::parseExpressionStatem
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ExpressionStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
 
     BINJS_TRY_DECL(result, factory_.newExprStatement(expression, tokenizer_->offset()));
     return result;
@@ -4778,17 +4908,22 @@ BinASTParser<Tok>::parseForInOfBinding()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ForInOfBinding);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Kind, BinField::Binding }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Kind, BinField::Binding };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     AutoVariableDeclarationKind kindGuard(this);
 
 
     BINJS_MOZ_TRY_DECL(kind_, parseVariableDeclarationKind());
 
 
 
 
@@ -4832,17 +4967,22 @@ BinASTParser<Tok>::parseForInStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ForInStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Left, BinField::Right, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Left, BinField::Right, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     ParseContext::Statement stmt(parseContext_, StatementKind::ForInLoop);
 
     // Implicit scope around the `for`, used to store `for (let x in  ...)`
     // or `for (const x in ...)`-style declarations. Detail on the
     // declaration is stored as part of `scope`.
     ParseContext::Scope scope(cx_, parseContext_, usedNames_);
     BINJS_TRY(scope.init(parseContext_));
 
@@ -4926,17 +5066,22 @@ BinASTParser<Tok>::parseForStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ForStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Init, BinField::Test, BinField::Update, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[4] = { BinField::Init, BinField::Test, BinField::Update, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     ParseContext::Statement stmt(parseContext_, StatementKind::ForLoop);
 
     // Implicit scope around the `for`, used to store `for (let x; ...; ...)`
     // or `for (const x; ...; ...)`-style declarations. Detail on the
     // declaration is stored as part of `BINJS_Scope`.
     ParseContext::Scope scope(cx_, parseContext_, usedNames_);
     BINJS_TRY(scope.init(parseContext_));
 
@@ -4993,17 +5138,22 @@ BinASTParser<Tok>::parseFormalParameters
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceFormalParameters(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::FormalParameters);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Items, BinField::Rest }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Items, BinField::Rest };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(items, parseListOfParameter());
 
 
 
 
@@ -5042,17 +5192,22 @@ BinASTParser<Tok>::parseFunctionBody()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceFunctionBody(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::FunctionBody);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Directives, BinField::Statements }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Directives, BinField::Statements };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(directives, parseListOfDirective());
 
 
 
 
@@ -5086,17 +5241,22 @@ BinASTParser<Tok>::parseIdentifierExpres
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::IdentifierExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Name };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom name(cx_);
     MOZ_TRY_VAR(name, tokenizer_->readAtom());
 
 
     if (!IsIdentifier(name))
         return raiseError("Invalid identifier");
@@ -5129,17 +5289,22 @@ BinASTParser<Tok>::parseIfStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::IfStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Consequent, BinField::Alternate }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Test, BinField::Consequent, BinField::Alternate };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
 
 
 
@@ -5268,17 +5433,22 @@ BinASTParser<Tok>::parseLabelledStatemen
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LabelledStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Label, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Label, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom label(cx_);
     MOZ_TRY_VAR(label, tokenizer_->readAtom());
     if (!IsIdentifier(label))
         return raiseError("Invalid identifier");
     ParseContext::LabelStatement stmt(parseContext_, label);
 
@@ -5314,17 +5484,22 @@ BinASTParser<Tok>::parseLiteralBooleanEx
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralBooleanExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralBooleanExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Value };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(value, tokenizer_->readBool());
 
 
     BINJS_TRY_DECL(result, factory_.newBooleanLiteral(value, tokenizer_->pos(start)));
     return result;
@@ -5379,17 +5554,17 @@ BinASTParser<Tok>::parseLiteralNullExpre
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralNullExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralNullExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields0(kind, fields));
+MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     BINJS_TRY_DECL(result, factory_.newNullLiteral(tokenizer_->pos(start)));
     return result;
 }
 
 
 /*
  interface LiteralNumericExpression : Node {
@@ -5413,17 +5588,22 @@ BinASTParser<Tok>::parseLiteralNumericEx
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralNumericExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralNumericExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Value };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(value, tokenizer_->readDouble());
 
 
     BINJS_TRY_DECL(result, factory_.newNumber(value, DecimalPoint::HasDecimal, tokenizer_->pos(start)));
     return result;
@@ -5452,17 +5632,22 @@ BinASTParser<Tok>::parseLiteralPropertyN
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralPropertyName(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralPropertyName);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Value };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom value(cx_);
     MOZ_TRY_VAR(value, tokenizer_->readAtom());
 
 
     ParseNode* result;
     uint32_t index;
@@ -5497,17 +5682,22 @@ BinASTParser<Tok>::parseLiteralRegExpExp
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralRegExpExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralRegExpExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Pattern, BinField::Flags }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Pattern, BinField::Flags };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom pattern(cx_);
     MOZ_TRY_VAR(pattern, tokenizer_->readAtom());
 
     Chars flags(cx_);
     MOZ_TRY(tokenizer_->readChars(flags));
 
@@ -5562,17 +5752,22 @@ BinASTParser<Tok>::parseLiteralStringExp
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralStringExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralStringExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Value };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
     RootedAtom value(cx_);
     MOZ_TRY_VAR(value, tokenizer_->readAtom());
 
 
     BINJS_TRY_DECL(result, factory_.newStringLiteral(value, tokenizer_->pos(start)));
     return result;
@@ -5632,17 +5827,22 @@ BinASTParser<Tok>::parseNewExpression()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceNewExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::NewExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Callee, BinField::Arguments }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Callee, BinField::Arguments };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(callee, parseExpression());
 
 
 
 
@@ -5761,17 +5961,22 @@ BinASTParser<Tok>::parseObjectExpression
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceObjectExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ObjectExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Properties }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Properties };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(properties, parseListOfObjectProperty());
 
 
     auto result = properties;
     return result;
@@ -5800,17 +6005,22 @@ BinASTParser<Tok>::parseReturnStatement(
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceReturnStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ReturnStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     if (!parseContext_->isFunctionBox()) {
         // Return statements are permitted only inside functions.
         return raiseInvalidKind("Toplevel Statement", kind);
     }
 
     parseContext_->functionBox()->usesReturn = true;
 
 
@@ -5846,17 +6056,22 @@ BinASTParser<Tok>::parseScript()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceScript(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::Script);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Scope, BinField::Directives, BinField::Statements }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Scope, BinField::Directives, BinField::Statements };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     MOZ_TRY(parseOptionalAssertedVarScope());
 
 
 
 
@@ -5895,17 +6110,22 @@ BinASTParser<Tok>::parseShorthandPropert
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceShorthandProperty(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ShorthandProperty);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Name };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(name, parseIdentifierExpression());
 
 
     if (!factory_.isUsableAsObjectPropertyName(name))
         BINJS_TRY_VAR(name, factory_.newObjectLiteralPropertyName(name->name(), tokenizer_->pos(start)));
@@ -6134,17 +6354,22 @@ BinASTParser<Tok>::parseStaticMemberAssi
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceStaticMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::StaticMemberAssignmentTarget);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Property }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Object, BinField::Property };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
 
 
 
     RootedAtom property(cx_);
@@ -6179,17 +6404,22 @@ BinASTParser<Tok>::parseStaticMemberExpr
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceStaticMemberExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::StaticMemberExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Property }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Object, BinField::Property };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
 
 
 
     RootedAtom property(cx_);
@@ -6251,17 +6481,22 @@ BinASTParser<Tok>::parseSwitchCase()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSwitchCase(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::SwitchCase);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Consequent }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Test, BinField::Consequent };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
 
 
 
@@ -6295,17 +6530,22 @@ BinASTParser<Tok>::parseSwitchDefault()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::SwitchDefault);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Consequent }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Consequent };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(consequent, parseListOfStatement());
 
 
     BINJS_TRY_DECL(result, factory_.newCaseOrDefault(start, nullptr, consequent));
     return result;
@@ -6335,17 +6575,22 @@ BinASTParser<Tok>::parseSwitchStatement(
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::SwitchStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Discriminant, BinField::Cases }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Discriminant, BinField::Cases };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(discriminant, parseExpression());
 
 
 
 
@@ -6383,17 +6628,22 @@ BinASTParser<Tok>::parseSwitchStatementW
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::SwitchStatementWithDefault);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Discriminant, BinField::PreDefaultCases, BinField::DefaultCase, BinField::PostDefaultCases }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[4] = { BinField::Discriminant, BinField::PreDefaultCases, BinField::DefaultCase, BinField::PostDefaultCases };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(discriminant, parseExpression());
 
 
 
 
@@ -6503,17 +6753,17 @@ BinASTParser<Tok>::parseThisExpression()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ThisExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields0(kind, fields));
+MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     if (parseContext_->isFunctionBox())
         parseContext_->functionBox()->usesThis = true;
 
     TokenPos pos = tokenizer_->pos(start);
     ParseNode* thisName(nullptr);
     if (parseContext_->sc()->thisBinding() == ThisBinding::Function)
         BINJS_TRY_VAR(thisName, factory_.newName(cx_->names().dotThis, pos, cx_));
@@ -6545,17 +6795,22 @@ BinASTParser<Tok>::parseThrowStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ThrowStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Expression }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[1] = { BinField::Expression };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
 
     BINJS_TRY_DECL(result, factory_.newThrowStatement(expression, tokenizer_->pos(start)));
     return result;
@@ -6585,17 +6840,22 @@ BinASTParser<Tok>::parseTryCatchStatemen
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceTryCatchStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::TryCatchStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Body, BinField::CatchClause }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Body, BinField::CatchClause };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
     ParseNode* body;
     {
         ParseContext::Statement stmt(parseContext_, StatementKind::Try);
         ParseContext::Scope scope(cx_, parseContext_, usedNames_);
         BINJS_TRY(scope.init(parseContext_));
         MOZ_TRY_VAR(body, parseBlock());
 
@@ -6635,17 +6895,22 @@ BinASTParser<Tok>::parseTryFinallyStatem
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceTryFinallyStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::TryFinallyStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Body, BinField::CatchClause, BinField::Finalizer }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::Body, BinField::CatchClause, BinField::Finalizer };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
     ParseNode* body;
     {
         ParseContext::Statement stmt(parseContext_, StatementKind::Try);
         ParseContext::Scope scope(cx_, parseContext_, usedNames_);
         BINJS_TRY(scope.init(parseContext_));
         MOZ_TRY_VAR(body, parseBlock());
 
@@ -6693,17 +6958,22 @@ BinASTParser<Tok>::parseUnaryExpression(
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceUnaryExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::UnaryExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Operator, BinField::Operand }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Operator, BinField::Operand };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(operator_, parseUnaryOperator());
 
 
 
 
@@ -6781,17 +7051,22 @@ BinASTParser<Tok>::parseUpdateExpression
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceUpdateExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::UpdateExpression);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsPrefix, BinField::Operator, BinField::Operand }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[3] = { BinField::IsPrefix, BinField::Operator, BinField::Operand };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(isPrefix, tokenizer_->readBool());
 
 
 
 
@@ -6842,17 +7117,22 @@ BinASTParser<Tok>::parseVariableDeclarat
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::VariableDeclaration);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Kind, BinField::Declarators }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Kind, BinField::Declarators };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     AutoVariableDeclarationKind kindGuard(this);
 
 
     BINJS_MOZ_TRY_DECL(kind_, parseVariableDeclarationKind());
     // Restored by `kindGuard`.
     variableDeclarationKind_ = kind_;
 
 
@@ -6905,17 +7185,22 @@ BinASTParser<Tok>::parseVariableDeclarat
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceVariableDeclarator(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::VariableDeclarator);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Binding, BinField::Init }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Binding, BinField::Init };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(binding, parseBinding());
 
 
 
 
@@ -6967,17 +7252,22 @@ BinASTParser<Tok>::parseWhileStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceWhileStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::WhileStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Test, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
     ParseContext::Statement stmt(parseContext_, StatementKind::WhileLoop);
 
 
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
 
 
 
@@ -7012,17 +7302,22 @@ BinASTParser<Tok>::parseWithStatement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceWithStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::WithStatement);
     CheckRecursionLimit(cx_);
 
-    MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Body }));
+
+#if defined(DEBUG)
+    const BinField expected_fields[2] = { BinField::Object, BinField::Body };
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+
 
 
 
     BINJS_MOZ_TRY_DECL(object, parseExpression());
 
 
 
 
--- a/js/src/frontend/binsource/src/main.rs
+++ b/js/src/frontend/binsource/src/main.rs
@@ -1111,25 +1111,32 @@ impl CPPExporter {
 ",
                 kind = kind.to_str(),
                 first_line = first_line,
             ));
         } else {
             let check_fields = if number_of_fields == 0 {
                 format!("MOZ_TRY(tokenizer_->checkFields0(kind, fields));")
             } else {
-                format!("MOZ_TRY(tokenizer_->checkFields(kind, fields, {fields_type_list}));",
-                    fields_type_list = fields_type_list)
+                // The following strategy is designed for old versions of clang.
+                format!("
+#if defined(DEBUG)
+    const BinField expected_fields[{number_of_fields}] = {fields_type_list};
+    MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
+#endif // defined(DEBUG)
+",
+                    fields_type_list = fields_type_list,
+                    number_of_fields = number_of_fields)
             };
             buffer.push_str(&format!("{first_line}
 {{
     MOZ_ASSERT(kind == BinKind::{kind});
     CheckRecursionLimit(cx_);
 
-    {check_fields}
+{check_fields}
 {pre}{fields_implem}
 {post}
     return result;
 }}
 
 ",
                 check_fields = check_fields,
                 fields_implem = fields_implem,