anchor.diff:        {bool isAsync: false,
         bool hasProblem}) {
       assert(hasProblem != null);
  -    DartType elementType;
       bool typeChecksNeeded = !inferrer.isTopLevel;
  -    DartType syntheticWriteType;
  -    Expression rhs;
  -    // If `true`, the synthetic statement should not be visited.
  -    bool skipStatement = false;
  -    // TODO(johnniwinther): Refactor handling of synthetic assignment to avoid
  -    // case handling here.
  -    VariableSet syntheticVariableSet;
  -    PropertySet syntheticPropertySet;
  -    SuperPropertySet syntheticSuperPropertySet;
  -    StaticSet syntheticStaticSet;
  -    if (syntheticAssignment is VariableSet) {
  -      syntheticVariableSet = syntheticAssignment;
  -      syntheticWriteType = elementType = syntheticVariableSet.variable.type;
  -      rhs = syntheticVariableSet.value;
  -      // This expression is fully handled in this method so we should not
  -      // visit the synthetic statement.
  -      skipStatement = true;
  -    } else if (syntheticAssignment is PropertySet) {
  -      syntheticPropertySet = syntheticAssignment;
  -      ExpressionInferenceResult receiverResult = inferrer.inferExpression(
  -          syntheticPropertySet.receiver, const UnknownType(), true);
  -      syntheticPropertySet.receiver = receiverResult.expression
  -        ..parent = syntheticPropertySet;
  -      DartType receiverType = receiverResult.inferredType;
  -      ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
  -          receiverType,
  -          syntheticPropertySet.name,
  -          syntheticPropertySet.fileOffset,
  -          setter: true,
  -          instrumented: true,
  -          includeExtensionMethods: true);
  -      syntheticWriteType =
  -          elementType = inferrer.getSetterType(writeTarget, receiverType);
  -      Expression error = inferrer.reportMissingInterfaceMember(
  -          writeTarget,
  -          receiverType,
  -          syntheticPropertySet.name,
  -          syntheticPropertySet.fileOffset,
  -          templateUndefinedSetter);
  -      if (error != null) {
  -        rhs = error;
  -      } else {
  -        if (writeTarget.isInstanceMember) {
  -          if (inferrer.instrumentation != null &&
  -              receiverType == const DynamicType()) {
  -            inferrer.instrumentation.record(
  -                inferrer.uriForInstrumentation,
  -                syntheticPropertySet.fileOffset,
  -                'target',
  -                new InstrumentationValueForMember(writeTarget.member));
  -          }
  -          syntheticPropertySet.interfaceTarget = writeTarget.member;
  -        }
  -        rhs = syntheticPropertySet.value;
  -      }
  -    } else if (syntheticAssignment is SuperPropertySet) {
  -      syntheticSuperPropertySet = syntheticAssignment;
  -      DartType receiverType = inferrer.thisType;
  -      ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
  -          receiverType,
  -          syntheticSuperPropertySet.name,
  -          syntheticSuperPropertySet.fileOffset,
  -          setter: true,
  -          instrumented: true);
  -      if (writeTarget.isInstanceMember) {
  -        syntheticSuperPropertySet.interfaceTarget = writeTarget.member;
  -      }
  -      syntheticWriteType =
  -          elementType = inferrer.getSetterType(writeTarget, receiverType);
  -      rhs = syntheticSuperPropertySet.value;
  -    } else if (syntheticAssignment is StaticSet) {
  -      syntheticStaticSet = syntheticAssignment;
  -      syntheticWriteType = elementType = syntheticStaticSet.target.setterType;
  -      rhs = syntheticStaticSet.value;
  -    } else if (syntheticAssignment is InvalidExpression || hasProblem) {
  -      elementType = const UnknownType();
  -    } else {
  -      unhandled(
  -          "${syntheticAssignment.runtimeType}",
  -          "handleForInStatementWithoutVariable",
  -          syntheticAssignment.fileOffset,
  -          inferrer.helper.uri);
  -    }
  -
  +    ForInVariable forInVariable =
  +        computeForInVariable(syntheticAssignment, hasProblem);
  +    DartType elementType = forInVariable.computeElementType(inferrer);
       ExpressionInferenceResult iterableResult = inferForInIterable(
           iterable, elementType, typeChecksNeeded,
           isAsync: isAsync);
  
positive.code:     return new ExpressionInferenceResult(inferredType, iterable);
    }
  
    ForInResult handleForInWithoutVariable(
        TreeNode node,
        VariableDeclaration variable,
  
negative.code:     }
      // This is matched by the call to [forEach_end] in
      // [inferElement], [inferMapEntry] or [inferForInStatement].
      inferrer.flowAnalysis.forEach_bodyBegin(node, variable, inferredType);
      syntheticAssignment = forInVariable.inferAssignment(inferrer, inferredType);
      if (expressionEffects != null) {
        StatementInferenceResult result =
            inferrer.inferStatement(expressionEffects);
        expressionEffects =
            result.hasChanged ? result.statement : expressionEffects;
      }
      return new ForInResult(variable, iterableResult.expression,
          syntheticAssignment, expressionEffects);
  