Bug 1455463 - Make calls to checkFields more explicit r=arai
authorDavid Teller <dteller@mozilla.com>
Fri, 20 Apr 2018 16:40:08 +0200
changeset 468511 fbc02c102431e96bbc6bc760749aaae48a821a99
parent 468510 8d4cf28964f6956cd22d8710b316456e2c7c848d
child 468512 f37ff744e424a027509a40dc95232dc2bf5e6f52
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1455463
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1455463 - Make calls to checkFields more explicit r=arai 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,