1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Jan 18 18:26:36 2012 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jan 24 17:52:02 2012 +0000 1.3 @@ -34,6 +34,7 @@ 1.4 import com.sun.tools.javac.code.Type.*; 1.5 import com.sun.tools.javac.code.Type.ForAll.ConstraintKind; 1.6 import com.sun.tools.javac.code.Symbol.*; 1.7 +import com.sun.tools.javac.comp.Resolve.InapplicableMethodException; 1.8 import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode; 1.9 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 1.10 1.11 @@ -84,7 +85,7 @@ 1.12 1.13 } 1.14 1.15 - public static class InferenceException extends Resolve.InapplicableMethodException { 1.16 + public static class InferenceException extends InapplicableMethodException { 1.17 private static final long serialVersionUID = 0; 1.18 1.19 InferenceException(JCDiagnostic.Factory diags) { 1.20 @@ -287,6 +288,18 @@ 1.21 } 1.22 } 1.23 1.24 + Type asUndetType(Type t, List<Type> undetvars) { 1.25 + return types.subst(t, inferenceVars(undetvars), undetvars); 1.26 + } 1.27 + 1.28 + List<Type> inferenceVars(List<Type> undetvars) { 1.29 + ListBuffer<Type> tvars = ListBuffer.lb(); 1.30 + for (Type uv : undetvars) { 1.31 + tvars.append(((UndetVar)uv).qtype); 1.32 + } 1.33 + return tvars.toList(); 1.34 + } 1.35 + 1.36 /*************************************************************************** 1.37 * Exported Methods 1.38 ***************************************************************************/ 1.39 @@ -372,62 +385,11 @@ 1.40 final Warner warn) throws InferenceException { 1.41 //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG 1.42 List<Type> undetvars = Type.map(tvars, fromTypeVarFun); 1.43 - List<Type> formals = mt.argtypes; 1.44 - //need to capture exactly once - otherwise subsequent 1.45 - //applicability checks might fail 1.46 - final List<Type> capturedArgs = types.capture(argtypes); 1.47 - List<Type> actuals = capturedArgs; 1.48 - List<Type> actualsNoCapture = argtypes; 1.49 - // instantiate all polymorphic argument types and 1.50 - // set up lower bounds constraints for undetvars 1.51 - Type varargsFormal = useVarargs ? formals.last() : null; 1.52 - if (varargsFormal == null && 1.53 - actuals.size() != formals.size()) { 1.54 - throw unambiguousNoInstanceException 1.55 - .setMessage("infer.arg.length.mismatch"); 1.56 - } 1.57 - while (actuals.nonEmpty() && formals.head != varargsFormal) { 1.58 - Type formal = formals.head; 1.59 - Type actual = actuals.head.baseType(); 1.60 - Type actualNoCapture = actualsNoCapture.head.baseType(); 1.61 - if (actual.tag == FORALL) 1.62 - actual = instantiateArg((ForAll)actual, formal, tvars, warn); 1.63 - Type undetFormal = types.subst(formal, tvars, undetvars); 1.64 - boolean works = allowBoxing 1.65 - ? types.isConvertible(actual, undetFormal, warn) 1.66 - : types.isSubtypeUnchecked(actual, undetFormal, warn); 1.67 - if (!works) { 1.68 - throw unambiguousNoInstanceException 1.69 - .setMessage("infer.no.conforming.assignment.exists", 1.70 - tvars, actualNoCapture, formal); 1.71 - } 1.72 - formals = formals.tail; 1.73 - actuals = actuals.tail; 1.74 - actualsNoCapture = actualsNoCapture.tail; 1.75 - } 1.76 + //final List<Type> capturedArgs = types.capture(argtypes); 1.77 1.78 - if (formals.head != varargsFormal) // not enough args 1.79 - throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); 1.80 - 1.81 - // for varargs arguments as well 1.82 - if (useVarargs) { 1.83 - Type elemType = types.elemtype(varargsFormal); 1.84 - Type elemUndet = types.subst(elemType, tvars, undetvars); 1.85 - while (actuals.nonEmpty()) { 1.86 - Type actual = actuals.head.baseType(); 1.87 - Type actualNoCapture = actualsNoCapture.head.baseType(); 1.88 - if (actual.tag == FORALL) 1.89 - actual = instantiateArg((ForAll)actual, elemType, tvars, warn); 1.90 - boolean works = types.isConvertible(actual, elemUndet, warn); 1.91 - if (!works) { 1.92 - throw unambiguousNoInstanceException 1.93 - .setMessage("infer.no.conforming.assignment.exists", 1.94 - tvars, actualNoCapture, elemType); 1.95 - } 1.96 - actuals = actuals.tail; 1.97 - actualsNoCapture = actualsNoCapture.tail; 1.98 - } 1.99 - } 1.100 + final List<Type> capturedArgs = 1.101 + rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(), 1.102 + allowBoxing, useVarargs, warn, new InferenceCheckHandler(undetvars)); 1.103 1.104 // minimize as yet undetermined type variables 1.105 for (Type t : undetvars) 1.106 @@ -503,6 +465,31 @@ 1.107 } 1.108 //where 1.109 1.110 + /** inference check handler **/ 1.111 + class InferenceCheckHandler implements Resolve.MethodCheckHandler { 1.112 + 1.113 + List<Type> undetvars; 1.114 + 1.115 + public InferenceCheckHandler(List<Type> undetvars) { 1.116 + this.undetvars = undetvars; 1.117 + } 1.118 + 1.119 + public InapplicableMethodException arityMismatch() { 1.120 + return unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); 1.121 + } 1.122 + public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) { 1.123 + String key = varargs ? 1.124 + "infer.varargs.argument.mismatch" : 1.125 + "infer.no.conforming.assignment.exists"; 1.126 + return unambiguousNoInstanceException.setMessage(key, 1.127 + inferenceVars(undetvars), found, expected); 1.128 + } 1.129 + public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) { 1.130 + return unambiguousNoInstanceException.setMessage("inaccessible.varargs.type", 1.131 + expected, Kinds.kindName(location), location); 1.132 + } 1.133 + } 1.134 + 1.135 /** 1.136 * A delegated type representing a partially uninferred method type. 1.137 * The return type of a partially uninferred method type is a ForAll 1.138 @@ -572,7 +559,7 @@ 1.139 rs.checkRawArgumentsAcceptable(env, actuals, formals, 1.140 allowBoxing, useVarargs, warn); 1.141 } 1.142 - catch (Resolve.InapplicableMethodException ex) { 1.143 + catch (InapplicableMethodException ex) { 1.144 // inferred method is not applicable 1.145 throw invalidInstanceException.setMessage(ex.getDiagnostic()); 1.146 }