1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri May 25 16:32:56 2012 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu May 31 17:42:14 2012 +0100 1.3 @@ -214,16 +214,23 @@ 1.4 * If no instantiation exists, or if several incomparable 1.5 * best instantiations exist throw a NoInstanceException. 1.6 */ 1.7 - public Type instantiateExpr(ForAll that, 1.8 - Type to, 1.9 + public List<Type> instantiateUninferred(DiagnosticPosition pos, 1.10 + List<Type> undetvars, 1.11 + List<Type> tvars, 1.12 + MethodType mtype, 1.13 + Attr.ResultInfo resultInfo, 1.14 Warner warn) throws InferenceException { 1.15 - List<Type> undetvars = that.undetvars(); 1.16 - Type qtype1 = types.subst(that.qtype, that.tvars, undetvars); 1.17 + Type to = resultInfo.pt; 1.18 + if (to.tag == NONE) { 1.19 + to = mtype.getReturnType().tag <= VOID ? 1.20 + mtype.getReturnType() : syms.objectType; 1.21 + } 1.22 + Type qtype1 = types.subst(mtype.getReturnType(), tvars, undetvars); 1.23 if (!types.isSubtype(qtype1, 1.24 qtype1.tag == UNDETVAR ? types.boxedTypeOrType(to) : to)) { 1.25 throw unambiguousNoInstanceException 1.26 .setMessage("infer.no.conforming.instance.exists", 1.27 - that.tvars, that.qtype, to); 1.28 + tvars, mtype.getReturnType(), to); 1.29 } 1.30 1.31 List<Type> insttypes; 1.32 @@ -232,32 +239,32 @@ 1.33 insttypes = List.nil(); 1.34 for (Type t : undetvars) { 1.35 UndetVar uv = (UndetVar)t; 1.36 - if (uv.inst == null && (uv.eq.nonEmpty() || !Type.containsAny(uv.hibounds, that.tvars))) { 1.37 + if (uv.inst == null && (uv.eq.nonEmpty() || !Type.containsAny(uv.hibounds, tvars))) { 1.38 maximizeInst((UndetVar)t, warn); 1.39 stuck = false; 1.40 } 1.41 insttypes = insttypes.append(uv.inst == null ? uv.qtype : uv.inst); 1.42 } 1.43 - if (!Type.containsAny(insttypes, that.tvars)) { 1.44 + if (!Type.containsAny(insttypes, tvars)) { 1.45 //all variables have been instantiated - exit 1.46 break; 1.47 } else if (stuck) { 1.48 //some variables could not be instantiated because of cycles in 1.49 //upper bounds - provide a (possibly recursive) default instantiation 1.50 insttypes = types.subst(insttypes, 1.51 - that.tvars, 1.52 - instantiateAsUninferredVars(undetvars, that.tvars)); 1.53 + tvars, 1.54 + instantiateAsUninferredVars(undetvars, tvars)); 1.55 break; 1.56 } else { 1.57 //some variables have been instantiated - replace newly instantiated 1.58 //variables in remaining upper bounds and continue 1.59 for (Type t : undetvars) { 1.60 UndetVar uv = (UndetVar)t; 1.61 - uv.hibounds = types.subst(uv.hibounds, that.tvars, insttypes); 1.62 + uv.hibounds = types.subst(uv.hibounds, tvars, insttypes); 1.63 } 1.64 } 1.65 } 1.66 - return that.inst(insttypes, types); 1.67 + return insttypes; 1.68 } 1.69 1.70 /** 1.71 @@ -296,18 +303,19 @@ 1.72 /** Instantiate method type `mt' by finding instantiations of 1.73 * `tvars' so that method can be applied to `argtypes'. 1.74 */ 1.75 - public Type instantiateMethod(final Env<AttrContext> env, 1.76 + public Type instantiateMethod(Env<AttrContext> env, 1.77 List<Type> tvars, 1.78 MethodType mt, 1.79 - final Symbol msym, 1.80 - final List<Type> argtypes, 1.81 - final boolean allowBoxing, 1.82 - final boolean useVarargs, 1.83 - final Warner warn) throws InferenceException { 1.84 + Attr.ResultInfo resultInfo, 1.85 + Symbol msym, 1.86 + List<Type> argtypes, 1.87 + boolean allowBoxing, 1.88 + boolean useVarargs, 1.89 + Warner warn) throws InferenceException { 1.90 //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG 1.91 - final List<Type> undetvars = makeUndetvars(tvars); 1.92 + List<Type> undetvars = makeUndetvars(tvars); 1.93 1.94 - final List<Type> capturedArgs = 1.95 + List<Type> capturedArgs = 1.96 rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(), 1.97 allowBoxing, useVarargs, warn, new InferenceCheckHandler(undetvars)); 1.98 1.99 @@ -344,38 +352,23 @@ 1.100 1.101 mt = (MethodType)types.subst(mt, tvars, insttypes.toList()); 1.102 1.103 - if (!restvars.isEmpty()) { 1.104 - // if there are uninstantiated variables, 1.105 - // quantify result type with them 1.106 - final List<Type> inferredTypes = insttypes.toList(); 1.107 - final List<Type> all_tvars = tvars; //this is the wrong tvars 1.108 - return new UninferredMethodType(env.tree.pos(), msym, mt, restvars.toList()) { 1.109 - @Override 1.110 - List<Type> undetvars() { 1.111 - return restundet.toList(); 1.112 - } 1.113 - @Override 1.114 - void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException { 1.115 - Type owntype = new MethodType(types.subst(getParameterTypes(), tvars, inferred), 1.116 - restype, 1.117 - types.subst(getThrownTypes(), tvars, inferred), 1.118 - qtype.tsym); 1.119 - // check that actuals conform to inferred formals 1.120 - warn.clear(); 1.121 - checkArgumentsAcceptable(env, capturedArgs, owntype.getParameterTypes(), allowBoxing, useVarargs, warn); 1.122 - // check that inferred bounds conform to their bounds 1.123 - checkWithinBounds(all_tvars, undetvars, 1.124 - types.subst(inferredTypes, tvars, inferred), warn); 1.125 - qtype = chk.checkMethod(owntype, msym, env, TreeInfo.args(env.tree), capturedArgs, useVarargs, warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)); 1.126 - } 1.127 - }; 1.128 + if (!restvars.isEmpty() && resultInfo != null) { 1.129 + List<Type> restInferred = 1.130 + instantiateUninferred(env.tree.pos(), restundet.toList(), restvars.toList(), mt, resultInfo, warn); 1.131 + checkWithinBounds(tvars, undetvars, 1.132 + types.subst(insttypes.toList(), restvars.toList(), restInferred), warn); 1.133 + mt = (MethodType)types.subst(mt, restvars.toList(), restInferred); 1.134 + if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { 1.135 + log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt); 1.136 + } 1.137 } 1.138 - else { 1.139 + 1.140 + if (restvars.isEmpty() || resultInfo != null) { 1.141 // check that actuals conform to inferred formals 1.142 checkArgumentsAcceptable(env, capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn); 1.143 - // return instantiated version of method type 1.144 - return mt; 1.145 } 1.146 + // return instantiated version of method type 1.147 + return mt; 1.148 } 1.149 //where 1.150 1.151 @@ -404,60 +397,6 @@ 1.152 } 1.153 } 1.154 1.155 - /** 1.156 - * A delegated type representing a partially uninferred method type. 1.157 - * The return type of a partially uninferred method type is a ForAll 1.158 - * type - when the return type is instantiated (see Infer.instantiateExpr) 1.159 - * the underlying method type is also updated. 1.160 - */ 1.161 - abstract class UninferredMethodType extends DelegatedType { 1.162 - 1.163 - final List<Type> tvars; 1.164 - final Symbol msym; 1.165 - final DiagnosticPosition pos; 1.166 - 1.167 - public UninferredMethodType(DiagnosticPosition pos, Symbol msym, MethodType mtype, List<Type> tvars) { 1.168 - super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym)); 1.169 - this.tvars = tvars; 1.170 - this.msym = msym; 1.171 - this.pos = pos; 1.172 - asMethodType().restype = new UninferredReturnType(tvars, mtype.restype); 1.173 - } 1.174 - 1.175 - @Override 1.176 - public MethodType asMethodType() { 1.177 - return qtype.asMethodType(); 1.178 - } 1.179 - 1.180 - @Override 1.181 - public Type map(Mapping f) { 1.182 - return qtype.map(f); 1.183 - } 1.184 - 1.185 - abstract void instantiateReturnType(Type restype, List<Type> inferred, Types types); 1.186 - 1.187 - abstract List<Type> undetvars(); 1.188 - 1.189 - class UninferredReturnType extends ForAll { 1.190 - public UninferredReturnType(List<Type> tvars, Type restype) { 1.191 - super(tvars, restype); 1.192 - } 1.193 - @Override 1.194 - public Type inst(List<Type> actuals, Types types) { 1.195 - Type newRestype = super.inst(actuals, types); 1.196 - instantiateReturnType(newRestype, actuals, types); 1.197 - if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { 1.198 - log.note(pos, "deferred.method.inst", msym, UninferredMethodType.this.qtype, newRestype); 1.199 - } 1.200 - return UninferredMethodType.this.qtype.getReturnType(); 1.201 - } 1.202 - @Override 1.203 - public List<Type> undetvars() { 1.204 - return UninferredMethodType.this.undetvars(); 1.205 - } 1.206 - } 1.207 - } 1.208 - 1.209 private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals, 1.210 boolean allowBoxing, boolean useVarargs, Warner warn) { 1.211 try {