Skip to content

Commit

Permalink
Fixes #945: LanguageFeatures/Instantiate-to-bounds/class/static tests…
Browse files Browse the repository at this point in the history
… updated according to the recent changes.
  • Loading branch information
iarkh committed Oct 1, 2020
1 parent 8a9278c commit 5543ed8
Show file tree
Hide file tree
Showing 11 changed files with 532 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2018, 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 Instantiate to bound then computes an actual type argument list
* for [G] as follows:
*
* Let [Ui],[1] be [Si], for all [i] in [1 .. k]. (This is the "current value"
* of the bound for type variable [i], at step [1]; in general we will
* consider the current step, [m], and use data for that step, e.g., the bound
* [Ui],[m], to compute the data for step [m + 1]).
*
* Let [-->m] be a relation among the type variables [X1 .. Xk] such that
* [Xp -->m Xq] iff [Xq] occurs in [Up],[m] (so each type variable is related
* to, that is, depends on, every type variable in its bound, possibly
* including itself). Let [==>m] be the transitive closure of [-->m]. For each
* [m], let [Ui],[m+1], for [i] in [1 .. k], be determined by the following
* iterative process:
*
* 1. If there exists a [j] in [1 .. k] such that [Xj ==>m X0j] (that is, if
* the dependency graph has a cycle) let [M1 .. Mp] be the strongly connected
* components (SCCs) with respect to [-->m] (that is, the maximal subsets of
* [X1 .. Xk] where every pair of variables in each subset are related in both
* directions by [==>m]; note that the SCCs are pairwise disjoint; also, they
* are uniquely defined up to reordering, and the order does not matter). Let
* [M] be the union of [M1 .. Mp] (that is, all variables that participate in
* a dependency cycle). Let [i] be in [1 .. k]. If [Xi] does not belong to [M]
* then [Ui,m+1 = Ui,m]. Otherwise there exists a [q] such that [Xi] belongs
* to [Mq]; [Ui,m+1] is then obtained from [Ui,m] by replacing every covariant
* occurrence of a variable in [Mq] by [dynamic], and replacing every
* contravariant occurrence of a variable in [Mq] by [Null].
*
* 2. Otherwise, (if no dependency cycle exists) let [j] be the lowest number
* such that [Xj] occurs in [Up,m] for some [p] and [Xj -/->m Xq] for all [q]
* in [1..k] (that is, [Uj,m] is closed, that is, the current bound of [Xj]
* does not contain any type variables; but [Xj] is being depended on by the
* bound of some other type variable). Then, for all [i] in [1 .. k], [Ui,m+1]
* is obtained from [Ui,m] by replacing every covariant occurrence of [Xj] by
* [Uj,m], and replacing every contravariant occurrence of [Xj] by [Null].
*
* 3. Otherwise, (when no dependencies exist) terminate with the result
* [<U1,m ..., Uk,m>].
* @description Checks that instantiation to bounds works OK for the class with
* [typedef G<X> = X Function(X)] parameter (invariant case).
* @author iarkh@unipro.ru
*/
// SharedOptions=--enable-experiment=non-nullable

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

typedef G<X> = X Function(X);
class A<X extends G<A<X>>> {}

