Skip to content

Commit

Permalink
Use demoteType() on inferred type arguments.
Browse files Browse the repository at this point in the history
Bug: dart-lang/language#1182 (comment)
Change-Id: I72d30f51aaf1d2651c1568cd68f37e5c7c03b582
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/165683
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
scheglov authored and [email protected] committed Oct 1, 2020
1 parent 033e029 commit 3698091
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 3 deletions.
3 changes: 3 additions & 0 deletions pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,9 @@ class GenericInferrer {
types[i] = _typeSystem.nonNullifyLegacy(types[i]);
}
}
for (var i = 0; i < types.length; i++) {
types[i] = _typeSystem.demoteType(types[i]);
}
}

/// If in a legacy library, return the legacy version of the [type].
Expand Down
21 changes: 21 additions & 0 deletions pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,27 @@ class GenericFunctionInferenceTest extends AbstractTypeSystemNullSafetyTest {
);
}

/// https://github.com/dart-lang/language/issues/1182#issuecomment-702272641
void test_demoteType() {
// <T>(T x) -> void
var T = typeParameter('T');
var rawType = functionTypeNone(
typeFormals: [T],
parameters: [
requiredParameter(type: typeParameterTypeNone(T)),
],
returnType: voidNone,
);

var S = typeParameter('S');
var S_and_int = typeParameterTypeNone(S, promotedBound: intNone);

var inferredTypes = _inferCall(rawType, [S_and_int]);
var inferredType = inferredTypes[0] as TypeParameterTypeImpl;
expect(inferredType.element, S);
expect(inferredType.promotedBound, isNull);
}

void test_fromLegacy_nonNullableBound() {
typeSystem = analysisContext.typeSystemLegacy;

Expand Down
37 changes: 35 additions & 2 deletions pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,48 @@
// 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.

import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'context_collection_resolution.dart';

main() {
defineReflectiveSuite(() {
defineReflectiveTests(InstanceCreationDriverResolutionTest);
defineReflectiveTests(InstanceCreationTest);
defineReflectiveTests(InstanceCreationWithNullSafetyTest);
});
}

@reflectiveTest
class InstanceCreationDriverResolutionTest extends PubPackageResolutionTest {
class InstanceCreationTest extends PubPackageResolutionTest
with InstanceCreationTestCases {}

mixin InstanceCreationTestCases on PubPackageResolutionTest {
test_demoteType() async {
await assertNoErrorsInCode(r'''
class A<T> {
A(T t);
}
void f<S>(S s) {
if (s is int) {
A(s);
}
}
''');

var creation = findNode.instanceCreation('A(s)');
var creationType = creation.staticType as InterfaceType;

assertTypeParameterType(
creationType.typeArguments[0],
element: findElement.typeParameter('S'),
promotedBound: null,
);
}

test_error_newWithInvalidTypeParameters_implicitNew_inference_top() async {
await assertErrorsInCode(r'''
final foo = Map<int>();
Expand Down Expand Up @@ -147,3 +176,7 @@ main() {
);
}
}

@reflectiveTest
class InstanceCreationWithNullSafetyTest extends PubPackageResolutionTest
with WithNullSafetyMixin, InstanceCreationTestCases {}
19 changes: 19 additions & 0 deletions pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,25 @@ f(A a, int b, int c) {
expectedType: 'String');
}

test_demoteType() async {
await assertNoErrorsInCode(r'''
void test<T>(T t) {}
void f<S>(S s) {
if (s is int) {
test(s);
}
}
''');

assertTypeParameterType(
findNode.methodInvocation('test(s)').typeArgumentTypes[0],
element: findElement.typeParameter('S'),
promotedBound: null,
);
}

test_error_ambiguousImport_topFunction() async {
newFile('$testPackageLibPath/a.dart', content: r'''
void foo(int _) {}
Expand Down
13 changes: 12 additions & 1 deletion pkg/analyzer/test/src/dart/resolution/resolution.dart
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,9 @@ mixin ResolutionTest implements ResourceProviderMixin {

void assertType(Object typeOrNode, String expected) {
DartType actual;
if (typeOrNode is DartType) {
if (typeOrNode == null) {
actual = typeOrNode;
} else if (typeOrNode is DartType) {
actual = typeOrNode;
} else if (typeOrNode is Expression) {
actual = typeOrNode.staticType;
Expand Down Expand Up @@ -774,6 +776,15 @@ mixin ResolutionTest implements ResourceProviderMixin {
expect(node.staticType, isNull);
}

void assertTypeParameterType(
TypeParameterTypeImpl type, {
@required TypeParameterElement element,
@required String promotedBound,
}) {
assertElement(type.element, element);
assertType(type.promotedBound, promotedBound);
}

Matcher elementMatcher(
Element declaration, {
bool isLegacy = false,
Expand Down

0 comments on commit 3698091

Please sign in to comment.