Skip to content

[parser/spec] initializerExpression inconsistency between the spec and implementation: the spec does not support some constructs supported by the implementation. #54271

Open
@modulovalue

Description

@modulovalue

@eernst wrote in #51482 (comment)

(Actually, looking at this, I believe initializerExpression should include throw and assignment expressions; but I've never seen any failures because they aren't currently included).

Here's one failure:

class AssertAlwaysThrows_Constructor {
Object a;
Object b;
AssertAlwaysThrows_Constructor(
Object o, Object p, bool Function(Object, Object) f)
: a = o is int ? true : throw 'x',
b = throw 'x',
assert(f(o = p, throw 'x')) {
/*int*/ o;
}
}

The spec does not appear to support throw expressions in constructor initializer expressions.

Throw expressions are supported by the implementation (actually, throwExpressionWithoutCascade), but not by the spec:

class Foo {
  int i = 0;
  Foo(int j) : i = throw 0;
}
 === Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-55]
┗━ <ClassDeclarationImpl> [0-54]
  ┣━ 'class' [0-5]
  ┣━ 'Foo' [6-9]
  ┣━ '{' [10-11]
  ┣━ <FieldDeclarationImpl> [14-24]
  ┃  ┣━ <VariableDeclarationListImpl> [14-23]
  ┃  ┃  ┣━ <NamedTypeImpl> [14-17]
  ┃  ┃  ┃  ┗━ 'int' [14-17]
  ┃  ┃  ┗━ <VariableDeclarationImpl> [18-23]
  ┃  ┃    ┣━ 'i' [18-19]
  ┃  ┃    ┣━ '=' [20-21]
  ┃  ┃    ┗━ <IntegerLiteralImpl> [22-23]
  ┃  ┃      ┗━ '0' [22-23]
  ┃  ┗━ ';' [23-24]
  ┣━ <ConstructorDeclarationImpl> [27-52]
  ┃  ┣━ <SimpleIdentifierImpl> [27-30]
  ┃  ┃  ┗━ 'Foo' [27-30]
  ┃  ┣━ <FormalParameterListImpl> [30-37]
  ┃  ┃  ┣━ '(' [30-31]
  ┃  ┃  ┣━ <SimpleFormalParameterImpl> [31-36]
  ┃  ┃  ┃  ┣━ <NamedTypeImpl> [31-34]
  ┃  ┃  ┃  ┃  ┗━ 'int' [31-34]
  ┃  ┃  ┃  ┗━ 'j' [35-36]
  ┃  ┃  ┗━ ')' [36-37]
  ┃  ┣━ ':' [38-39]
  ┃  ┣━ <ConstructorFieldInitializerImpl> [40-51]
  ┃  ┃  ┣━ <SimpleIdentifierImpl> [40-41]
  ┃  ┃  ┃  ┗━ 'i' [40-41]
  ┃  ┃  ┣━ '=' [42-43]
  ┃  ┃  ┗━ <ThrowExpressionImpl> [44-51]
  ┃  ┃    ┣━ 'throw' [44-49]
  ┃  ┃    ┗━ <IntegerLiteralImpl> [50-51]
  ┃  ┃      ┗━ '0' [50-51]
  ┃  ┗━ <EmptyFunctionBodyImpl> [51-52]
  ┃    ┗━ ';' [51-52]
  ┗━ '}' [53-54]
--------------------------------------------------------------------------------
 === ANTLR ===