main() {
Expect.equals(
typeOf<A<G<A<dynamic>>>>(),
typeOf<A>()
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2018, 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 Instantiate to bound then computes an actual type argument list
* for [G] as follows:
*
* Let [Ui],[1] be [Si], for all [i] in [1 .. k]. (This is the "current value"
* of the bound for type variable [i], at step [1]; in general we will
* consider the current step, [m], and use data for that step, e.g., the bound
* [Ui],[m], to compute the data for step [m + 1]).
*
* Let [-->m] be a relation among the type variables [X1 .. Xk] such that
* [Xp -->m Xq] iff [Xq] occurs in [Up],[m] (so each type variable is related
* to, that is, depends on, every type variable in its bound, possibly
* including itself). Let [==>m] be the transitive closure of [-->m]. For each
* [m], let [Ui],[m+1], for [i] in [1 .. k], be determined by the following
* iterative process:
*
* 1. If there exists a [j] in [1 .. k] such that [Xj ==>m X0j] (that is, if
* the dependency graph has a cycle) let [M1 .. Mp] be the strongly connected
* components (SCCs) with respect to [-->m] (that is, the maximal subsets of
* [X1 .. Xk] where every pair of variables in each subset are related in both
* directions by [==>m]; note that the SCCs are pairwise disjoint; also, they
* are uniquely defined up to reordering, and the order does not matter). Let
* [M] be the union of [M1 .. Mp] (that is, all variables that participate in
* a dependency cycle). Let [i] be in [1 .. k]. If [Xi] does not belong to [M]
* then [Ui,m+1 = Ui,m]. Otherwise there exists a [q] such that [Xi] belongs
* to [Mq]; [Ui,m+1] is then obtained from [Ui,m] by replacing every covariant
* occurrence of a variable in [Mq] by [dynamic], and replacing every
* contravariant occurrence of a variable in [Mq] by [Null].
*
* 2. Otherwise, (if no dependency cycle exists) let [j] be the lowest number
* such that [Xj] occurs in [Up,m] for some [p] and [Xj -/->m Xq] for all [q]
* in [1..k] (that is, [Uj,m] is closed, that is, the current bound of [Xj]
* does not contain any type variables; but [Xj] is being depended on by the
* bound of some other type variable). Then, for all [i] in [1 .. k], [Ui,m+1]
* is obtained from [Ui,m] by replacing every covariant occurrence of [Xj] by
* [Uj,m], and replacing every contravariant occurrence of [Xj] by [Null].
*
* 3. Otherwise, (when no dependencies exist) terminate with the result
* [<U1,m ..., Uk,m>].
* @description Checks that instantiation to bounds works OK for [typedef G<X> =
* Function(X)], [class A<X extends G<A<X, Y>>, Y extends X>] (covariant)
* @author iarkh@unipro.ru
*/
// SharedOptions=--enable-experiment=non-nullable

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

typedef G<X> = X Function(X);
class A<X extends G<A<X, Y>>, Y extends X> {}

main() {
Expect.equals(
typeOf<A<G<A<dynamic, dynamic>>, dynamic>>(),
typeOf<A>()
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2018, 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 Instantiate to bound then computes an actual type argument list
* for [G] as follows:
*
* Let [Ui],[1] be [Si], for all [i] in [1 .. k]. (This is the "current value"
* of the bound for type variable [i], at step [1]; in general we will
* consider the current step, [m], and use data for that step, e.g., the bound
* [Ui],[m], to compute the data for step [m + 1]).
*
* Let [-->m] be a relation among the type variables [X1 .. Xk] such that
* [Xp -->m Xq] iff [Xq] occurs in [Up],[m] (so each type variable is related
* to, that is, depends on, every type variable in its bound, possibly
* including itself). Let [==>m] be the transitive closure of [-->m]. For each
* [m], let [Ui],[m+1], for [i] in [1 .. k], be determined by the following
* iterative process:
*
* 1. If there exists a [j] in [1 .. k] such that [Xj ==>m X0j] (that is, if
* the dependency graph has a cycle) let [M1 .. Mp] be the strongly connected
* components (SCCs) with respect to [-->m] (that is, the maximal subsets of
* [X1 .. Xk] where every pair of variables in each subset are related in both
* directions by [==>m]; note that the SCCs are pairwise disjoint; also, they
* are uniquely defined up to reordering, and the order does not matter). Let
* [M] be the union of [M1 .. Mp] (that is, all variables that participate in
* a dependency cycle). Let [i] be in [1 .. k]. If [Xi] does not belong to [M]
* then [Ui,m+1 = Ui,m]. Otherwise there exists a [q] such that [Xi] belongs
* to [Mq]; [Ui,m+1] is then obtained from [Ui,m] by replacing every covariant
* occurrence of a variable in [Mq] by [dynamic], and replacing every
* contravariant occurrence of a variable in [Mq] by [Null].
*
* 2. Otherwise, (if no dependency cycle exists) let [j] be the lowest number
* such that [Xj] occurs in [Up,m] for some [p] and [Xj -/->m Xq] for all [q]
* in [1..k] (that is, [Uj,m] is closed, that is, the current bound of [Xj]
* does not contain any type variables; but [Xj] is being depended on by the
* bound of some other type variable). Then, for all [i] in [1 .. k], [Ui,m+1]
* is obtained from [Ui,m] by replacing every covariant occurrence of [Xj] by
* [Uj,m], and replacing every contravariant occurrence of [Xj] by [Null].
*
* 3. Otherwise, (when no dependencies exist) terminate with the result
* [<U1,m ..., Uk,m>].
* @description Checks that instantiation to bounds works OK for [typedef G<X> =
* X Function(X)], [class A<X extends G<A<X, Y>>, Y extends X>] (invariant)
* @author iarkh@unipro.ru
*/
// SharedOptions=--enable-experiment=non-nullable

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

typedef G<X> = X Function(X);
class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}

main() {
Expect.equals(
typeOf<A<G<A<dynamic, dynamic>>,G<A<dynamic, dynamic>>>>(),
typeOf<A>()
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,24 @@ import "dart:async";

class A<X extends FutureOr<A<X>?>> {}

main() {
A? source;
void test(A source) {
var fsource = toF(source);
F<A<FutureOr<A<dynamic>?>>?>? target = fsource;
F<A<FutureOr<A<dynamic>?>>> target = fsource;

F<A<FutureOr<A<dynamic>?>?>?>? target0 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
F<A<FutureOr<A<dynamic>?>?>> target0 = fsource;

F<A<dynamic>?>? target1 = fsource;
// ^^^^^^^
F<A<dynamic>> target1 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<FutureOr<dynamic>?>?>? target2 = fsource;
// ^^^^^^^
F<A<FutureOr<dynamic>?>> target2 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<FutureOr<A<FutureOr<A<dynamic>?>>?>>?>? target3 = fsource;
// ^^^^^^^
F<A<FutureOr<A<FutureOr<A<dynamic>?>>?>>> target3 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

Expand All @@ -84,3 +80,5 @@ main() {
// [analyzer] unspecified
// [cfe] unspecified
}

main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -54,48 +54,67 @@ import "../../../../Utils/expect.dart";
typedef G<X> = Function(X);
class A<X extends G<A<X>>> {}

main() {
A? source;
test(A source) {
var fsource = toF(source);
F<A<G<A<Never>>>?>? target = fsource;
F<A<G<A<Never>>>> target = fsource;

F<A<dynamic>?>? target1 = fsource;
// ^^^^^^^
F<A<dynamic>> target1 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<dynamic>>?>? target2 = fsource;
// ^^^^^^^
F<A<G<dynamic>>> target2 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<A<G<dynamic>>>>?>? target3 = fsource;
// ^^^^^^^
F<A<G<A<G<dynamic>>>>> target3 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<A<G<A<dynamic>>>>>?>? target4 = fsource;
// ^^^^^^^
F<A<G<A<G<A<dynamic>>>>>> target4 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<Never>?>? target5 = fsource;
// ^^^^^^^
F<A<Never>> target5 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<Never>>?>? target6 = fsource;
// ^^^^^^^
F<A<G<Never>>> target6 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<A<G<Never>>>>?>? target7 = fsource;
// ^^^^^^^
F<A<G<A<G<Never>>>>> target7 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<A<G<A<Never>>>>>?>? target8 = fsource;
// ^^^^^^^
F<A<G<A<G<A<Never>>>>>> target8 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<Null>> target9 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<Null>>> target10 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<A<G<Null>>>>> target11 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

F<A<G<A<G<A<Null>>>>>> target12 = fsource;
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

Expand All @@ -104,3 +123,5 @@ main() {
// [analyzer] unspecified
// [cfe] unspecified
}

main() {}
Loading

0 comments on commit 5543ed8

Please sign in to comment.