Skip to content

Commit

Permalink
Report COULD_NOT_INFER when inference fails for ExtensionOverride.
Browse files Browse the repository at this point in the history
[email protected]

Change-Id: Ibadc5deac6289216b3d1547b963a206560c64691
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112760
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
scheglov authored and [email protected] committed Aug 12, 2019
1 parent 5d2c17d commit f444374
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
23 changes: 12 additions & 11 deletions pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,7 @@ class ExtensionMemberResolver {
var receiverExpression = arguments[0];
var receiverType = receiverExpression.staticType;

var typeArgumentTypes = _inferTypeArguments(
element,
receiverType,
node.typeArguments,
);
var typeArgumentTypes = _inferTypeArguments(node, receiverType);

nodeImpl.typeArgumentTypes = typeArgumentTypes;
nodeImpl.extendedType = Substitution.fromPairs(
Expand Down Expand Up @@ -307,23 +303,24 @@ class ExtensionMemberResolver {
return candidates;
}

/// Given the generic [extension] element, either return types specified
/// Given the generic [element] element, either return types specified
/// explicitly in [typeArguments], or infer type arguments from the given
/// [receiverType].
///
/// If the number of explicit type arguments is different than the number
/// of extension's type parameters, or inference fails, return `dynamic`
/// for all type parameters.
List<DartType> _inferTypeArguments(
ExtensionElement extension,
ExtensionOverride node,
DartType receiverType,
TypeArgumentList typeArguments,
) {
var typeParameters = extension.typeParameters;
var element = node.staticElement;
var typeParameters = element.typeParameters;
if (typeParameters.isEmpty) {
return const <DartType>[];
}

var typeArguments = node.typeArguments;
if (typeArguments != null) {
var arguments = typeArguments.arguments;
if (arguments.length == typeParameters.length) {
Expand All @@ -340,10 +337,14 @@ class ExtensionMemberResolver {
);
inferrer.constrainArgument(
receiverType,
extension.extendedType,
element.extendedType,
'extendedType',
);
return inferrer.infer(typeParameters);
return inferrer.infer(
typeParameters,
errorReporter: _errorReporter,
errorNode: node.extensionName,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

Expand Down Expand Up @@ -283,6 +284,23 @@ void f(A<int> a) {
);
}

test_override_inferTypeArguments_error_couldNotInfer() async {
await assertErrorsInCode('''
extension E<T extends num> on T {
void foo() {}
}
f(String s) {
E(s).foo();
}
''', [
error(StrongModeCode.COULD_NOT_INFER, 69, 1),
]);
var override = findNode.extensionOverride('E(s)');
assertElementTypeStrings(override.typeArgumentTypes, ['String']);
assertElementTypeString(override.extendedType, 'String');
}

test_override_inferTypeArguments_getter() async {
await assertNoErrorsInCode('''
class A<T> {}
Expand Down

0 comments on commit f444374

Please sign in to comment.