| Index: lib/src/checker/checker.dart | 
| diff --git a/lib/src/checker/checker.dart b/lib/src/checker/checker.dart | 
| index 36d85178606638450536c73ddb9602b347271453..96c2d1d401915ce6e851247061e667418c0f2b10 100644 | 
| --- a/lib/src/checker/checker.dart | 
| +++ b/lib/src/checker/checker.dart | 
| @@ -406,7 +406,9 @@ class CodeChecker extends RecursiveAstVisitor { | 
| void visitForEachStatement(ForEachStatement node) { | 
| // Check that the expression is an Iterable. | 
| var expr = node.iterable; | 
| -    var iterableType = rules.provider.iterableType; | 
| +    var iterableType = node.awaitKeyword != null | 
| +        ? rules.provider.streamType | 
| +        : rules.provider.iterableType; | 
| var loopVariable = node.identifier != null | 
| ? node.identifier | 
| : node.loopVariable.identifier; | 
| @@ -578,69 +580,10 @@ class CodeChecker extends RecursiveAstVisitor { | 
| node.visitChildren(this); | 
| } | 
|  | 
| -  DartType _getExpectedReturnType(FunctionBody body, bool yieldStar) { | 
| -    FunctionType functionType; | 
| -    var parent = body.parent; | 
| -    if (parent is Declaration) { | 
| -      functionType = rules.elementType(parent.element); | 
| -    } else { | 
| -      assert(parent is FunctionExpression); | 
| -      functionType = rules.getStaticType(parent); | 
| -    } | 
| - | 
| -    var type = functionType.returnType; | 
| -    var provider = rules.provider; | 
| - | 
| -    InterfaceType expectedType = null; | 
| -    if (body.isAsynchronous) { | 
| -      if (body.isGenerator) { | 
| -        // Stream<T> -> T | 
| -        expectedType = provider.streamType; | 
| -      } else { | 
| -        // Future<T> -> T | 
| -        // TODO(vsm): Revisit with issue #228. | 
| -        expectedType = provider.futureType; | 
| -      } | 
| -    } else { | 
| -      if (body.isGenerator) { | 
| -        // Iterable<T> -> T | 
| -        expectedType = provider.iterableType; | 
| -      } else { | 
| -        // T -> T | 
| -        return type; | 
| -      } | 
| -    } | 
| -    if (yieldStar) { | 
| -      if (type.isDynamic) { | 
| -        // Ensure it's at least a Stream / Iterable. | 
| -        return expectedType.substitute4([provider.dynamicType]); | 
| -      } else { | 
| -        // Analyzer will provide a separate error if expected type | 
| -        // is not compatible with type. | 
| -        return type; | 
| -      } | 
| -    } | 
| -    if (type.isDynamic) { | 
| -      return type; | 
| -    } else if (type is InterfaceType && type.element == expectedType.element) { | 
| -      return type.typeArguments[0]; | 
| -    } else { | 
| -      // Malformed type - fallback on analyzer error. | 
| -      return null; | 
| -    } | 
| -  } | 
| - | 
| -  FunctionBody _getFunctionBody(AstNode node) { | 
| -    while (node is! FunctionBody) { | 
| -      node = node.parent; | 
| -    } | 
| -    return node as FunctionBody; | 
| -  } | 
| - | 
| void _checkReturnOrYield(Expression expression, AstNode node, | 
| -      [bool yieldStar = false]) { | 
| -    var body = _getFunctionBody(node); | 
| -    var type = _getExpectedReturnType(body, yieldStar); | 
| +      {bool yieldStar: false}) { | 
| +    var body = node.getAncestor((n) => n is FunctionBody); | 
| +    var type = rules.getExpectedReturnType(body, yieldStar: yieldStar); | 
| if (type == null) { | 
| // We have a type mismatch: the async/async*/sync* modifier does | 
| // not match the return or yield type.  We should have already gotten an | 
| @@ -665,7 +608,7 @@ class CodeChecker extends RecursiveAstVisitor { | 
|  | 
| @override | 
| void visitYieldStatement(YieldStatement node) { | 
| -    _checkReturnOrYield(node.expression, node, node.star != null); | 
| +    _checkReturnOrYield(node.expression, node, yieldStar: node.star != null); | 
| node.visitChildren(this); | 
| } | 
|  | 
|  |