diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart index 2199a52146b..6910d46392d 100644 --- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart +++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart @@ -46,6 +46,8 @@ class TypeMaskSystem { TypeMask fixedLengthType; TypeMask interceptorType; + TypeMask _indexableTypeTest; + ClassElement get jsNullClass => backend.jsNullClass; // TODO(karlklose): remove compiler here. @@ -71,8 +73,17 @@ class TypeMaskSystem { TypeMask typedArray = nonNullSubclass(backend.typedArrayClass); fixedLengthType = new TypeMask.unionOf( - [stringType, backend.fixedArrayType, typedArray], - classWorld); + [stringType, backend.fixedArrayType, typedArray], + classWorld); + + // Make a TypeMask containing Indexable and (redundantly) subtypes of + // string because the type inference does not infer that all strings are + // indexables. + TypeMask indexable = + new TypeMask.nonNullSubtype(backend.jsIndexableClass, classWorld); + _indexableTypeTest = new TypeMask.unionOf( + [indexable, anyString], + classWorld); } bool methodUsesReceiverArgument(FunctionElement function) { @@ -256,7 +267,7 @@ class TypeMaskSystem { bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) { if (!allowNull && t.isNullable) return false; - return t.nonNullable().satisfies(backend.jsIndexableClass, classWorld); + return _indexableTypeTest.containsMask(t.nonNullable(), classWorld); } bool isDefinitelyMutableIndexable(TypeMask t, {bool allowNull: false}) { diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart index 7fd2153184a..4748a59621b 100644 --- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart +++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart @@ -1238,8 +1238,8 @@ class TransformingVisitor extends DeepRecursiveVisitor { return true; case '[]=': - if (receiverValue.isNullable) return false; - if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type)) { + if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type, + allowNull: true)) { return false; } Primitive index = getDartArgument(node, 0);