Chromium Code Reviews| Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
| diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
| index 4d402db12c117e7ed6b633ca64e7a420543b7322..cd2f017288d2a70ea5e880c83b02a5dc6bc02672 100644 |
| --- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
| +++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
| @@ -649,7 +649,11 @@ isFunctionSubtype(ft1, ft2, covariant) => JS( |
| if (ret2 === $_void) return true; |
| // Dart allows void functions to subtype dynamic functions, but not |
| // other functions. |
| - if (ret1 === $_void) return (ret2 === $dynamic); |
| + // TODO(jmesserly): this check does not match our compile time subtype |
| + // implementation. Reconcile. |
| + if (ret1 === $_void) { |
| + return ret2 === $dynamic || ret2 === $FutureOr; |
| + } |
| if (!$_isSubtype(ret1, ret2, $covariant)) return null; |
| return true; |
| })()'''); |
| @@ -685,7 +689,12 @@ final isSubtype = JS( |
| _isBottom(type) => JS('bool', '# == #', type, bottom); |
| -_isTop(type) => JS('bool', '# == # || # == #', type, Object, type, dynamic); |
| +_isTop(type) { |
| + if (JS('bool', '# === #', getGenericClass(type), getGenericClass(FutureOr))) { |
| + return _isTop(JS('', '#[0]', getGenericArgs(type))); |
| + } |
| + return JS('bool', '# == # || # == #', type, Object, type, dynamic); |
| +} |
| _isSubtype(t1, t2, covariant) => JS( |
| '', |
| @@ -773,6 +782,22 @@ isClassSubType(t1, t2, covariant) => JS( |
| return true; |
| } |
| + // Handle FutureOr<T>. |
| + // It's not really a class type, but it's convenient to handle here. |
| + if (raw1 === ${getGenericClass(FutureOr)}) { |
| + // given t1 is Future<A> | A, then: |
| + // (Future<A> | A) <: t2 iff t2 <: Future<A> and t2 <: A. |
|
Leaf
2017/01/24 21:56:27
should be Future<A> <: t2 and A <: t2
Jennifer Messerly
2017/01/25 00:33:36
thank you. I managed to copy+paste this mistake in
|
| + let t1TypeArg = $getGenericArgs($t1)[0]; |
| + let t1Future = ${getGenericClass(Future)}(t1TypeArg); |
| + return $isSubtype(t1Future, $t2) && $isSubtype(t1TypeArg, $t2); |
| + } else if (raw2 === ${getGenericClass(FutureOr)}) { |
| + // given t2 is Future<A> | A, then: |
| + // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A |
| + let t2TypeArg = $getGenericArgs($t2)[0]; |
| + let t2Future = ${getGenericClass(Future)}(t2TypeArg); |
| + return $isSubtype($t1, t2Future) || $isSubtype($t1, t2TypeArg); |
| + } |
| + |
| let indefinite = false; |
| function definitive(t1, t2) { |
| let result = $isClassSubType(t1, t2, $covariant); |