Skip to content

Commit

Permalink
Fixes dart-lang#2490. Add more await tests for extension types (dart-…
Browse files Browse the repository at this point in the history
…lang#2500)

Add more await tests for extension types.
  • Loading branch information
sgrekhov authored Jan 29, 2024
1 parent 6e2b5ec commit a38a448
Show file tree
Hide file tree
Showing 11 changed files with 435 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
// 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 It is a compile-time error if await e occurs, and the static type
/// of e is an extension type which is not a subtype of Future<T> for any T.
/// @assertion We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is a compile-time error if `await e` occurs, and
/// the static type of `e` is an extension type which is not a subtype of
Expand All @@ -12,40 +20,40 @@
// SharedOptions=--enable-experiment=inline-class

extension type V1(int id) {}
extension type V1(int _) {}

extension type V2<T>(T id) {}
extension type V2<T>(T _) {}

extension type V3<T extends num>(T id) {}
extension type V3<T extends num>(T _) {}

main() async {
V1 v1 = V1(42);
await v1;
// ^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V2<String> v2_1 = V2("42");
await v2_1;
// ^^^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V2 v2_2 = V2("42");
await v2_2;
// ^^^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V3<int> v3_1 = V3(42);
await v3_1;
// ^^^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V3 v3_2 = V3(42);
await v3_2;
// ^^^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
// 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 It is a compile-time error if await e occurs, and the static type
/// of e is an extension type which is not a subtype of Future<T> for any T.
/// @assertion We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is a compile-time error if `await e` occurs, and
/// the static type of `e` is an extension type which is not a subtype of
Expand All @@ -12,30 +20,30 @@
// SharedOptions=--enable-experiment=inline-class

extension type V0(Future<int> id) {}
extension type V0(Future<int> _) {}

extension type V1(Future<int> id) {}
extension type V1(Future<int> _) {}

extension type V2<T extends Future<Object>>(T id) {}
extension type V2<T extends Future<Object>>(T _) {}

extension type V3(Future<int> id) implements V0 {}
extension type V3(Future<int> _) implements V0 {}

main() async {
V1 v1 = V1(Future<int>.value(42));
await v1;
// ^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V2<Future<String>> v2 = V2(Future<String>.value("42"));
await v2;
// ^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V3 v3 = V3(Future<int>.value(42));
await v3;
// ^^
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
// 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 It is a compile-time error if await e occurs, and the static type
/// of e is an extension type which is not a subtype of Future<T> for any T.
/// @assertion We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is not an error if `await e` occurs and the
/// static type of `e` is an extension type which is a subtype of `Future<T>`
Expand All @@ -14,9 +22,9 @@

import "../../Utils/expect.dart";

extension type V1(Future<int> id) implements Future<int> {}
extension type V1(Future<int> _) implements Future<int> {}

extension type V2<T extends Future<Object>>(T id) implements Future<Object>{}
extension type V2<T extends Future<Object>>(T _) implements Future<Object>{}

main() async {
V1 v1 = V1(Future<int>.value(42));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// 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 We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is a compile-time error if `await e` occurs, and
/// the static type of `e` is `S?`, and `S` is incompatible with await.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import 'dart:async';

extension type V1(int _) {}

extension type V2<T>(T _) {}

extension type V3<T extends num>(T _) {}

extension type V4(Future<int> _) {}

extension type V5<T>(FutureOr<T> _) {}

extension type V6<T extends num>(Future<T>? _) {}

main() async {
V1? v1 = V1(42);
await v1;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V2<String>? v2_1 = null;
await v2_1;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V2? v2_2 = V2("42");
await v2_2;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V3<int>? v3_1 = V3(42);
await v3_1;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V3? v3_2 = null;
await v3_2;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V4? v4 = V4(Future<int>.value(42));
await v4;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V5<String>? v5_1 = null;
await v5_1;
//^^^^
// [analyzer] unspecified
// [cfe] unspecified

V5<String>? v5_2 = V5("42");
await v2_2;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V6<int>? v6_1 = V6(null);
await v6_1;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

V6? v6_2 = null;
await v6_2;
//^^^^^
// [analyzer] unspecified
// [cfe] unspecified

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2023, 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 We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is not an error if `await e` occurs and the
/// static type of `e` is `S?`, and `S` is compatible with await.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/expect.dart";

extension type V1(Future<int> _) implements Future<int> {}

extension type V2<T extends Future<Object>>(T _) implements Future<Object>{}

main() async {
V1? v1 = V1(Future<int>.value(42));
var _v1 = await v1;
Expect.equals(42, _v1);

V2<Future<String>>? v2 = V2(Future<String>.value("42"));
var _v2 = await v2;
Expect.equals("42", _v2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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 We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is a compile-time error if `await e` occurs, and
/// the static type of `e` is `X & B`, and `B` is incompatible with await.
/// @author sgrekhov22@gmail.com
/// @issue 54648, 54649
// SharedOptions=--enable-experiment=inline-class

import 'dart:async';

extension type NumET(num _) implements num {}
extension type IntET(int _) implements NumET {}

test1<X extends FutureOr<NumET>>(X x) async {
if (x is IntET) {
await x;
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
}

test2<X extends FutureOr<num>>(X x) async {
if (x is IntET) {
await x;
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
}

main() {
print(test1);
print(test2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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 We say that a type T is incompatible with await if at least one
/// of the following criteria holds:
/// - T is an extension type that does not implement Future.
/// - T is S?, and S is incompatible with await.
/// - T is X & B, and either:
/// - B is incompatible with await, or
/// - B does not derive a future type, and X is incompatible with await.
/// - T is a type variable with bound S, and S is incompatible with await.
/// Consider an expression of the form await e. A compile-time error occurs if
/// the static type of e is incompatible with await.
///
/// @description Checks that it is a compile-time error if `await e` occurs, and
/// the static type of `e` is `X & B` and `B` does not derive a future type, and
/// `X` is incompatible with await.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

extension type NumET(num _) implements num {}
extension type IntET(int _) implements NumET {}

test1<X extends NumET>(X x) async {
if (x is IntET) {
await x;
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
}

test2<X extends num>(X x) async {
if (x is int) {
await x; // No error here, int is compatible with await
}
if (x is IntET) {
await x;
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
}

main() {
print(test1);
print(test2);
}
Loading

0 comments on commit a38a448

Please sign in to comment.