Index: pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart |
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart |
index a5680663b42babb1f0b732cb0e6a77ce72a21d3c..4ff72abcc81347b0ada2d56bd23603fe6c047361 100644 |
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart |
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart |
@@ -538,11 +538,28 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> { |
} |
TypeMask joinTypeMasks(Iterable<TypeMask> masks) { |
- TypeMask newType = const TypeMask.nonNullEmpty(); |
+ var dynamicType = compiler.typesTask.dynamicType; |
+ // Optimization: we are iterating over masks twice, but because `masks` is a |
+ // mapped iterable, we save the intermediate results to avoid computing them |
+ // again. |
+ var list = []; |
for (TypeMask mask in masks) { |
- newType = newType.union(mask, classWorld); |
+ // Don't do any work on computing unions if we know that after all that |
+ // work the result will be `dynamic`. |
+ // TODO(sigmund): change to `mask == dynamicType` so we can continue to |
+ // track the non-nullable bit. |
+ if (mask.containsAll(classWorld)) return dynamicType; |
Siggi Cherem (dart-lang)
2015/12/17 01:02:57
note: i reverted a change I did here: instead of `
|
+ list.add(mask); |
} |
- return newType.containsAll(classWorld) ? dynamicType.type : newType; |
+ |
+ TypeMask newType = null; |
+ for (TypeMask mask in masks) { |
+ newType = newType == null ? mask : newType.union(mask, classWorld); |
+ // Likewise - stop early if we already reach dynamic. |
+ if (newType.containsAll(classWorld)) return dynamicType; |
+ } |
+ |
+ return newType ?? const TypeMask.nonNullEmpty(); |
} |
} |