@@ -2259,6 +2259,26 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
22592259
22602260 DartType iterableType = node.iterable.typeOrThrow;
22612261
2262+ Token ? awaitKeyword;
2263+ var parent = node.parent;
2264+ if (parent is ForStatement ) {
2265+ awaitKeyword = parent.awaitKeyword;
2266+ } else if (parent is ForElement ) {
2267+ awaitKeyword = parent.awaitKeyword;
2268+ }
2269+
2270+ // Use an explicit string instead of [loopType] to remove the "<E>".
2271+ String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable' ;
2272+
2273+ if (iterableType.isDynamic && typeSystem.strictCasts) {
2274+ errorReporter.reportErrorForNode (
2275+ CompileTimeErrorCode .FOR_IN_OF_INVALID_TYPE ,
2276+ node.iterable,
2277+ [iterableType, loopNamedType],
2278+ );
2279+ return false ;
2280+ }
2281+
22622282 // TODO(scheglov) use NullableDereferenceVerifier
22632283 if (_isNonNullableByDefault) {
22642284 if (typeSystem.isNullable (iterableType)) {
@@ -2275,14 +2295,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
22752295 return false ;
22762296 }
22772297
2278- Token ? awaitKeyword;
2279- var parent = node.parent;
2280- if (parent is ForStatement ) {
2281- awaitKeyword = parent.awaitKeyword;
2282- } else if (parent is ForElement ) {
2283- awaitKeyword = parent.awaitKeyword;
2284- }
2285-
22862298 // The object being iterated has to implement Iterable<T> for some T that
22872299 // is assignable to the variable's type.
22882300 // TODO(rnystrom): Move this into mostSpecificTypeArgument()?
@@ -2297,8 +2309,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
22972309 }
22982310
22992311 if (! typeSystem.isAssignableTo (iterableType, requiredSequenceType)) {
2300- // Use an explicit string instead of [loopType] to remove the "<E>".
2301- String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable' ;
23022312 errorReporter.reportErrorForNode (
23032313 CompileTimeErrorCode .FOR_IN_OF_INVALID_TYPE ,
23042314 node.iterable,
0 commit comments