Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1678313002: fix part of #25200, reject non-generic function subtype of generic function (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix synthetic ctor Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 1c3a644d230aa3c51518fe6a85c617a7e7cfd14f..041322f071f4a3c634640f9dcfb9f15d218d9c50 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -7295,6 +7295,48 @@ class ResolverVisitor extends ScopedVisitor {
}
/**
+ * Given a downward inference type [fnType], and the declared
+ * [typeParameterList] for a function expression, determines if we can enable
+ * downward inference and if so, returns the function type to use for
+ * inference.
+ *
+ * This will return null if inference is not possible. This happens when
+ * there is no way we can find a subtype of the function type, given the
+ * provided type parameter list.
+ */
+ FunctionType matchFunctionTypeParameters(
+ TypeParameterList typeParameterList, FunctionType fnType) {
+ if (typeParameterList == null) {
+ if (fnType.typeFormals.isEmpty) {
+ return fnType;
+ }
+
+ // A non-generic function cannot be a subtype of a generic one.
+ return null;
+ }
+
+ NodeList<TypeParameter> typeParameters = typeParameterList.typeParameters;
+ if (fnType.typeFormals.isEmpty) {
+ // TODO(jmesserly): this is a legal subtype. We don't currently infer
+ // here, but we could. This is similar to
+ // StrongTypeSystemImpl.inferFunctionTypeInstantiation, but we don't
+ // have the FunctionType yet for the current node, so it's not quite
+ // straightforward to apply.
+ return null;
+ }
+
+ if (fnType.typeFormals.length != typeParameters.length) {
+ // A subtype cannot have different number of type formals.
+ return null;
+ }
+
+ // Same number of type formals. Instantiate the function type so its
+ // parameter and return type are in terms of the surrounding context.
+ return fnType.instantiate(
+ typeParameters.map((t) => t.name.staticElement.type).toList());
+ }
+
+ /**
* If it is appropriate to do so, override the current type of the static and propagated elements
* associated with the given expression with the given type. Generally speaking, it is appropriate
* if the given type is more specific than the current type.
@@ -8078,12 +8120,16 @@ class ResolverVisitor extends ScopedVisitor {
try {
DartType functionType = InferenceContext.getType(node);
if (functionType is FunctionType) {
- _inferFormalParameterList(node.parameters, functionType);
- DartType returnType = _computeReturnOrYieldType(
- functionType.returnType,
- _enclosingFunction.isGenerator,
- _enclosingFunction.isAsynchronous);
- InferenceContext.setType(node.body, returnType);
+ functionType =
+ matchFunctionTypeParameters(node.typeParameters, functionType);
+ if (functionType is FunctionType) {
+ _inferFormalParameterList(node.parameters, functionType);
+ DartType returnType = _computeReturnOrYieldType(
+ functionType.returnType,
+ _enclosingFunction.isGenerator,
+ _enclosingFunction.isAsynchronous);
+ InferenceContext.setType(node.body, returnType);
+ }
}
super.visitFunctionExpression(node);
} finally {
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/type.dart ('k') | pkg/analyzer/lib/src/generated/static_type_analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698