eclipse-jdt / eclipse.jdt.core

Eclipse Public License 2.0
164 stars 130 forks source link

Incorrect overload resolution ends in type error. #2941

Open rluble opened 1 month ago

rluble commented 1 month ago

The following code:

import static java.util.stream.Collectors.collectingAndThen;

import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;

public abstract class BiStream<K, V> {
  public static <E, K, V> Collector<E, ?, BiStream<K, V>> toBiStream(
      Function<? super E, ? extends K> toKey, Function<? super E, ? extends V> toValue) {
    return collectingAndThen(toStream(), stream -> from(stream));
  }

  private static <T> Collector<T, ?, Stream<T>> toStream() {
    return null;
  }

  public static <T, K, V> BiStream<K, V> from(Iterable<T> elements) {
    return null;
  }

  public static <T, K, V> BiStream<K, V> from(Stream<T> stream) {
    return null;
  }
}

Fails to compile in ecj-4.32 with the following error:

1. ERROR in /Users/rluble/Downloads/BiStream.java (at line 10)
    return collectingAndThen(toStream(), stream -> from(stream));
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Type mismatch: cannot convert from Collector<Object,Object,Object> to Collector<E,?,BiStream<K,V>>

This is the result of selecting the wrong overload and incorrectly depending on declaration order.

If the overloads are declared in a different order as in:

import static java.util.stream.Collectors.collectingAndThen;

import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;

public abstract class BiStream<K, V> {
  public static <E, K, V> Collector<E, ?, BiStream<K, V>> toBiStream(
      Function<? super E, ? extends K> toKey, Function<? super E, ? extends V> toValue) {
    return collectingAndThen(toStream(), stream -> from(stream));
  }

  private static <T> Collector<T, ?, Stream<T>> toStream() {
    return null;
  }

  public static <T, K, V> BiStream<K, V> from(Stream<T> stream) {
    return null;
  }

  public static <T, K, V> BiStream<K, V> from(Iterable<T> elements) {
    return null;
  }
}

the code compiles.

stephan-herrmann commented 1 month ago

ECJ 3.35 and earlier (Eclipse 4.29) successfully compile the original example.

I'll check what commit caused this change.

rluble commented 1 month ago

ECJ 3.35 and earlier (Eclipse 4.29) successfully compile the original example.

I just downloaded ecj-4.29 and the error is present there as well. ecj-4.28 compiles it correctly.