Skip to content

Commit a621589

Browse files
chloestefantsovaCommit Queue
authored andcommitted
[model] Handle local function instantiations in type checks
Closes #61370 Change-Id: I6007bafaf7058bf1b2d5f7ec28f1413bc5a4e694 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447700 Reviewed-by: Erik Ernst <[email protected]> Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent c440213 commit a621589

File tree

3 files changed

+98
-13
lines changed

3 files changed

+98
-13
lines changed

pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -957,18 +957,15 @@ extension on Element {
957957
/// `null` is returned. For [PropertyAccessorElement], the return value is
958958
/// returned. For all other elements, their `type` property is returned.
959959
DartType? get referenceType {
960-
if (this is ConstructorElement) {
961-
return (this as ConstructorElement).type;
962-
} else if (this is TopLevelFunctionElement) {
963-
return (this as TopLevelFunctionElement).type;
964-
} else if (this is PropertyAccessorElement) {
965-
return (this as PropertyAccessorElement).returnType;
966-
} else if (this is MethodElement) {
967-
return (this as MethodElement).type;
968-
} else if (this is VariableElement) {
969-
return (this as VariableElement).type;
970-
} else {
971-
return null;
972-
}
960+
var self = this;
961+
return switch (self) {
962+
ConstructorElement() => self.type,
963+
TopLevelFunctionElement() => self.type,
964+
LocalFunctionElement() => self.type,
965+
PropertyAccessorElement() => self.returnType,
966+
MethodElement() => self.type,
967+
VariableElement() => self.type,
968+
_ => null,
969+
};
973970
}
974971
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
typedef F<X> = X Function(X);
6+
7+
extension<X> on X {
8+
X m<Y extends F<X>>() => this;
9+
}
10+
11+
void test1() {
12+
g() sync* {
13+
yield 1;
14+
yield null;
15+
}
16+
17+
g.m<F<Iterable<int?> Function()>>();
18+
g.m<F<Iterable<int?> Function()>>;
19+
g.m<F<Iterable<int> Function()>>();
20+
//^
21+
// [cfe] Type argument 'Iterable<int> Function() Function(Iterable<int> Function())' doesn't conform to the bound 'X Function(X)' of the type variable 'Y' on 'm'.
22+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
24+
g.m<F<Iterable<int> Function()>>;
25+
// ^
26+
// [cfe] Type argument 'Iterable<int> Function() Function(Iterable<int> Function())' doesn't conform to the bound 'Iterable<int?> Function() Function(Iterable<int?> Function())' of the type variable 'Y' on 'Iterable<int?> Function() Function<Y extends Iterable<int?> Function() Function(Iterable<int?> Function())>()'.
27+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
28+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
29+
}
30+
31+
void test2(Iterable<int?> h()) {
32+
h.m<F<Iterable<int?> Function()>>();
33+
h.m<F<Iterable<int?> Function()>>;
34+
h.m<F<Iterable<int> Function()>>();
35+
//^
36+
// [cfe] Type argument 'Iterable<int> Function() Function(Iterable<int> Function())' doesn't conform to the bound 'X Function(X)' of the type variable 'Y' on 'm'.
37+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
39+
h.m<F<Iterable<int> Function()>>;
40+
// ^
41+
// [cfe] Type argument 'Iterable<int> Function() Function(Iterable<int> Function())' doesn't conform to the bound 'Iterable<int?> Function() Function(Iterable<int?> Function())' of the type variable 'Y' on 'Iterable<int?> Function() Function<Y extends Iterable<int?> Function() Function(Iterable<int?> Function())>()'.
42+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
43+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
typedef F<X> = X Function(X);
6+
7+
extension<X> on X {
8+
X m<Y extends F<X>>() => this;
9+
}
10+
11+
void test1() {
12+
g() {
13+
if (2 > 1) return 1;
14+
return null;
15+
}
16+
17+
g.m<F<int? Function()>>();
18+
g.m<F<int? Function()>>;
19+
g.m<F<int Function()>>();
20+
//^
21+
// [cfe] Type argument 'int Function() Function(int Function())' doesn't conform to the bound 'X Function(X)' of the type variable 'Y' on 'm'.
22+
// ^^^^^^^^^^^^^^^^^
23+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
24+
g.m<F<int Function()>>;
25+
// ^
26+
// [cfe] Type argument 'int Function() Function(int Function())' doesn't conform to the bound 'int? Function() Function(int? Function())' of the type variable 'Y' on 'int? Function() Function<Y extends int? Function() Function(int? Function())>()'.
27+
// ^^^^^^^^^^^^^^^^^
28+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
29+
}
30+
31+
void test2(int? h()) {
32+
h.m<F<int? Function()>>();
33+
h.m<F<int? Function()>>;
34+
h.m<F<int Function()>>();
35+
//^
36+
// [cfe] Type argument 'int Function() Function(int Function())' doesn't conform to the bound 'X Function(X)' of the type variable 'Y' on 'm'.
37+
// ^^^^^^^^^^^^^^^^^
38+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
39+
h.m<F<int Function()>>;
40+
// ^
41+
// [cfe] Type argument 'int Function() Function(int Function())' doesn't conform to the bound 'int? Function() Function(int? Function())' of the type variable 'Y' on 'int? Function() Function<Y extends int? Function() Function(int? Function())>()'.
42+
// ^^^^^^^^^^^^^^^^^
43+
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
44+
}

0 commit comments

Comments
 (0)