Use default type for type variable bounds.
Change-Id: I5d21a16a76eb6cd898e8e11104d0be0f7e669426
Reviewed-on: https://dart-review.googlesource.com/59420
Reviewed-by: Stephen Adams <sra@google.com>
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index c4419b5..738bd388 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -1455,6 +1455,12 @@
/// `Object`.
DartType getTypeVariableBound(TypeVariableEntity typeVariable);
+ /// The default type of the [typeVariable].
+ ///
+ /// This is the type used as the default type argument when no explicit type
+ /// argument is passed.
+ DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable);
+
/// Returns the type of [function].
FunctionType getFunctionType(FunctionEntity function);
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 492adf3..d3267ab 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -170,7 +170,7 @@
targetArguments[count++] = _rtiEncoder.getTypeRepresentation(
_emitter,
_closedWorld.elementEnvironment
- .getTypeVariableBound(typeVariable.element),
+ .getTypeVariableDefaultType(typeVariable.element),
(_) => _emitter.constantReference(new NullConstantValue()));
} else {
String jsName = '\$${typeVariable.element.name}';
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index e566ff0..ee5006d 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -682,6 +682,12 @@
return data.getBound(this);
}
+ DartType _getTypeVariableDefaultType(IndexedTypeVariable typeVariable) {
+ assert(checkFamily(typeVariable));
+ TypeVariableData data = _typeVariables.getData(typeVariable);
+ return data.getDefaultType(this);
+ }
+
ClassEntity _getAppliedMixin(IndexedClass cls) {
assert(checkFamily(cls));
ClassData data = _classes.getData(cls);
@@ -1280,6 +1286,11 @@
return super._getTypeVariableBound(typeVariable);
}
+ DartType _getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
+ if (typeVariable is KLocalTypeVariable) return typeVariable.defaultType;
+ return super._getTypeVariableDefaultType(typeVariable);
+ }
+
@override
void _forEachNestedClosure(
MemberEntity member, void f(FunctionEntity closure)) {
@@ -1373,6 +1384,8 @@
index = 0;
for (ir.TypeParameter typeParameter in function.typeParameters) {
typeVariables[index].bound = getDartType(typeParameter.bound);
+ typeVariables[index].defaultType =
+ getDartType(typeParameter.defaultType);
index++;
}
localFunction.functionType = getFunctionType(function);
@@ -1488,6 +1501,11 @@
}
@override
+ DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
+ return elementMap._getTypeVariableDefaultType(typeVariable);
+ }
+
+ @override
InterfaceType createInterfaceType(
ClassEntity cls, List<DartType> typeArguments) {
return new InterfaceType(cls, typeArguments);
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index dde76e85..dcef78f 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -1014,6 +1014,7 @@
class TypeVariableData {
final ir.TypeParameter node;
DartType _bound;
+ DartType _defaultType;
TypeVariableData(this.node);
@@ -1021,6 +1022,10 @@
return _bound ??= elementMap.getDartType(node.bound);
}
+ DartType getDefaultType(KernelToElementMap elementMap) {
+ return _defaultType ??= elementMap.getDartType(node.defaultType);
+ }
+
TypeVariableData copy() {
return new TypeVariableData(node);
}
diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart
index 3b18fbc..38d7dd6 100644
--- a/pkg/compiler/lib/src/kernel/kelements.dart
+++ b/pkg/compiler/lib/src/kernel/kelements.dart
@@ -293,6 +293,7 @@
final String name;
final int index;
DartType bound;
+ DartType defaultType;
KLocalTypeVariable(this.typeDeclaration, this.name, this.index);
diff --git a/tests/compiler/dart2js/generic_methods/generic_method_test.dart b/tests/compiler/dart2js/generic_methods/generic_method_test.dart
index e907015..ae1e4fd 100644
--- a/tests/compiler/dart2js/generic_methods/generic_method_test.dart
+++ b/tests/compiler/dart2js/generic_methods/generic_method_test.dart
@@ -113,8 +113,6 @@
new Class2().method5<int>(0);
new Class3().method6<int>(0);
dynamic c3 = args != null ? new Class3() : new Class2();
- // TODO(johnniwinther): Expected bounds should be `dynamic` when CFE supports
- // instantiate-to-bound.
c3.method6(0); // Missing type arguments.
try {
dynamic c2 = args == null ? new Class3() : new Class2();
@@ -162,8 +160,8 @@
"foo" is int = false
Class3.method6:
-0 is Object = true
-"foo" is Object = true
+0 is dynamic = true
+"foo" is dynamic = true
Class2.method6:
0 is int = true
diff --git a/tests/language_2/function_call_generic_test.dart b/tests/language_2/function_call_generic_test.dart
index b98584e..db40488 100644
--- a/tests/language_2/function_call_generic_test.dart
+++ b/tests/language_2/function_call_generic_test.dart
@@ -1,6 +1,7 @@
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// dart2jsOptions=-Ddart.isdart2js=true
import "package:expect/expect.dart";
@@ -21,7 +22,8 @@
print('a: $expected');
print('b: $actual');
if (((actual[0] == Object && expected[0] == dynamic) ||
- (actual[0] == dynamic && expected[0] == Object))) {
+ (actual[0] == dynamic && expected[0] == Object)) &&
+ !const bool.fromEnvironment('dart.isdart2js')) {
// TODO(32483): dartdevk sometimes defaults type to 'Object' when 'dynamic'
// is required. Remove this hack when fixed.
// TODO(31581): dart2js needs instantiate-to-bound to generic 'dynamic'