L#4210. Skip empty return when inferring function literal return type when generator.
Bug: https://github.com/dart-lang/language/pull/4210 Change-Id: I098d80fe36ba6629d8613f2b4e80d4562c3232b5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446183 Reviewed-by: Erik Ernst <eernst@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
committed by
Commit Queue
parent
8f3035707f
commit
94920ec28f
@@ -10,6 +10,7 @@ import 'package:analyzer/src/dart/element/type.dart';
|
||||
import 'package:analyzer/src/dart/element/type_provider.dart';
|
||||
import 'package:analyzer/src/dart/element/type_system.dart';
|
||||
|
||||
/// See https://github.com/dart-lang/language/blob/main/resources/type-system/inference.md#function-literal-return-type-inference
|
||||
class BodyInferenceContext {
|
||||
final TypeSystemImpl _typeSystem;
|
||||
final bool isAsynchronous;
|
||||
@@ -67,7 +68,12 @@ class BodyInferenceContext {
|
||||
|
||||
void addReturnExpression(Expression? expression) {
|
||||
if (expression == null) {
|
||||
_returnTypes.add(_typeProvider.nullType);
|
||||
// If the enclosing function is not marked `sync*` or `async*`:
|
||||
// For each `return;` statement in the block, update
|
||||
// `T` to be `UP(Null, T)`.
|
||||
if (!isGenerator) {
|
||||
_returnTypes.add(_typeProvider.nullType);
|
||||
}
|
||||
} else {
|
||||
var type = expression.typeOrThrow;
|
||||
if (isAsynchronous) {
|
||||
|
||||
@@ -661,6 +661,55 @@ var v = () async* {
|
||||
_assertReturnType('() async* {', 'Stream<int>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_asyncStar_blockBody_hasReturn_empty() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () async* {
|
||||
yield 0;
|
||||
return;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() async* {', 'Stream<int>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_asyncStar_blockBody_hasReturn_noYield() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () async* {
|
||||
return;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() async* {', 'Stream<dynamic>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_asyncStar_blockBody_lubNum() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () async* {
|
||||
yield 0;
|
||||
yield 1.1;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() async* {', 'Stream<num>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_asyncStar_blockBody_lubObject() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () async* {
|
||||
yield 0;
|
||||
yield '';
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() async* {', 'Stream<Object>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_asyncStar_blockBody_lubWithNull() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () async* {
|
||||
yield 0;
|
||||
yield null;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() async* {', 'Stream<int?>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_sync_blockBody() async {
|
||||
await resolveTestCode('''
|
||||
var v = () {
|
||||
@@ -875,6 +924,55 @@ var v = () sync* {
|
||||
_assertReturnType('() sync* {', 'Iterable<int>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_syncStar_blockBody_hasReturn_empty() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () sync* {
|
||||
yield 0;
|
||||
return;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() sync* {', 'Iterable<int>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_syncStar_blockBody_hasReturn_noYield() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () sync* {
|
||||
return;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() sync* {', 'Iterable<dynamic>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_syncStar_blockBody_lubNum() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () sync* {
|
||||
yield 0;
|
||||
yield 1.1;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() sync* {', 'Iterable<num>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_syncStar_blockBody_lubObject() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () sync* {
|
||||
yield 0;
|
||||
yield '';
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() sync* {', 'Iterable<Object>');
|
||||
}
|
||||
|
||||
test_noContext_returnType_syncStar_blockBody_lubWithNull() async {
|
||||
await resolveTestCode(r'''
|
||||
var v = () sync* {
|
||||
yield 0;
|
||||
yield null;
|
||||
};
|
||||
''');
|
||||
_assertReturnType('() sync* {', 'Iterable<int?>');
|
||||
}
|
||||
|
||||
test_targetBoundedByFunctionType_argumentTypeMismatch() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
|
||||
Reference in New Issue
Block a user