56f46b0659
This changes the CFE expectation test suites to use unsound null safety as default to avoid passing --enable-experiments=no-non-nullable to opt out old test folders. This change removes most test folders from the 'strong' tester, since this now only supports sound null safety, which requires all libraries to be opted in. Instead, the 'weak' tester now runs all test folders. Additionally the 'outline' tester is changed to use unsound null safety so that it call be used on all test folders. The 'fast_strong' tester is removed since it should just be run locally and it can be run by passing an option to the other testers. References to non-existing 'shaker' folder has been removed from testing.json. Change-Id: Ibcc306f7b27d06b9637c205238bc408194f1d062 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184787 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
244 lines
9.5 KiB
Dart
244 lines
9.5 KiB
Dart
// Copyright (c) 2019, 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.
|
|
// @dart=2.9
|
|
// Testing that i2b and checks for correct super-boundedness are applied
|
|
// to type arguments, taking the variance of type parameters into account.
|
|
|
|
// Standard type comparison support.
|
|
|
|
typedef F<X> = void Function<Y extends X>();
|
|
F<X> toF<X>(X x) => null;
|
|
|
|
// Material specific to this test.
|
|
|
|
typedef Fcov<X> = X Function();
|
|
typedef Fcon<X> = Function(X);
|
|
typedef Finv<X> = X Function(X);
|
|
|
|
class Acov<X extends Fcov<Y>, Y> {}
|
|
|
|
class Acon<X extends Fcon<Y>, Y> {}
|
|
|
|
class Ainv<X extends Finv<Y>, Y> {}
|
|
|
|
typedef FcovBound<X extends num> = X Function();
|
|
typedef FconBound<X extends num> = Function(X);
|
|
typedef FinvBound<X extends num> = X Function(X);
|
|
|
|
class AcovBound<X extends FcovBound<Y>, Y extends num> {}
|
|
|
|
class AconBound<X extends FconBound<Y>, Y extends num> {}
|
|
|
|
class AinvBound<X extends FinvBound<Y>, Y extends num> {}
|
|
|
|
class A<X> {}
|
|
|
|
typedef FcovCyclicBound<X extends A<X>> = X Function();
|
|
typedef FconCyclicBound<X extends A<X>> = Function(X);
|
|
typedef FinvCyclicBound<X extends A<X>> = X Function(X);
|
|
|
|
class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
|
|
|
|
class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
|
|
|
|
class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
|
|
|
|
typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
|
|
typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
|
|
typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
|
|
|
|
class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
|
|
}
|
|
|
|
class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
|
|
}
|
|
|
|
class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
|
|
}
|
|
|
|
class B<X> {}
|
|
|
|
void testTypeAliasAsTypeArgument() {
|
|
// I2b: Use bounds (Fcov<Y>, dynamic), then replace covariant occurrence
|
|
// (of `Y` in `Acov<Fcov<Y>, _>`) by `Y`s value `dynamic`. Resulting type
|
|
// `Acov<Fcov<dynamic>, dynamic>` is regular-bounded.
|
|
Acov source1;
|
|
var fsource1 = toF(source1);
|
|
F<Acov<Fcov<dynamic>, dynamic>> target1 = fsource1;
|
|
|
|
// I2b: Use bounds (Fcon<Y>, dynamic), then replace contravariant occurrence
|
|
// (of `Y` in `Acon<Fcon<Y>, _>`) by `Null`. Resulting type
|
|
// is super-bounded: Acon<Fcon<Object>, Null> is regular-bounded.
|
|
Acon source2;
|
|
var fsource2 = toF(source2);
|
|
F<Acon<Fcon<Null>, dynamic>> target2 = fsource2;
|
|
|
|
// I2b: Use bounds (Finv<Y>, dynamic) then replace invariant occurrence
|
|
// (of `Y` in `Ainv<Finv<Y>, _>`) by `Y`s value `dynamic`. Resulting type
|
|
// `Ainv<Finv<dynamic>, dynamic>` is regular-bounded.
|
|
Ainv source3;
|
|
var fsource3 = toF(source3);
|
|
F<Ainv<Finv<dynamic>, dynamic>> target3 = fsource3;
|
|
|
|
// I2b: Use bounds (FcovBound<Y>, num), then replace covariant occurrence
|
|
// (of `Y` in `AcovBound<FcovBound<Y>, _>`) by `Y`s value `num`.
|
|
// Resulting type `AcovBound<FcovBound<num>, num>` is regular-bounded.
|
|
AcovBound source4;
|
|
var fsource4 = toF(source4);
|
|
F<AcovBound<FcovBound<num>, num>> target4 = fsource4;
|
|
|
|
// I2b: Use bounds (FconBound<Y>, num), then replace contravariant occurrence
|
|
// of `Y` in `AconBound<FconBound<Y>, _>` by `Null`. Resulting type is
|
|
// super-bounded: AconBound<FconBound<Object>, num> is regular-bounded.
|
|
AconBound source5;
|
|
var fsource5 = toF(source5);
|
|
F<AconBound<FconBound<Null>, num>> target5 = fsource5;
|
|
|
|
// I2b: Use bounds (FinvBound<Y>, num), then replace invariant occurrence
|
|
// of `Y` in `AinvBound<FinvBound<Y>, _>` by `Y`s value `num`. Resulting
|
|
// type `AinvBound<FinvBound<num>, num>` is regular-bounded.
|
|
AinvBound source6;
|
|
var fsource6 = toF(source6);
|
|
F<AinvBound<FinvBound<num>, num>> target6 = fsource6;
|
|
|
|
// I2b: Use bounds (FcovCyclicBound<Y>, A<Y>), then break cycle {Y} by
|
|
// replacing covariant occurrence of `Y` in `AcovCyclicBound<_, A<Y>>`
|
|
// by `dynamic`; then replace covariant occurrence of `Y` in
|
|
// `AcovCyclicBound<FcovCyclicBound<Y>, _>` by `Y`s value `A<dynamic>`.
|
|
// Resulting type `AcovCyclicBound<FcovCyclicBound<A<dynamic>>, A<dynamic>>>`
|
|
// is regular-bounded.
|
|
AcovCyclicBound source7;
|
|
var fsource7 = toF(source7);
|
|
F<AcovCyclicBound<FcovCyclicBound<A<dynamic>>, A<dynamic>>> target7 =
|
|
fsource7;
|
|
|
|
// I2b: Use bounds (FconCyclicBound<Y>, A<Y>), then break cycle {Y} by
|
|
// replacing covariant occurrence of `Y` in `AconCyclicBound<_, A<Y>>`
|
|
// by `dynamic`; then replace contravariant occurrence of `Y` in
|
|
// `AconCyclicBound<FconCyclicBound<Y>, _>` by `Null`.
|
|
// Resulting type `AconCyclicBound<FconCyclicBound<Null>, A<dynamic>>>` is
|
|
// super-bounded because `AconCyclicBound<FconCyclicBound<Object>, A<Null>>>`
|
|
// is regular-bounded.
|
|
AconCyclicBound source8;
|
|
var fsource8 = toF(source8);
|
|
F<AconCyclicBound<FconCyclicBound<Null>, A<dynamic>>> target8 = fsource8;
|
|
|
|
// I2b: Use bounds (FinvCyclicBound<Y>, A<Y>), then break cycle {Y} by
|
|
// replacing covariant occurrence of `Y` in `AinvCyclicBound<_, A<Y>>`
|
|
// by `dynamic`; then replace invariant occurrence of `Y` in
|
|
// `AinvCyclicBound<FinvCyclicBound<Y>, _>` by `Y`s value `A<dynamic>`.
|
|
// Resulting type `AinvCyclicBound<FinvCyclicBound<A<dynamic>>, A<dynamic>>>`
|
|
// looks regular-bounded, but contains `FinvCyclicBound<A<dynamic>>` which
|
|
// is not well-bounded.
|
|
AinvCyclicBound source9; //# 01: compile-time error
|
|
// var fsource9 = toF(source9);
|
|
// F<AinvCyclicBound<FinvCyclicBound<A<dynamic>>, A<dynamic>>> target9 =
|
|
// fsource9;
|
|
|
|
// I2b: Use bounds (FcovCyclicCoBound<Y>, Function(Y)), then break cycle {Y}
|
|
// by replacing contravariant occurrence of `Y` in
|
|
// `AcovCyclicCoBound<_, Function(Y)>` by `Null`; then replace covariant
|
|
// occurrence of `Y` in `AcovCyclicCoBound<FcovCyclicCoBound<Y>, _>` by `Y`s
|
|
// value `Function(Null)`. Resulting type
|
|
// `AcovCyclicCoBound<FcovCyclicCoBound<Function(Null)>, Function(Null)>`
|
|
// is regular-bounded, with subterm `FcovCyclicCoBound<Function(Null)>` which
|
|
// is super-bounded because `FcovCyclicCoBound<Function(Object)>` is
|
|
// regular-bounded.
|
|
AcovCyclicCoBound source10;
|
|
var fsource10 = toF(source10);
|
|
F<AcovCyclicCoBound<FcovCyclicCoBound<Function(Null)>, Function(Null)>>
|
|
target10 = fsource10;
|
|
|
|
// I2b: Use bounds (FconCyclicCoBound<Y>, Function(Y)), then break cycle {Y}
|
|
// by replacing contravariant occurrence of `Y` in
|
|
// `AconCyclicCoBound<_, Function(Y)>` by `Null`; then replace contravariant
|
|
// occurrence of `Y` in `AconCyclicCoBound<FconCyclicCoBound<Y>, _>` by
|
|
// `Null`. Resulting type
|
|
// `AconCyclicCoBound<FconCyclicCoBound<Null>, Function(Null)>` is
|
|
// super-bounded because
|
|
// `AconCyclicCoBound<FconCyclicCoBound<Object>, Function(Object)>` is
|
|
// regular-bounded.
|
|
AconCyclicCoBound source11;
|
|
var fsource11 = toF(source11);
|
|
F<AconCyclicCoBound<FconCyclicCoBound<Null>, Function(Null)>> target11 =
|
|
fsource11;
|
|
|
|
// I2b: Use bounds (FinvCyclicCoBound<Y>, Function(Y)), then break cycle {Y}
|
|
// by replacing contravariant occurrence of `Y` in
|
|
// `AinvCyclicCoBound<_, Function(Y)>` by `Null`; then replace invariant
|
|
// occurrence of `Y` in `AinvCyclicCoBound<FinvCyclicCoBound<Y>, _>` by `Y`s
|
|
// value `Function(Null)`.
|
|
// Resulting type
|
|
// `AinvCyclicCoBound<FinvCyclicCoBound<Function(Null)>, Function(Null)>>`
|
|
// looks regular-bounded, but contains `FinvCyclicCoBound<Function(Null)>`
|
|
// which is not well-bounded.
|
|
AinvCyclicCoBound source12; //# 02: compile-time error
|
|
// var fsource12 = toF(source12);
|
|
// F<AinvCyclicCoBound<FinvCyclicCoBound<Function(Null)>, Function(Null)>>
|
|
// target12 = fsource12;
|
|
}
|
|
|
|
void testNested() {
|
|
// Everything gets the same treatment when the cases from `testTopLevel`
|
|
// are duplicated at the nested level in a covariant position.
|
|
|
|
B<Acov> source1;
|
|
var fsource1 = toF(source1);
|
|
F<B<Acov<Fcov<dynamic>, dynamic>>> target1 = fsource1;
|
|
|
|
B<Acon> source2;
|
|
var fsource2 = toF(source2);
|
|
F<B<Acon<Fcon<Null>, dynamic>>> target2 = fsource2;
|
|
|
|
B<Ainv> source3;
|
|
var fsource3 = toF(source3);
|
|
F<B<Ainv<Finv<dynamic>, dynamic>>> target3 = fsource3;
|
|
|
|
B<AcovBound> source4;
|
|
var fsource4 = toF(source4);
|
|
F<B<AcovBound<FcovBound<num>, num>>> target4 = fsource4;
|
|
|
|
B<AconBound> source5;
|
|
var fsource5 = toF(source5);
|
|
F<B<AconBound<FconBound<Null>, num>>> target5 = fsource5;
|
|
|
|
B<AinvBound> source6;
|
|
var fsource6 = toF(source6);
|
|
F<B<AinvBound<FinvBound<num>, num>>> target6 = fsource6;
|
|
|
|
B<AcovCyclicBound> source7;
|
|
var fsource7 = toF(source7);
|
|
F<B<AcovCyclicBound<FcovCyclicBound<A<dynamic>>, A<dynamic>>>> target7 =
|
|
fsource7;
|
|
|
|
B<AconCyclicBound> source8;
|
|
var fsource8 = toF(source8);
|
|
F<B<AconCyclicBound<FconCyclicBound<Null>, A<dynamic>>>> target8 = fsource8;
|
|
|
|
B<AinvCyclicBound> source9; //# 03: compile-time error
|
|
// var fsource9 = toF(source9);
|
|
// F<B<AinvCyclicBound<FinvCyclicBound<A<dynamic>>, A<dynamic>>>> target9 =
|
|
// fsource9;
|
|
|
|
B<AcovCyclicCoBound> source10;
|
|
var fsource10 = toF(source10);
|
|
F<B<AcovCyclicCoBound<FcovCyclicCoBound<Function(Null)>, Function(Null)>>>
|
|
target10 = fsource10;
|
|
|
|
B<AconCyclicCoBound> source11;
|
|
var fsource11 = toF(source11);
|
|
F<B<AconCyclicCoBound<FconCyclicCoBound<Null>, Function(Null)>>> target11 =
|
|
fsource11;
|
|
|
|
B<AinvCyclicCoBound> source12; //# 04: compile-time error
|
|
// var fsource12 = toF(source12);
|
|
// F<B<AinvCyclicCoBound<FinvCyclicCoBound<Function(Null)>, Function(Null)>>>
|
|
// target12 = fsource12;
|
|
}
|
|
|
|
main() {
|
|
testTypeAliasAsTypeArgument();
|
|
testNested();
|
|
}
|