JDK-4898773 : inference: error in type inference for bounded type parameters
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2003-07-30
  • Updated: 2007-09-25
  • Resolved: 2007-09-25
Related Reports
Relates :  
Description

Name: rmT116609			Date: 07/30/2003


FULL PRODUCT VERSION :
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

FULL OS VERSION :
Windows XP

EXTRA RELEVANT SYSTEM CONFIGURATION :
prototype compiler for generics version 2.2-ea

A DESCRIPTION OF THE PROBLEM :
I'm using the prototype compiler for generics version 2.2-ea.

For a parameterized method the compiler seems to deduce a type that is not within bounds.

package generics;
import java.util.*;
import java.io.Serializable;


public class ParameterInference3 {
	
	private static void f(String s) {
		System.out.println("String");
	}

	private static void f(Integer s) {
		System.out.println("String");
	}

	private static void f(Comparable e) {
		System.out.println("Comparable");
	}

	private static void f(Serializable e) {
		System.out.println("Serializable");
	}

	private static void f(Object e) {
		System.out.println("Object");
	}
	
	
	private static class Utilities {

	  public static <T extends Comparable> T max(T arg1, T arg2) {
	  	return (arg1.compareTo(arg2)>0)?arg1:arg2;
	  }
	}






	public static void main(String[] args) {
		f(Utilities.max("abc",new Integer(10)));
	}
}


The compiler complains:

ParameterInference3.java:42: reference to f is ambiguous, both method f(java.lang.Comparable) in generics.ParameterInference3 and method f(java.io.Serializable) in generics.ParameterInference3 match
		f(Utilities.max("abc",new Integer(10)));
                ^

It looks like the compiler infers T:=java.lang.Object&java.io.Serializable&java.lang.Comparable<?>, which leads to the ambiguity when resolving the call among the overloaded version of f().

However, Object and Serializable are no viable options for the type parameter because they are not within the bound of method max().

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile the source code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
error free compilation
ACTUAL -
compile-time error message

ERROR MESSAGES/STACK TRACES THAT OCCUR :
ParameterInference3.java:42: reference to f is ambiguous, both method f(java.lang.Comparable) in generics.ParameterInference3 and method f(java.io.Serializable) in generics.ParameterInference3 match
		f(Utilities.max("abc",new Integer(10)));
                ^

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

package generics;
import java.util.*;
import java.io.Serializable;


public class ParameterInference3 {
	
	private static void f(String s) {
		System.out.println("String");
	}

	private static void f(Integer s) {
		System.out.println("String");
	}

	private static void f(Comparable e) {
		System.out.println("Comparable");
	}

	private static void f(Serializable e) {
		System.out.println("Serializable");
	}

	private static void f(Object e) {
		System.out.println("Object");
	}
	
	
	private static class Utilities {

	  public static <T extends Comparable> T max(T arg1, T arg2) {
	  	return (arg1.compareTo(arg2)>0)?arg1:arg2;
	  }
	}






	public static void main(String[] args) {
		f(Utilities.max("abc",new Integer(10)));
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
explicit type parameter specification

f(Utilities.<Comparable>max("abc",new Integer(10)));
(Incident Review ID: 193183) 
======================================================================

Comments
EVALUATION When a type parameter is not inferred from actual arguments, it can be helpful to inspect the bound of a type parameter (see 6569277). But when a type parameter is inferred but under-constrained (c.f. the intersection type here), I agree with the previous evaluation that using the bound is over-complicated. While the preferred inference for T is obvious in <T extends Comparable<?>>, it is not obvious in general because bounds may depend on each other or have intersection supertypes, e.g. <T extends U, U extends V&W>. Choosing T based on its bound now requires choosing U based on its bound, but U may not be inferred from the actual arguments, etc, etc, etc - the complexity is never-ending.
25-09-2007

PUBLIC COMMENTS In cases where the type inference algorithm is not sophisticated enough to reach the desired conclusion, explicit type arguments can be used.
10-06-2004

EVALUATION The essence of this bug is a request for a smarter inference algorithm. In most cases, inference does not take advantage of knowledge of the bounds of the type parameter being inferred. Inference is a very complex process, and we don't want to make it more complex; there will always be examples that would work with smarter inference. In those cases, we recommend passing type arguments explicitly. ###@###.### 2004-06-04
04-06-2004