Index: sdk/lib/_internal/compiler/implementation/lib/js_rti.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart b/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart |
index 721f38fcf51bc33eec995cd34ad24d5a81acc86a..0cd37e1cd1031abe633b22be37ac8a73cf60b5a9 100644 |
--- a/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart |
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart |
@@ -119,7 +119,7 @@ substitute(var substitution, var arguments) { |
* against. |
*/ |
bool checkSubtype(Object object, String isField, List checks, String asField) { |
- if (object == null) return true; |
+ if (object == null) return false; |
var arguments = getRuntimeTypeInfo(object); |
// Interceptor is needed for JSArray and native classes. |
// TODO(sra): It could be a more specialized interceptor since [object] is not |
@@ -143,7 +143,7 @@ String computeTypeName(String isField, List arguments) { |
} |
Object subtypeCast(Object object, String isField, List checks, String asField) { |
- if (!checkSubtype(object, isField, checks, asField)) { |
+ if (object != null && !checkSubtype(object, isField, checks, asField)) { |
String actualType = Primitives.objectTypeName(object); |
String typeName = computeTypeName(isField, checks); |
throw new CastErrorImplementation(object, typeName); |
@@ -153,7 +153,7 @@ Object subtypeCast(Object object, String isField, List checks, String asField) { |
Object assertSubtype(Object object, String isField, List checks, |
String asField) { |
- if (!checkSubtype(object, isField, checks, asField)) { |
+ if (object != null && !checkSubtype(object, isField, checks, asField)) { |
String typeName = computeTypeName(isField, checks); |
throw new TypeErrorImplementation(object, typeName); |
} |
@@ -195,13 +195,19 @@ getArguments(var type) { |
getField(var object, var name) => JS('var', r'#[#]', object, name); |
+bool isSubtypeOfNull(type) { |
+ // `null` means `dynamic`. |
+ return type == null || getConstructorName(type) == JS_OBJECT_CLASS_NAME(); |
+} |
+ |
/** |
* Tests whether the Dart object [o] is a subtype of the runtime type |
* representation [t], which is a type representation as described in the |
* comment on [isSubtype]. |
*/ |
bool checkSubtypeOfRuntimeType(Object o, var t) { |
- if (JS('bool', '# == null', o) || JS('bool', '# == null', t)) return true; |
+ if (JS('bool', '# == null', o)) return isSubtypeOfNull(t); |
+ if (JS('bool', '# == null', t)) return true; |
// Get the runtime type information from the object here, because we may |
// overwrite o with the interceptor below. |
var rti = getRuntimeTypeInfo(o); |
@@ -224,7 +230,7 @@ bool checkSubtypeOfRuntimeType(Object o, var t) { |
} |
Object subtypeOfRuntimeTypeCast(Object object, var type) { |
- if (!checkSubtypeOfRuntimeType(object, type)) { |
+ if (object != null && !checkSubtypeOfRuntimeType(object, type)) { |
String actualType = Primitives.objectTypeName(object); |
throw new CastErrorImplementation(actualType, runtimeTypeToString(type)); |
} |
@@ -232,7 +238,7 @@ Object subtypeOfRuntimeTypeCast(Object object, var type) { |
} |
Object assertSubtypeOfRuntimeType(Object object, var type) { |
- if (!checkSubtypeOfRuntimeType(object, type)) { |
+ if (object != null && !checkSubtypeOfRuntimeType(object, type)) { |
throw new TypeErrorImplementation(object, runtimeTypeToString(type)); |
} |
return object; |