anchor.diff:  // [String] depending on which it hits first.
   //
   // TODO(vsm): Consider merging with similar isClassSubType logic.
  -List _extractTypes(Type t1, Type t2) => JS('', '''(() => {
  -  let typeArguments2 = $getGenericArgs($t2);
  +List _extractTypes(Type t1, Type t2, List typeArguments2) => JS('', '''(() => {
     if ($t1 == $t2) return typeArguments2;
   
     if ($t1 == $Object) return null;
  
positive.code:   if (raw1 != null && raw1 == raw2) {
      let typeArguments1 = $getGenericArgs($t1);
      let length = typeArguments1.length;
      if (typeArguments2.length == 0) {
        // t2 is the raw form of t1
        return typeArguments1;
      } else if (length == 0) {
        // t1 is raw, but t2 is not
        if (typeArguments2.every($_isTop)) return typeArguments2;
        return null;
      }
      if (length != typeArguments2.length) $assertFailed();
      for (let i = 0; i < length; ++i) {
        let result =
            $_isSubtype(typeArguments1[i], typeArguments2[i], true);
  
negative.code:     return typeArguments1;
    }
  
    var result = $_extractTypes($t1.__proto__, $t2, $typeArguments2);
    if (result) return result;
  
    // Check mixin.
    let m1 = $getMixin($t1);
    if (m1 != null) {
      result = $_extractTypes(m1, $t2, $typeArguments2);
      if (result) return result;
    }
  
  