Skip to content

Commit 94920ec

Browse files
scheglovCommit Queue
authored andcommitted
L#4210. Skip empty return when inferring function literal return type when generator.
Bug: dart-lang/language#4210 Change-Id: I098d80fe36ba6629d8613f2b4e80d4562c3232b5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446183 Reviewed-by: Erik Ernst <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]>
1 parent 8f30357 commit 94920ec

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:analyzer/src/dart/element/type.dart';
1010
import 'package:analyzer/src/dart/element/type_provider.dart';
1111
import 'package:analyzer/src/dart/element/type_system.dart';
1212

13+
/// See https://github.com/dart-lang/language/blob/main/resources/type-system/inference.md#function-literal-return-type-inference
1314
class BodyInferenceContext {
1415
final TypeSystemImpl _typeSystem;
1516
final bool isAsynchronous;
@@ -67,7 +68,12 @@ class BodyInferenceContext {
6768

6869
void addReturnExpression(Expression? expression) {
6970
if (expression == null) {
70-
_returnTypes.add(_typeProvider.nullType);
71+
// If the enclosing function is not marked `sync*` or `async*`:
72+
// For each `return;` statement in the block, update
73+
// `T` to be `UP(Null, T)`.
74+
if (!isGenerator) {
75+
_returnTypes.add(_typeProvider.nullType);
76+
}
7177
} else {
7278
var type = expression.typeOrThrow;
7379
if (isAsynchronous) {

pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,55 @@ var v = () async* {
661661
_assertReturnType('() async* {', 'Stream<int>');
662662
}
663663

664+
test_noContext_returnType_asyncStar_blockBody_hasReturn_empty() async {
665+
await resolveTestCode(r'''
666+
var v = () async* {
667+
yield 0;
668+
return;
669+
};
670+
''');
671+
_assertReturnType('() async* {', 'Stream<int>');
672+
}
673+
674+
test_noContext_returnType_asyncStar_blockBody_hasReturn_noYield() async {
675+
await resolveTestCode(r'''
676+
var v = () async* {
677+
return;
678+
};
679+
''');
680+
_assertReturnType('() async* {', 'Stream<dynamic>');
681+
}
682+
683+
test_noContext_returnType_asyncStar_blockBody_lubNum() async {
684+
await resolveTestCode(r'''
685+
var v = () async* {
686+
yield 0;
687+
yield 1.1;
688+
};
689+
''');
690+
_assertReturnType('() async* {', 'Stream<num>');
691+
}
692+
693+
test_noContext_returnType_asyncStar_blockBody_lubObject() async {
694+
await resolveTestCode(r'''
695+
var v = () async* {
696+
yield 0;
697+
yield '';
698+
};
699+
''');
700+
_assertReturnType('() async* {', 'Stream<Object>');
701+
}
702+
703+
test_noContext_returnType_asyncStar_blockBody_lubWithNull() async {
704+
await resolveTestCode(r'''
705+
var v = () async* {
706+
yield 0;
707+
yield null;
708+
};
709+
''');
710+
_assertReturnType('() async* {', 'Stream<int?>');
711+
}
712+
664713
test_noContext_returnType_sync_blockBody() async {
665714
await resolveTestCode('''
666715
var v = () {
@@ -875,6 +924,55 @@ var v = () sync* {
875924
_assertReturnType('() sync* {', 'Iterable<int>');
876925
}
877926

927+
test_noContext_returnType_syncStar_blockBody_hasReturn_empty() async {
928+
await resolveTestCode(r'''
929+
var v = () sync* {
930+
yield 0;
931+
return;
932+
};
933+
''');
934+
_assertReturnType('() sync* {', 'Iterable<int>');
935+
}
936+
937+
test_noContext_returnType_syncStar_blockBody_hasReturn_noYield() async {
938+
await resolveTestCode(r'''
939+
var v = () sync* {
940+
return;
941+
};
942+
''');
943+
_assertReturnType('() sync* {', 'Iterable<dynamic>');
944+
}
945+
946+
test_noContext_returnType_syncStar_blockBody_lubNum() async {
947+
await resolveTestCode(r'''
948+
var v = () sync* {
949+
yield 0;
950+
yield 1.1;
951+
};
952+
''');
953+
_assertReturnType('() sync* {', 'Iterable<num>');
954+
}
955+
956+
test_noContext_returnType_syncStar_blockBody_lubObject() async {
957+
await resolveTestCode(r'''
958+
var v = () sync* {
959+
yield 0;
960+
yield '';
961+
};
962+
''');
963+
_assertReturnType('() sync* {', 'Iterable<Object>');
964+
}
965+
966+
test_noContext_returnType_syncStar_blockBody_lubWithNull() async {
967+
await resolveTestCode(r'''
968+
var v = () sync* {
969+
yield 0;
970+
yield null;
971+
};
972+
''');
973+
_assertReturnType('() sync* {', 'Iterable<int?>');
974+
}
975+
878976
test_targetBoundedByFunctionType_argumentTypeMismatch() async {
879977
await assertErrorsInCode(
880978
r'''

0 commit comments

Comments
 (0)