diff --git a/pkg/front_end/test/static_types/data/for_in.dart b/pkg/front_end/test/static_types/data/for_in.dart index 662d2137a65d..c75d8a952351 100644 --- a/pkg/front_end/test/static_types/data/for_in.dart +++ b/pkg/front_end/test/static_types/data/for_in.dart @@ -159,3 +159,23 @@ customStreamIterator(StreamWithCustomIterator stream) async { e; } } + +void genericIterable>(T x) { + /*current: T*/ + for (var y in + /*cfe|dart2js.T*/ + /*cfe:nnbd.T!*/ + x) { + /*T*/ y; + } +} + +void genericStream>(T x) async { + /*current: T*/ + await for (var y in + /*cfe|dart2js.T*/ + /*cfe:nnbd.T!*/ + x) { + /*T*/ y; + } +} diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart index c10bc7d93d43..84f5a8f63ab9 100644 --- a/pkg/kernel/lib/type_environment.dart +++ b/pkg/kernel/lib/type_environment.dart @@ -99,6 +99,11 @@ abstract class TypeEnvironment extends SubtypeTester { DartType forInElementType(ForInStatement node, DartType iterableType) { // TODO(johnniwinther): Update this to use the type of // `iterable.iterator.current` if inference is updated accordingly. + while (iterableType is TypeParameterType) { + TypeParameterType typeParameterType = iterableType; + iterableType = + typeParameterType.promotedBound ?? typeParameterType.parameter.bound; + } if (node.isAsync) { InterfaceType type = getTypeAsInstanceOf(iterableType, coreTypes.streamClass);