anchor.diff:      DartType receiverType = _rules.getStaticType(target);
       assert(receiverType != null);
       if (receiverType.isDynamic) {
  -       record(new DynamicInvoke(_rules, node));
  +      record(new DynamicInvoke(_rules, node));
       }
       node.visitChildren(this);
       return node;
  
positive.code:     // Note: this essentially applies erasure on generics
      // instead of Dart's covariance.
  
      if (i1 == i2)
        return true;
  
      if (i1.element == i2.element)
        // Erasure!
        return true;
  
      if (i1 == provider.objectType)
        return false;
  
      if (isInterfaceSubTypeOf(i1.superclass, i2))
        return true;
  
      for (final parent in i1.interfaces) {
        if (isInterfaceSubTypeOf(parent, i2))
          return true;
      }
  
      for (final parent in i1.mixins) {
        if (isInterfaceSubTypeOf(parent, i2))
          return true;
      }
  
      return false;
  
negative.code: 
    bool isDynamic(DartType t) {
      // Erasure
      if (t is TypeParameterType) return true;
      if (t.isDartCoreFunction) return true;
      return t.isDynamic;
    }
  
    bool canBeBoxedTo(DartType primitiveType, DartType boxedType) {
      assert(isPrimitive(primitiveType));
      // Any primitive can be boxed to Object or dynamic.
      if (boxedType.isObject ||
          boxedType.isDynamic ||
          boxedType is TypeParameterType) {
        return true;
      }
      // True iff a location with this type may be assigned a boxed
      // int or double.
      if (primitiveType !=
          provider.boolType && !primitiveNum && boxedType.name == "num") {
        return true;
      }
      return false;
    }
  
    bool isPrimitive(DartType t) {
      // FIXME: Handle VoidType here?
      if (t.isVoid) return true;
      if (t == provider.intType ||
          t == provider.doubleType ||
          t == provider.boolType) return true;
      if (primitiveNum && t.name == "num") return true;
      return false;
    }
  
  