mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:21:07 +00:00
Support for bounds of generic function types for raw-depends / not simply bounded.
Change-Id: I568f4ebb922b3ce40debff1f4ce20a9ac580f29d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193141 Reviewed-by: Samuel Rawlins <srawlins@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
0e8bc12b51
commit
2c02737d7a
|
@ -289,6 +289,19 @@ class DefaultTypesBuilder {
|
|||
visited,
|
||||
),
|
||||
);
|
||||
for (var typeParameter in startType.typeFormals) {
|
||||
var bound = typeParameter.bound;
|
||||
if (bound != null) {
|
||||
paths.addAll(
|
||||
_findRawTypePathsToDeclaration(
|
||||
startParameter,
|
||||
bound,
|
||||
end,
|
||||
visited,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
for (var formalParameter in startType.parameters) {
|
||||
paths.addAll(
|
||||
_findRawTypePathsToDeclaration(
|
||||
|
|
|
@ -145,6 +145,7 @@ class SimplyBoundedDependencyWalker
|
|||
var collector = _TypeCollector();
|
||||
if (type is GenericFunctionType) {
|
||||
collector.addType(type.returnType);
|
||||
collector.visitTypeParameters(type.typeParameters);
|
||||
collector.visitParameters(type.parameters);
|
||||
} else {
|
||||
collector.addType(type);
|
||||
|
@ -283,6 +284,7 @@ class SimplyBoundedNode extends graph.Node<SimplyBoundedNode> {
|
|||
if (type is GenericFunctionType) {
|
||||
var collector = _TypeCollector();
|
||||
collector.addType(type.returnType);
|
||||
collector.visitTypeParameters(type.typeParameters);
|
||||
collector.visitParameters(type.parameters);
|
||||
for (var type in collector.types) {
|
||||
if (!_visitType(dependencies, type, allowTypeParameters)) {
|
||||
|
@ -326,4 +328,12 @@ class _TypeCollector {
|
|||
visitParameter(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void visitTypeParameters(TypeParameterList? node) {
|
||||
if (node != null) {
|
||||
for (var typeParameter in node.typeParameters) {
|
||||
addType(typeParameter.bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,14 @@ class A<T extends void Function(A)> {}
|
|||
]);
|
||||
}
|
||||
|
||||
test_class_recursion_notInstantiated_genericFunctionType2() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A<T extends void Function<U extends A>()> {}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, 42, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_class_recursion_typedef_notInstantiated() async {
|
||||
await assertErrorsInCode(r'''
|
||||
typedef F(C value);
|
||||
|
|
|
@ -1778,6 +1778,20 @@ notSimplyBounded class A<covariant T extends void Function(A<dynamic>)> {
|
|||
withTypeParameterVariance: true);
|
||||
}
|
||||
|
||||
test_class_typeParameters_defaultType_cycle_genericFunctionType2() async {
|
||||
featureSet = FeatureSets.genericMetadata;
|
||||
var library = await checkLibrary(r'''
|
||||
class C<T extends void Function<U extends C>()> {}
|
||||
''');
|
||||
checkElementText(
|
||||
library,
|
||||
r'''
|
||||
notSimplyBounded class C<covariant T extends void Function<U extends C<dynamic>>()> {
|
||||
}
|
||||
''',
|
||||
withTypeParameterVariance: true);
|
||||
}
|
||||
|
||||
test_class_typeParameters_defaultType_functionTypeAlias_contravariant_legacy() async {
|
||||
featureSet = FeatureSets.beforeNullSafe;
|
||||
var library = await checkLibrary(r'''
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
class Hest<TypeX extends Fisk> {}
|
||||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
|
||||
// ^
|
||||
// [cfe] Type variables can't have generic function types in their bounds.
|
||||
|
||||
typedef Fisk = void Function // don't merge lines
|
||||
// [error line 5, column 1, length 346]
|
||||
// [error line 7, column 1, length 346]
|
||||
// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
|
||||
// ^
|
||||
// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
|
||||
<TypeY extends Hest>();
|
||||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
|
||||
|
||||
main() {
|
||||
Hest hest = new Hest();
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
class Hest<TypeX extends Fisk> {}
|
||||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
|
||||
// ^
|
||||
// [cfe] Type variables can't have generic function types in their bounds.
|
||||
|
||||
typedef Fisk = void Function // don't merge lines
|
||||
// [error line 5, column 1, length 346]
|
||||
// [error line 7, column 1, length 346]
|
||||
// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
|
||||
// ^
|
||||
// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
|
||||
<TypeY extends Hest>();
|
||||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
|
||||
|
||||
main() {
|
||||
Hest hest = new Hest();
|
||||
|
|
Loading…
Reference in a new issue