Errors of type 1: [[@16,44:48='throw',<78>,3:19] Bad state: , [@16,44:48='throw',<78>,3:19] Bad state: , [@13,38:38=':',<12>,3:13] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: ]
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
  ┣━ <metadata>
  ┣━ <topLevelDefinition>
  ┃  ┗━ <classDeclaration>
  ┃    ┣━ <classModifiers>
  ┃    ┣━ 'class'
  ┃    ┣━ <typeWithParameters>
  ┃    ┃  ┗━ <typeIdentifier>
  ┃    ┃    ┗━ 'Foo'
  ┃    ┣━ '{'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ <declaration>
  ┃    ┃  ┃  ┣━ <varOrType>
  ┃    ┃  ┃  ┃  ┗━ <type>
  ┃    ┃  ┃  ┃    ┗━ <typeNotFunction>
  ┃    ┃  ┃  ┃      ┗━ <typeNotVoidNotFunction>
  ┃    ┃  ┃  ┃        ┗━ <typeName>
  ┃    ┃  ┃  ┃          ┗━ <typeIdentifier>
  ┃    ┃  ┃  ┃            ┗━ 'int'
  ┃    ┃  ┃  ┗━ <initializedIdentifierList>
  ┃    ┃  ┃    ┗━ <initializedIdentifier>
  ┃    ┃  ┃      ┣━ <identifier>
  ┃    ┃  ┃      ┃  ┗━ 'i'
  ┃    ┃  ┃      ┣━ '='
  ┃    ┃  ┃      ┗━ <expression>
  ┃    ┃  ┃        ┗━ <conditionalExpression>
  ┃    ┃  ┃          ┗━ <ifNullExpression>
  ┃    ┃  ┃            ┗━ <logicalOrExpression>
  ┃    ┃  ┃              ┗━ <logicalAndExpression>
  ┃    ┃  ┃                ┗━ <equalityExpression>
  ┃    ┃  ┃                  ┗━ <relationalExpression>
  ┃    ┃  ┃                    ┗━ <bitwiseOrExpression>
  ┃    ┃  ┃                      ┗━ <bitwiseXorExpression>
  ┃    ┃  ┃                        ┗━ <bitwiseAndExpression>
  ┃    ┃  ┃                          ┗━ <shiftExpression>
  ┃    ┃  ┃                            ┗━ <additiveExpression>
  ┃    ┃  ┃                              ┗━ <multiplicativeExpression>
  ┃    ┃  ┃                                ┗━ <unaryExpression>
  ┃    ┃  ┃                                  ┗━ <postfixExpression>
  ┃    ┃  ┃                                    ┗━ <primary>
  ┃    ┃  ┃                                      ┗━ <literal>
  ┃    ┃  ┃                                        ┗━ <numericLiteral>
  ┃    ┃  ┃                                          ┗━ '0'
  ┃    ┃  ┗━ ';'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┗━ 'Foo'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┗━ '('
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┗━ 'int'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ 'j'
  ┃    ┃  ┣━ ')'
  ┃    ┃  ┗━ ':'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ 'i'
  ┃    ┃  ┣━ '='
  ┃    ┃  ┣━ 'throw'
  ┃    ┃  ┣━ '0'
  ┃    ┃  ┗━ ';'
  ┃    ┗━ '}'
  ┗━ '<EOF>'

Assignment expressions are also supported by the implementation (it even supports cascades), but not by the spec:

class Foo {
  int i = 0;
  Foo(int j) : i = j *= 0;
}
 === Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-54]
┗━ <ClassDeclarationImpl> [0-53]
  ┣━ 'class' [0-5]
  ┣━ 'Foo' [6-9]
  ┣━ '{' [10-11]
  ┣━ <FieldDeclarationImpl> [14-24]
  ┃  ┣━ <VariableDeclarationListImpl> [14-23]
  ┃  ┃  ┣━ <NamedTypeImpl> [14-17]
  ┃  ┃  ┃  ┗━ 'int' [14-17]
  ┃  ┃  ┗━ <VariableDeclarationImpl> [18-23]
  ┃  ┃    ┣━ 'i' [18-19]
  ┃  ┃    ┣━ '=' [20-21]
  ┃  ┃    ┗━ <IntegerLiteralImpl> [22-23]
  ┃  ┃      ┗━ '0' [22-23]
  ┃  ┗━ ';' [23-24]
  ┣━ <ConstructorDeclarationImpl> [27-51]
  ┃  ┣━ <SimpleIdentifierImpl> [27-30]
  ┃  ┃  ┗━ 'Foo' [27-30]
  ┃  ┣━ <FormalParameterListImpl> [30-37]
  ┃  ┃  ┣━ '(' [30-31]
  ┃  ┃  ┣━ <SimpleFormalParameterImpl> [31-36]
  ┃  ┃  ┃  ┣━ <NamedTypeImpl> [31-34]
  ┃  ┃  ┃  ┃  ┗━ 'int' [31-34]
  ┃  ┃  ┃  ┗━ 'j' [35-36]
  ┃  ┃  ┗━ ')' [36-37]
  ┃  ┣━ ':' [38-39]
  ┃  ┣━ <ConstructorFieldInitializerImpl> [40-50]
  ┃  ┃  ┣━ <SimpleIdentifierImpl> [40-41]
  ┃  ┃  ┃  ┗━ 'i' [40-41]
  ┃  ┃  ┣━ '=' [42-43]
  ┃  ┃  ┗━ <AssignmentExpressionImpl> [44-50]
  ┃  ┃    ┣━ <SimpleIdentifierImpl> [44-45]
  ┃  ┃    ┃  ┗━ 'j' [44-45]
  ┃  ┃    ┣━ '*=' [46-48]
  ┃  ┃    ┗━ <IntegerLiteralImpl> [49-50]
  ┃  ┃      ┗━ '0' [49-50]
  ┃  ┗━ <EmptyFunctionBodyImpl> [50-51]
  ┃    ┗━ ';' [50-51]
  ┗━ '}' [52-53]
