dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.21k stars 1.57k forks source link

CFE doesn't allow 'super!' #40372

Open sgrekhov opened 4 years ago

sgrekhov commented 4 years ago

The following test fails on DDC

class A {
  String s = "Show must go on";
  foo() {}
  Object? get getValue => "Lily was here";
  int? operator [](int index) => index;
  void operator []=(int index, String val) {
    s = val;
  }
}

class C extends A {
  test() {
    super!;          //# 01: static type warning
    super!.foo();    //# 02: static type warning
    super![42];      //# 03: static type warning
    super!?.foo();   //# 04: static type warning
    super!?.[42];    //# 05: static type warning
    super!.s = "Lily was here";    //# 06: static type warning
    super!?.s = "Lily was here";   //# 07: static type warning
    super![0] = "Lily was here";   //# 08: static type warning
    super!?.[0] = "Lily was here"; //# 09: static type warning
    super.getValue!;
    super[42]!;
  }
}

main() {
  C c = new C();
  c.test();
}

An error is (https://dart-ci.appspot.com/log/ddc-nnbd-linux-release-chrome/dartdevk-strong-linux-release-chrome/1641/co19/LanguageFeatures/nnbd/null_check_operator_A04_t01/01)


stdout:
org-dartlang-app:/out/ReleaseX64NNBD/generated_tests/co19/LanguageFeatures/nnbd/null_check_operator_A04_t01_01.dart:31:5: Error: Can't use 'super' as an expression.
To delegate a constructor to a super constructor, put the super call as an initializer.
    super!;          //# 01: static type warning
    ^^^^^
lrhn commented 4 years ago

As I read the current language grammar in the spec, the sequence super! is not allowed at all.

So, it's correct to have a compile-time error, but the error message is misleading.

The keyword super is always followed by either an \, which cannot be !, or a binary operator, which also cannot be !.

\ ::= ...     \alt \SUPER{} \

\ ::= ...     \alt \SUPER{} \

\ ::= `[' \ `]'     \alt `.' \

\ ::= ...     \alt \SUPER{} \

\ ::= ...     \alt \SUPER{} \ \

... etc ...

The only exception tot hat is the \

\ ::= ...     \alt (\ | \) \SUPER{}

and a \ also cannot be immediately followed by a ! operator (or any suffix operator) because of precedence.

The \ ! can only follow a constructor invocation or a primary, and as shown above super by itself is not a primary, it has to be followed by an unconditional non-! selector to become a primary.