diff -r 64d41533dc9e -r 532f41763bc9 langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Jan 18 18:26:36 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jan 24 17:52:02 2012 +0000 @@ -34,6 +34,7 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.ForAll.ConstraintKind; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.comp.Resolve.InapplicableMethodException; import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -84,7 +85,7 @@ } - public static class InferenceException extends Resolve.InapplicableMethodException { + public static class InferenceException extends InapplicableMethodException { private static final long serialVersionUID = 0; InferenceException(JCDiagnostic.Factory diags) { @@ -287,6 +288,18 @@ } } + Type asUndetType(Type t, List undetvars) { + return types.subst(t, inferenceVars(undetvars), undetvars); + } + + List inferenceVars(List undetvars) { + ListBuffer tvars = ListBuffer.lb(); + for (Type uv : undetvars) { + tvars.append(((UndetVar)uv).qtype); + } + return tvars.toList(); + } + /*************************************************************************** * Exported Methods ***************************************************************************/ @@ -372,62 +385,11 @@ final Warner warn) throws InferenceException { //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG List undetvars = Type.map(tvars, fromTypeVarFun); - List formals = mt.argtypes; - //need to capture exactly once - otherwise subsequent - //applicability checks might fail - final List capturedArgs = types.capture(argtypes); - List actuals = capturedArgs; - List actualsNoCapture = argtypes; - // instantiate all polymorphic argument types and - // set up lower bounds constraints for undetvars - Type varargsFormal = useVarargs ? formals.last() : null; - if (varargsFormal == null && - actuals.size() != formals.size()) { - throw unambiguousNoInstanceException - .setMessage("infer.arg.length.mismatch"); - } - while (actuals.nonEmpty() && formals.head != varargsFormal) { - Type formal = formals.head; - Type actual = actuals.head.baseType(); - Type actualNoCapture = actualsNoCapture.head.baseType(); - if (actual.tag == FORALL) - actual = instantiateArg((ForAll)actual, formal, tvars, warn); - Type undetFormal = types.subst(formal, tvars, undetvars); - boolean works = allowBoxing - ? types.isConvertible(actual, undetFormal, warn) - : types.isSubtypeUnchecked(actual, undetFormal, warn); - if (!works) { - throw unambiguousNoInstanceException - .setMessage("infer.no.conforming.assignment.exists", - tvars, actualNoCapture, formal); - } - formals = formals.tail; - actuals = actuals.tail; - actualsNoCapture = actualsNoCapture.tail; - } + //final List capturedArgs = types.capture(argtypes); - if (formals.head != varargsFormal) // not enough args - throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); - - // for varargs arguments as well - if (useVarargs) { - Type elemType = types.elemtype(varargsFormal); - Type elemUndet = types.subst(elemType, tvars, undetvars); - while (actuals.nonEmpty()) { - Type actual = actuals.head.baseType(); - Type actualNoCapture = actualsNoCapture.head.baseType(); - if (actual.tag == FORALL) - actual = instantiateArg((ForAll)actual, elemType, tvars, warn); - boolean works = types.isConvertible(actual, elemUndet, warn); - if (!works) { - throw unambiguousNoInstanceException - .setMessage("infer.no.conforming.assignment.exists", - tvars, actualNoCapture, elemType); - } - actuals = actuals.tail; - actualsNoCapture = actualsNoCapture.tail; - } - } + final List capturedArgs = + rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(), + allowBoxing, useVarargs, warn, new InferenceCheckHandler(undetvars)); // minimize as yet undetermined type variables for (Type t : undetvars) @@ -503,6 +465,31 @@ } //where + /** inference check handler **/ + class InferenceCheckHandler implements Resolve.MethodCheckHandler { + + List undetvars; + + public InferenceCheckHandler(List undetvars) { + this.undetvars = undetvars; + } + + public InapplicableMethodException arityMismatch() { + return unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); + } + public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) { + String key = varargs ? + "infer.varargs.argument.mismatch" : + "infer.no.conforming.assignment.exists"; + return unambiguousNoInstanceException.setMessage(key, + inferenceVars(undetvars), found, expected); + } + public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) { + return unambiguousNoInstanceException.setMessage("inaccessible.varargs.type", + expected, Kinds.kindName(location), location); + } + } + /** * A delegated type representing a partially uninferred method type. * The return type of a partially uninferred method type is a ForAll @@ -572,7 +559,7 @@ rs.checkRawArgumentsAcceptable(env, actuals, formals, allowBoxing, useVarargs, warn); } - catch (Resolve.InapplicableMethodException ex) { + catch (InapplicableMethodException ex) { // inferred method is not applicable throw invalidInstanceException.setMessage(ex.getDiagnostic()); }