diff --git a/LanguageFeatures/Extension-types/exhaustiveness_flow_analysis_A01_t01.dart b/LanguageFeatures/Extension-types/exhaustiveness_flow_analysis_A01_t01.dart new file mode 100644 index 0000000000..fc3386f778 --- /dev/null +++ b/LanguageFeatures/Extension-types/exhaustiveness_flow_analysis_A01_t01.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// @assertion Extension type erasure is not used during flow analysis +/// +/// @description Check that an extension type erasure is not used during flow +/// analysis that isn't concerned with run-time type tests +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=inline-class + +extension type const ET1(int value) { + void confirmET1() {} +} +extension type const ET2(int value) implements int { + void confirmET2() {} +} + +void main() { + int i = 42; + switch (i) { + case ET1 v: + v.confirmET1(); // This confirms that `ET1` is not erased to int + } + switch (i) { + case ET2 v: + v.confirmET2(); + } +} diff --git a/LanguageFeatures/Extension-types/exhaustiveness_variable_A04_t01.dart b/LanguageFeatures/Extension-types/exhaustiveness_variable_A04_t01.dart new file mode 100644 index 0000000000..94fcd6a7b4 --- /dev/null +++ b/LanguageFeatures/Extension-types/exhaustiveness_variable_A04_t01.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// @assertion Exhaustiveness of a variable pattern is determined by the static +/// type of the corresponding variable. +/// +/// @description Check static type of a variable pattern +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=inline-class + +import '../../Utils/static_type_helper.dart'; + +extension type ET(int i) {} +extension type TO(int i) implements ET {} + +main() { + ET x = ET(1); + switch (x) { + case int y: + x.expectStaticType>; + y.expectStaticType>; + case TO z: // Unreachable, it's Ok + x.expectStaticType>; + z.expectStaticType>; + } + switch (42) { + case ET y: + x.expectStaticType>; + y.expectStaticType>; + case TO z: // Unreachable, it's Ok + x.expectStaticType>; + z.expectStaticType>; + } +} diff --git a/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_lib.dart b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_lib.dart index 3076434bb7..e4e1c0d19f 100644 --- a/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_lib.dart +++ b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_lib.dart @@ -46,3 +46,7 @@ class LastPersonOnEarth implements Jack, Queen, King { LastPersonOnEarth(this.suit, {this.oneEyed = false}); } + +sealed class SClass {} +class B1Class extends SClass {} +class B2Class extends SClass {} diff --git a/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A02_t02.dart b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A02_t02.dart index 6b108ee3df..3b06a2e5a6 100644 --- a/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A02_t02.dart +++ b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A02_t02.dart @@ -6,7 +6,7 @@ /// matched type are always exhaustive /// /// @description Check that it is a compile-time error if the matched value type -/// of a switch expression or stetement is a sealed class and the set of cases +/// of a switch expression or statement is a sealed class and the set of cases /// is not exhaustive /// @author sgrekhov22@gmail.com diff --git a/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A03_t01.dart b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A03_t01.dart new file mode 100644 index 0000000000..57370f69c4 --- /dev/null +++ b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A03_t01.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// @assertion Switch statements and expressions with a sealed class as a +/// matched type are always exhaustive +/// +/// @description Check that the flow analysis considers a case reachable even in +/// the case where it accepts only objects of an unrelated type. +/// @author sgrekhov22@gmail.com + +class A {} + +class B {} + +void main() { + int x; + A a = A(); + switch (a) { + case B(): + print( + '''x is not assigned here. This case looks impossible, but there can + be a hidden subtype of A and B in some other library'''); + case _: + x = 1; + } + print(x); +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A03_t02.dart b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A03_t02.dart new file mode 100644 index 0000000000..0fe59d3411 --- /dev/null +++ b/LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A03_t02.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// @assertion Switch statements and expressions with a sealed class as a +/// matched type are always exhaustive +/// +/// @description Check that the flow analysis considers a case reachable even in +/// the case where it accepts only objects of an unrelated type. +/// @author sgrekhov22@gmail.com + +import 'exhaustiveness_lib.dart'; + +class C {} +class D extends C implements B1Class {} + +void main() { + int x; + SClass s = D(); + switch (s) { + case C(): + print('x is not assigned here'); + case B1Class(): + x = 1; + case B2Class(): + x = 2; + } + print(x); +// ^ +// [analyzer] unspecified +// [cfe] unspecified +}