--------------------------------------------------------------------------------
 === ANTLR ===
Errors of type 1: [[@17,46:47='*=',<22>,3:21] Bad state: , [@17,46:47='*=',<22>,3:21] Bad state: , [@13,38:38=':',<12>,3:13] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: , [@17,46:47='*=',<22>,3:21] Bad state: , [@17,46:47='*=',<22>,3:21] Bad state: ]
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
  ┣━ <metadata>
  ┣━ <topLevelDefinition>
  ┃  ┗━ <classDeclaration>
  ┃    ┣━ <classModifiers>
  ┃    ┣━ 'class'
  ┃    ┣━ <typeWithParameters>
  ┃    ┃  ┗━ <typeIdentifier>
  ┃    ┃    ┗━ 'Foo'
  ┃    ┣━ '{'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ <declaration>
  ┃    ┃  ┃  ┣━ <varOrType>
  ┃    ┃  ┃  ┃  ┗━ <type>
  ┃    ┃  ┃  ┃    ┗━ <typeNotFunction>
  ┃    ┃  ┃  ┃      ┗━ <typeNotVoidNotFunction>
  ┃    ┃  ┃  ┃        ┗━ <typeName>
  ┃    ┃  ┃  ┃          ┗━ <typeIdentifier>
  ┃    ┃  ┃  ┃            ┗━ 'int'
  ┃    ┃  ┃  ┗━ <initializedIdentifierList>
  ┃    ┃  ┃    ┗━ <initializedIdentifier>
  ┃    ┃  ┃      ┣━ <identifier>
  ┃    ┃  ┃      ┃  ┗━ 'i'
  ┃    ┃  ┃      ┣━ '='
  ┃    ┃  ┃      ┗━ <expression>
  ┃    ┃  ┃        ┗━ <conditionalExpression>
  ┃    ┃  ┃          ┗━ <ifNullExpression>
  ┃    ┃  ┃            ┗━ <logicalOrExpression>
  ┃    ┃  ┃              ┗━ <logicalAndExpression>
  ┃    ┃  ┃                ┗━ <equalityExpression>
  ┃    ┃  ┃                  ┗━ <relationalExpression>
  ┃    ┃  ┃                    ┗━ <bitwiseOrExpression>
  ┃    ┃  ┃                      ┗━ <bitwiseXorExpression>
  ┃    ┃  ┃                        ┗━ <bitwiseAndExpression>
  ┃    ┃  ┃                          ┗━ <shiftExpression>
  ┃    ┃  ┃                            ┗━ <additiveExpression>
  ┃    ┃  ┃                              ┗━ <multiplicativeExpression>
  ┃    ┃  ┃                                ┗━ <unaryExpression>
  ┃    ┃  ┃                                  ┗━ <postfixExpression>
  ┃    ┃  ┃                                    ┗━ <primary>
  ┃    ┃  ┃                                      ┗━ <literal>
  ┃    ┃  ┃                                        ┗━ <numericLiteral>
  ┃    ┃  ┃                                          ┗━ '0'
  ┃    ┃  ┗━ ';'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┗━ 'Foo'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┗━ '('
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┗━ 'int'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ 'j'
  ┃    ┃  ┣━ ')'
  ┃    ┃  ┗━ ':'
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ 'i'
  ┃    ┃  ┗━ '='
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┣━ <metadata>
  ┃    ┣━ <classMemberDeclaration>
  ┃    ┃  ┣━ 'j'
  ┃    ┃  ┣━ '*='
  ┃    ┃  ┣━ '0'
  ┃    ┃  ┗━ ';'
  ┃    ┗━ '}'
  ┗━ '<EOF>'


The spec also supports some expressions that the implementation does not support, see #11509 for that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions