Index: pkg/kernel/lib/transformations/erasure.dart |
diff --git a/pkg/kernel/lib/transformations/erasure.dart b/pkg/kernel/lib/transformations/erasure.dart |
index c2f572d2c7855188f5a5b059b87eb064ba933a1e..30e771f75fac1248f43cc0dc4ec3e974038d5149 100644 |
--- a/pkg/kernel/lib/transformations/erasure.dart |
+++ b/pkg/kernel/lib/transformations/erasure.dart |
@@ -51,6 +51,29 @@ class Erasure extends Transformer { |
@override |
visitDartType(DartType type) { |
+ if (type is FunctionType && type.typeParameters.isNotEmpty) { |
+ for (var parameter in type.typeParameters) { |
+ // Note, normally, we would have to remove these substitutions again to |
+ // avoid memory leaks. Unfortunately, that that's not compatible with |
+ // how function types share their TypeParameter object with a |
+ // FunctionNode. |
+ substitution[parameter] = const DynamicType(); |
+ } |
+ for (var parameter in type.typeParameters) { |
+ if (!isObject(parameter.bound)) { |
+ substitution[parameter] = substitute(parameter.bound, substitution); |
+ } |
+ } |
+ // We need to delete the type parameters of the function type before |
+ // calling [substitute], otherwise it creates a new environment with |
+ // fresh type variables that shadow the ones we want to remove. Since a |
+ // FunctionType is often assumed to immutable, we return a copy. |
Kevin Millikin (Google)
2017/08/14 10:47:35
"to immutable" ==> "to be immutable"
|
+ type = new FunctionType(type.positionalParameters, type.returnType, |
+ namedParameters: type.namedParameters, |
+ requiredParameterCount: type.requiredParameterCount, |
+ positionalParameterNames: type.positionalParameterNames, |
+ typedefReference: type.typedefReference); |
+ } |
type = substitute(type, substitution); |
if (isInConstantContext) { |
type = substitute(type, constantSubstitution); |