mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 17:59:39 +00:00
Update UP for FutureOr.
Bug: https://github.com/dart-lang/sdk/issues/43720 Change-Id: I9decd3a3b430f82e3e4bd0c4e6963cd3069f9adf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166786 Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
63e0cd6955
commit
694c8d0d6b
|
@ -677,6 +677,11 @@ class LeastUpperBoundHelper {
|
|||
return getLeastUpperBound(T1, _typeSystem.objectNone);
|
||||
}
|
||||
|
||||
var futureOrResult = _futureOr(T1, T2);
|
||||
if (futureOrResult != null) {
|
||||
return futureOrResult;
|
||||
}
|
||||
|
||||
// UP(T1, T2) = T2 if T1 <: T2
|
||||
// UP(T1, T2) = T1 if T2 <: T1
|
||||
// And other, more complex variants of interface types.
|
||||
|
@ -806,6 +811,56 @@ class LeastUpperBoundHelper {
|
|||
);
|
||||
}
|
||||
|
||||
DartType _futureOr(DartType T1, DartType T2) {
|
||||
var T1_futureOr = T1 is InterfaceType && T1.isDartAsyncFutureOr
|
||||
? T1.typeArguments[0]
|
||||
: null;
|
||||
|
||||
var T1_future = T1 is InterfaceType && T1.isDartAsyncFuture
|
||||
? T1.typeArguments[0]
|
||||
: null;
|
||||
|
||||
var T2_futureOr = T2 is InterfaceType && T2.isDartAsyncFutureOr
|
||||
? T2.typeArguments[0]
|
||||
: null;
|
||||
|
||||
var T2_future = T2 is InterfaceType && T2.isDartAsyncFuture
|
||||
? T2.typeArguments[0]
|
||||
: null;
|
||||
|
||||
// UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
if (T1_futureOr != null && T2_futureOr != null) {
|
||||
var T3 = getLeastUpperBound(T1_futureOr, T2_futureOr);
|
||||
return _typeSystem.typeProvider.futureOrType2(T3);
|
||||
}
|
||||
|
||||
// UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
if (T1_future != null && T2_futureOr != null) {
|
||||
var T3 = getLeastUpperBound(T1_future, T2_futureOr);
|
||||
return _typeSystem.typeProvider.futureOrType2(T3);
|
||||
}
|
||||
|
||||
// UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
if (T1_futureOr != null && T2_future != null) {
|
||||
var T3 = getLeastUpperBound(T1_futureOr, T2_future);
|
||||
return _typeSystem.typeProvider.futureOrType2(T3);
|
||||
}
|
||||
|
||||
// UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
if (T2_futureOr != null) {
|
||||
var T3 = getLeastUpperBound(T1, T2_futureOr);
|
||||
return _typeSystem.typeProvider.futureOrType2(T3);
|
||||
}
|
||||
|
||||
// UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
if (T1_futureOr != null) {
|
||||
var T3 = getLeastUpperBound(T1_futureOr, T2);
|
||||
return _typeSystem.typeProvider.futureOrType2(T3);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
DartType _parameterType(ParameterElement a, ParameterElement b) {
|
||||
return _typeSystem.getGreatestLowerBound(a.type, b.type);
|
||||
}
|
||||
|
|
|
@ -2608,6 +2608,50 @@ class UpperBoundTest extends _BoundsTestBase {
|
|||
);
|
||||
}
|
||||
|
||||
/// UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
/// UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
test_futureOr_future() {
|
||||
void check(DartType T1, DartType T2, DartType expected) {
|
||||
_checkLeastUpperBound(
|
||||
futureNone(T1),
|
||||
futureOrNone(T2),
|
||||
futureOrNone(expected),
|
||||
);
|
||||
}
|
||||
|
||||
check(intNone, doubleNone, numNone);
|
||||
check(intNone, stringNone, objectNone);
|
||||
}
|
||||
|
||||
/// UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
test_futureOr_futureOr() {
|
||||
void check(DartType T1, DartType T2, DartType expected) {
|
||||
_checkLeastUpperBound(
|
||||
futureOrNone(T1),
|
||||
futureOrNone(T2),
|
||||
futureOrNone(expected),
|
||||
);
|
||||
}
|
||||
|
||||
check(intNone, doubleNone, numNone);
|
||||
check(intNone, stringNone, objectNone);
|
||||
}
|
||||
|
||||
/// UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
/// UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
|
||||
test_futureOr_other() {
|
||||
void check(DartType T1, DartType T2, DartType expected) {
|
||||
_checkLeastUpperBound(
|
||||
futureOrNone(T1),
|
||||
T2,
|
||||
futureOrNone(expected),
|
||||
);
|
||||
}
|
||||
|
||||
check(intNone, doubleNone, numNone);
|
||||
check(intNone, stringNone, objectNone);
|
||||
}
|
||||
|
||||
test_identical() {
|
||||
void check(DartType type) {
|
||||
_checkLeastUpperBound(type, type, type);
|
||||
|
|
Loading…
Reference in a new issue