Tue, 12 Feb 2013 19:25:09 +0000
8007464: Add graph inference support
Summary: Add support for more aggressive type-inference scheme
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java Tue Feb 12 13:36:56 2013 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Tue Feb 12 19:25:09 2013 +0000 1.3 @@ -221,7 +221,7 @@ 1.4 public boolean allowIntersectionTypesInCast() { 1.5 return compareTo(JDK1_8) >= 0; 1.6 } 1.7 - public boolean allowEarlyReturnConstraints() { 1.8 + public boolean allowGraphInference() { 1.9 return compareTo(JDK1_8) >= 0; 1.10 } 1.11 public boolean allowStructuralMostSpecific() {
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Feb 12 13:36:56 2013 +0000 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Feb 12 19:25:09 2013 +0000 2.3 @@ -4152,7 +4152,9 @@ 2.4 } 2.5 2.6 private Type capture(Type type) { 2.7 - return types.capture(type); 2.8 + //do not capture free types 2.9 + return resultInfo.checkContext.inferenceContext().free(type) ? 2.10 + type : types.capture(type); 2.11 } 2.12 2.13 private void validateTypeAnnotations(JCTree tree) {
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Feb 12 13:36:56 2013 +0000 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Feb 12 19:25:09 2013 +0000 3.3 @@ -234,7 +234,7 @@ 3.4 dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase); 3.5 return speculativeTree.type; 3.6 case CHECK: 3.7 - Assert.check(dt.mode == AttrMode.SPECULATIVE); 3.8 + Assert.check(dt.mode != null); 3.9 return attr.attribTree(dt.tree, dt.env, resultInfo); 3.10 } 3.11 Assert.error(); 3.12 @@ -242,6 +242,13 @@ 3.13 } 3.14 }; 3.15 3.16 + DeferredTypeCompleter dummyCompleter = new DeferredTypeCompleter() { 3.17 + public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { 3.18 + Assert.check(deferredAttrContext.mode == AttrMode.CHECK); 3.19 + return dt.tree.type = Type.noType; 3.20 + } 3.21 + }; 3.22 + 3.23 /** 3.24 * The 'mode' in which the deferred type is to be type-checked 3.25 */ 3.26 @@ -382,7 +389,7 @@ 3.27 if (!progress) { 3.28 //remove all variables that have already been instantiated 3.29 //from the list of stuck variables 3.30 - inferenceContext.solveAny(inferenceContext.freeVarsIn(List.from(stuckVars))); 3.31 + inferenceContext.solveAny(List.from(stuckVars), warn); 3.32 inferenceContext.notifyChange(); 3.33 } 3.34 } 3.35 @@ -431,7 +438,15 @@ 3.36 return true; 3.37 case CHECK: 3.38 if (stuckVars.nonEmpty()) { 3.39 - return false; 3.40 + //stuck expression - see if we can propagate 3.41 + if (deferredAttrContext.parent != emptyDeferredAttrContext && 3.42 + Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, List.from(stuckVars))) { 3.43 + deferredAttrContext.parent.deferredAttrNodes.add(this); 3.44 + dt.check(resultInfo, List.<Type>nil(), dummyCompleter); 3.45 + return true; 3.46 + } else { 3.47 + return false; 3.48 + } 3.49 } else { 3.50 dt.check(resultInfo, stuckVars, basicCompleter); 3.51 return true;
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Feb 12 13:36:56 2013 +0000 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Feb 12 19:25:09 2013 +0000 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -25,22 +25,30 @@ 4.11 4.12 package com.sun.tools.javac.comp; 4.13 4.14 -import com.sun.tools.javac.code.*; 4.15 -import com.sun.tools.javac.code.Symbol.*; 4.16 -import com.sun.tools.javac.code.Type.*; 4.17 -import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; 4.18 -import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 4.19 -import com.sun.tools.javac.comp.Resolve.InapplicableMethodException; 4.20 -import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode; 4.21 import com.sun.tools.javac.tree.JCTree; 4.22 import com.sun.tools.javac.tree.JCTree.JCTypeCast; 4.23 import com.sun.tools.javac.tree.TreeInfo; 4.24 import com.sun.tools.javac.util.*; 4.25 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 4.26 import com.sun.tools.javac.util.List; 4.27 -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 4.28 +import com.sun.tools.javac.code.*; 4.29 +import com.sun.tools.javac.code.Type.*; 4.30 +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; 4.31 +import com.sun.tools.javac.code.Symbol.*; 4.32 +import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 4.33 +import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph; 4.34 +import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node; 4.35 +import com.sun.tools.javac.comp.Resolve.InapplicableMethodException; 4.36 +import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode; 4.37 4.38 import java.util.HashMap; 4.39 import java.util.Map; 4.40 +import java.util.Set; 4.41 + 4.42 +import java.util.ArrayList; 4.43 +import java.util.Collections; 4.44 +import java.util.EnumSet; 4.45 +import java.util.HashSet; 4.46 4.47 import static com.sun.tools.javac.code.TypeTag.*; 4.48 4.49 @@ -55,19 +63,15 @@ 4.50 protected static final Context.Key<Infer> inferKey = 4.51 new Context.Key<Infer>(); 4.52 4.53 - /** A value for prototypes that admit any type, including polymorphic ones. */ 4.54 - public static final Type anyPoly = new Type(NONE, null); 4.55 - 4.56 + Resolve rs; 4.57 + Check chk; 4.58 Symtab syms; 4.59 Types types; 4.60 - Check chk; 4.61 - Resolve rs; 4.62 - DeferredAttr deferredAttr; 4.63 + JCDiagnostic.Factory diags; 4.64 Log log; 4.65 - JCDiagnostic.Factory diags; 4.66 4.67 - /** Should we inject return-type constraints earlier? */ 4.68 - boolean allowEarlyReturnConstraints; 4.69 + /** should the graph solver be used? */ 4.70 + boolean allowGraphInference; 4.71 4.72 public static Infer instance(Context context) { 4.73 Infer instance = context.get(inferKey); 4.74 @@ -78,17 +82,22 @@ 4.75 4.76 protected Infer(Context context) { 4.77 context.put(inferKey, this); 4.78 + 4.79 + rs = Resolve.instance(context); 4.80 + chk = Check.instance(context); 4.81 syms = Symtab.instance(context); 4.82 types = Types.instance(context); 4.83 - rs = Resolve.instance(context); 4.84 - deferredAttr = DeferredAttr.instance(context); 4.85 + diags = JCDiagnostic.Factory.instance(context); 4.86 log = Log.instance(context); 4.87 - chk = Check.instance(context); 4.88 - diags = JCDiagnostic.Factory.instance(context); 4.89 inferenceException = new InferenceException(diags); 4.90 - allowEarlyReturnConstraints = Source.instance(context).allowEarlyReturnConstraints(); 4.91 + Options options = Options.instance(context); 4.92 + allowGraphInference = Source.instance(context).allowGraphInference() 4.93 + && options.isUnset("useLegacyInference"); 4.94 } 4.95 4.96 + /** A value for prototypes that admit any type, including polymorphic ones. */ 4.97 + public static final Type anyPoly = new Type(NONE, null); 4.98 + 4.99 /** 4.100 * This exception class is design to store a list of diagnostics corresponding 4.101 * to inference errors that can arise during a method applicability check. 4.102 @@ -118,140 +127,12 @@ 4.103 } 4.104 } 4.105 4.106 - final InferenceException inferenceException; 4.107 + protected final InferenceException inferenceException; 4.108 4.109 -/*************************************************************************** 4.110 - * Mini/Maximization of UndetVars 4.111 - ***************************************************************************/ 4.112 - 4.113 - /** Instantiate undetermined type variable to its minimal upper bound. 4.114 - * Throw a NoInstanceException if this not possible. 4.115 - */ 4.116 - void maximizeInst(UndetVar that, Warner warn) throws InferenceException { 4.117 - List<Type> hibounds = Type.filter(that.getBounds(InferenceBound.UPPER), boundFilter); 4.118 - if (that.getBounds(InferenceBound.EQ).isEmpty()) { 4.119 - if (hibounds.isEmpty()) 4.120 - that.inst = syms.objectType; 4.121 - else if (hibounds.tail.isEmpty()) 4.122 - that.inst = hibounds.head; 4.123 - else 4.124 - that.inst = types.glb(hibounds); 4.125 - } else { 4.126 - that.inst = that.getBounds(InferenceBound.EQ).head; 4.127 - } 4.128 - if (that.inst == null || 4.129 - that.inst.isErroneous()) 4.130 - throw inferenceException 4.131 - .setMessage("no.unique.maximal.instance.exists", 4.132 - that.qtype, hibounds); 4.133 - } 4.134 - 4.135 - private Filter<Type> boundFilter = new Filter<Type>() { 4.136 - @Override 4.137 - public boolean accepts(Type t) { 4.138 - return !t.isErroneous() && !t.hasTag(BOT); 4.139 - } 4.140 - }; 4.141 - 4.142 - /** Instantiate undetermined type variable to the lub of all its lower bounds. 4.143 - * Throw a NoInstanceException if this not possible. 4.144 - */ 4.145 - void minimizeInst(UndetVar that, Warner warn) throws InferenceException { 4.146 - List<Type> lobounds = Type.filter(that.getBounds(InferenceBound.LOWER), boundFilter); 4.147 - if (that.getBounds(InferenceBound.EQ).isEmpty()) { 4.148 - if (lobounds.isEmpty()) { 4.149 - //do nothing - the inference variable is under-constrained 4.150 - return; 4.151 - } else if (lobounds.tail.isEmpty()) 4.152 - that.inst = lobounds.head.isPrimitive() ? syms.errType : lobounds.head; 4.153 - else { 4.154 - that.inst = types.lub(lobounds); 4.155 - } 4.156 - if (that.inst == null || that.inst.hasTag(ERROR)) 4.157 - throw inferenceException 4.158 - .setMessage("no.unique.minimal.instance.exists", 4.159 - that.qtype, lobounds); 4.160 - } else { 4.161 - that.inst = that.getBounds(InferenceBound.EQ).head; 4.162 - } 4.163 - } 4.164 - 4.165 -/*************************************************************************** 4.166 - * Exported Methods 4.167 - ***************************************************************************/ 4.168 - 4.169 + // <editor-fold defaultstate="collapsed" desc="Inference routines"> 4.170 /** 4.171 - * Instantiate uninferred inference variables (JLS 15.12.2.8). First 4.172 - * if the method return type is non-void, we derive constraints from the 4.173 - * expected type - then we use declared bound well-formedness to derive additional 4.174 - * constraints. If no instantiation exists, or if several incomparable 4.175 - * best instantiations exist throw a NoInstanceException. 4.176 - */ 4.177 - public void instantiateUninferred(DiagnosticPosition pos, 4.178 - InferenceContext inferenceContext, 4.179 - MethodType mtype, 4.180 - Attr.ResultInfo resultInfo, 4.181 - Warner warn) throws InferenceException { 4.182 - while (true) { 4.183 - boolean stuck = true; 4.184 - for (Type t : inferenceContext.undetvars) { 4.185 - UndetVar uv = (UndetVar)t; 4.186 - if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() || 4.187 - !inferenceContext.free(uv.getBounds(InferenceBound.UPPER)))) { 4.188 - maximizeInst((UndetVar)t, warn); 4.189 - stuck = false; 4.190 - } 4.191 - } 4.192 - if (inferenceContext.restvars().isEmpty()) { 4.193 - //all variables have been instantiated - exit 4.194 - break; 4.195 - } else if (stuck) { 4.196 - //some variables could not be instantiated because of cycles in 4.197 - //upper bounds - provide a (possibly recursive) default instantiation 4.198 - instantiateAsUninferredVars(inferenceContext); 4.199 - break; 4.200 - } else { 4.201 - //some variables have been instantiated - replace newly instantiated 4.202 - //variables in remaining upper bounds and continue 4.203 - for (Type t : inferenceContext.undetvars) { 4.204 - UndetVar uv = (UndetVar)t; 4.205 - uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types); 4.206 - } 4.207 - } 4.208 - } 4.209 - } 4.210 - 4.211 - /** 4.212 - * Infer cyclic inference variables as described in 15.12.2.8. 4.213 - */ 4.214 - private void instantiateAsUninferredVars(InferenceContext inferenceContext) { 4.215 - ListBuffer<Type> todo = ListBuffer.lb(); 4.216 - //step 1 - create fresh tvars 4.217 - for (Type t : inferenceContext.undetvars) { 4.218 - UndetVar uv = (UndetVar)t; 4.219 - if (uv.inst == null) { 4.220 - TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner); 4.221 - fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null); 4.222 - todo.append(uv); 4.223 - uv.inst = fresh_tvar.type; 4.224 - } 4.225 - } 4.226 - //step 2 - replace fresh tvars in their bounds 4.227 - List<Type> formals = inferenceContext.inferenceVars(); 4.228 - for (Type t : todo) { 4.229 - UndetVar uv = (UndetVar)t; 4.230 - TypeVar ct = (TypeVar)uv.inst; 4.231 - ct.bound = types.glb(inferenceContext.asInstTypes(types.getBounds(ct))); 4.232 - if (ct.bound.isErroneous()) { 4.233 - //report inference error if glb fails 4.234 - reportBoundError(uv, BoundErrorKind.BAD_UPPER); 4.235 - } 4.236 - formals = formals.tail; 4.237 - } 4.238 - } 4.239 - 4.240 - /** Instantiate a generic method type by finding instantiations for all its 4.241 - * inference variables so that it can be applied to a given argument type list. 4.242 + * Main inference entry point - instantiate a generic method type 4.243 + * using given argument types and (possibly) an expected target-type. 4.244 */ 4.245 public Type instantiateMethod(Env<AttrContext> env, 4.246 List<Type> tvars, 4.247 @@ -267,259 +148,144 @@ 4.248 //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG 4.249 final InferenceContext inferenceContext = new InferenceContext(tvars); 4.250 inferenceException.clear(); 4.251 + try { 4.252 + DeferredAttr.DeferredAttrContext deferredAttrContext = 4.253 + resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn); 4.254 4.255 - DeferredAttr.DeferredAttrContext deferredAttrContext = 4.256 - resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn); 4.257 + methodCheck.argumentsAcceptable(env, deferredAttrContext, 4.258 + argtypes, mt.getParameterTypes(), warn); 4.259 4.260 - try { 4.261 - methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn); 4.262 - 4.263 - if (resultInfo != null && allowEarlyReturnConstraints && 4.264 + if (allowGraphInference && 4.265 + resultInfo != null && 4.266 !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { 4.267 - generateReturnConstraints(mt, inferenceContext, resultInfo); 4.268 + //inject return constraints earlier 4.269 + checkWithinBounds(inferenceContext, warn); //propagation 4.270 + generateReturnConstraints(resultInfo, mt, inferenceContext); 4.271 + //propagate outwards if needed 4.272 + if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) { 4.273 + //propagate inference context outwards and exit 4.274 + inferenceContext.dupTo(resultInfo.checkContext.inferenceContext()); 4.275 + deferredAttrContext.complete(); 4.276 + return mt; 4.277 + } 4.278 } 4.279 4.280 deferredAttrContext.complete(); 4.281 4.282 // minimize as yet undetermined type variables 4.283 - for (Type t : inferenceContext.undetvars) { 4.284 - minimizeInst((UndetVar)t, warn); 4.285 + if (allowGraphInference) { 4.286 + inferenceContext.solve(warn); 4.287 + } else { 4.288 + inferenceContext.solveLegacy(true, warn, LegacyInferenceSteps.EQ_LOWER.steps); //minimizeInst 4.289 } 4.290 4.291 - checkWithinBounds(inferenceContext, warn); 4.292 - 4.293 mt = (MethodType)inferenceContext.asInstType(mt); 4.294 4.295 - List<Type> restvars = inferenceContext.restvars(); 4.296 + if (!allowGraphInference && 4.297 + inferenceContext.restvars().nonEmpty() && 4.298 + resultInfo != null && 4.299 + !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { 4.300 + generateReturnConstraints(resultInfo, mt, inferenceContext); 4.301 + inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst 4.302 + mt = (MethodType)inferenceContext.asInstType(mt); 4.303 + } 4.304 4.305 - if (!restvars.isEmpty()) { 4.306 - if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { 4.307 - if (!allowEarlyReturnConstraints) { 4.308 - generateReturnConstraints(mt, inferenceContext, resultInfo); 4.309 - } 4.310 - instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn); 4.311 - checkWithinBounds(inferenceContext, warn); 4.312 - mt = (MethodType)inferenceContext.asInstType(mt); 4.313 - if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { 4.314 - log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt); 4.315 - } 4.316 - } 4.317 + if (resultInfo != null && rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { 4.318 + log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt); 4.319 } 4.320 4.321 // return instantiated version of method type 4.322 return mt; 4.323 } finally { 4.324 - inferenceContext.notifyChange(); 4.325 - } 4.326 - } 4.327 - //where 4.328 - void generateReturnConstraints(Type mt, InferenceContext inferenceContext, Attr.ResultInfo resultInfo) { 4.329 - if (resultInfo != null) { 4.330 - Type to = resultInfo.pt; 4.331 - if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) { 4.332 - to = mt.getReturnType().isPrimitiveOrVoid() ? 4.333 - mt.getReturnType() : syms.objectType; 4.334 - } 4.335 - Type qtype1 = inferenceContext.asFree(mt.getReturnType()); 4.336 - Warner retWarn = new Warner(); 4.337 - if (!resultInfo.checkContext.compatible(qtype1, qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to, retWarn) || 4.338 - //unchecked conversion is not allowed 4.339 - retWarn.hasLint(Lint.LintCategory.UNCHECKED)) { 4.340 - throw inferenceException 4.341 - .setMessage("infer.no.conforming.instance.exists", 4.342 - inferenceContext.restvars(), mt.getReturnType(), to); 4.343 - } 4.344 - } 4.345 - } 4.346 - 4.347 - /** check that type parameters are within their bounds. 4.348 - */ 4.349 - void checkWithinBounds(InferenceContext inferenceContext, 4.350 - Warner warn) throws InferenceException { 4.351 - //step 1 - check compatibility of instantiated type w.r.t. initial bounds 4.352 - for (Type t : inferenceContext.undetvars) { 4.353 - UndetVar uv = (UndetVar)t; 4.354 - uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types); 4.355 - checkCompatibleUpperBounds(uv, inferenceContext.inferenceVars()); 4.356 - if (!inferenceContext.restvars().contains(uv.qtype)) { 4.357 - Type inst = inferenceContext.asInstType(t); 4.358 - for (Type u : uv.getBounds(InferenceBound.UPPER)) { 4.359 - if (!types.isSubtypeUnchecked(inst, inferenceContext.asFree(u), warn)) { 4.360 - reportBoundError(uv, BoundErrorKind.UPPER); 4.361 - } 4.362 - } 4.363 - for (Type l : uv.getBounds(InferenceBound.LOWER)) { 4.364 - Assert.check(!inferenceContext.free(l)); 4.365 - if (!types.isSubtypeUnchecked(l, inst, warn)) { 4.366 - reportBoundError(uv, BoundErrorKind.LOWER); 4.367 - } 4.368 - } 4.369 - for (Type e : uv.getBounds(InferenceBound.EQ)) { 4.370 - Assert.check(!inferenceContext.free(e)); 4.371 - if (!types.isSameType(inst, e)) { 4.372 - reportBoundError(uv, BoundErrorKind.EQ); 4.373 - } 4.374 - } 4.375 - } 4.376 - } 4.377 - 4.378 - //step 2 - check that eq bounds are consistent w.r.t. eq/lower bounds 4.379 - for (Type t : inferenceContext.undetvars) { 4.380 - UndetVar uv = (UndetVar)t; 4.381 - //check eq bounds consistency 4.382 - Type eq = null; 4.383 - for (Type e : uv.getBounds(InferenceBound.EQ)) { 4.384 - Assert.check(!inferenceContext.free(e)); 4.385 - if (eq != null && !types.isSameType(e, eq)) { 4.386 - reportBoundError(uv, BoundErrorKind.EQ); 4.387 - } 4.388 - eq = e; 4.389 - for (Type l : uv.getBounds(InferenceBound.LOWER)) { 4.390 - Assert.check(!inferenceContext.free(l)); 4.391 - if (!types.isSubtypeUnchecked(l, e, warn)) { 4.392 - reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); 4.393 - } 4.394 - } 4.395 - for (Type u : uv.getBounds(InferenceBound.UPPER)) { 4.396 - if (inferenceContext.free(u)) continue; 4.397 - if (!types.isSubtypeUnchecked(e, u, warn)) { 4.398 - reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); 4.399 - } 4.400 - } 4.401 + if (resultInfo != null || !allowGraphInference) { 4.402 + inferenceContext.notifyChange(); 4.403 + } else { 4.404 + inferenceContext.notifyChange(inferenceContext.boundedVars()); 4.405 } 4.406 } 4.407 } 4.408 4.409 - void checkCompatibleUpperBounds(UndetVar uv, List<Type> tvars) { 4.410 - // VGJ: sort of inlined maximizeInst() below. Adding 4.411 - // bounds can cause lobounds that are above hibounds. 4.412 - ListBuffer<Type> hiboundsNoVars = ListBuffer.lb(); 4.413 - for (Type t : Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter)) { 4.414 - if (!t.containsAny(tvars)) { 4.415 - hiboundsNoVars.append(t); 4.416 + /** 4.417 + * Generate constraints from the generic method's return type. If the method 4.418 + * call occurs in a context where a type T is expected, use the expected 4.419 + * type to derive more constraints on the generic method inference variables. 4.420 + */ 4.421 + void generateReturnConstraints(Attr.ResultInfo resultInfo, 4.422 + MethodType mt, InferenceContext inferenceContext) { 4.423 + Type qtype1 = inferenceContext.asFree(mt.getReturnType()); 4.424 + Type to = returnConstraintTarget(qtype1, resultInfo.pt); 4.425 + Assert.check(allowGraphInference || !resultInfo.checkContext.inferenceContext().free(to), 4.426 + "legacy inference engine cannot handle constraints on both sides of a subtyping assertion"); 4.427 + //we need to skip capture? 4.428 + Warner retWarn = new Warner(); 4.429 + if (!resultInfo.checkContext.compatible(qtype1, resultInfo.checkContext.inferenceContext().asFree(to), retWarn) || 4.430 + //unchecked conversion is not allowed 4.431 + retWarn.hasLint(Lint.LintCategory.UNCHECKED)) { 4.432 + throw inferenceException 4.433 + .setMessage("infer.no.conforming.instance.exists", 4.434 + inferenceContext.restvars(), mt.getReturnType(), to); 4.435 + } 4.436 + } 4.437 + //where 4.438 + private Type returnConstraintTarget(Type from, Type to) { 4.439 + if (from.hasTag(VOID)) { 4.440 + return syms.voidType; 4.441 + } else if (to.hasTag(NONE)) { 4.442 + return from.isPrimitive() ? from : syms.objectType; 4.443 + } else if (from.hasTag(UNDETVAR) && to.isPrimitive()) { 4.444 + if (!allowGraphInference) { 4.445 + //if legacy, just return boxed type 4.446 + return types.boxedClass(to).type; 4.447 + } 4.448 + //if graph inference we need to skip conflicting boxed bounds... 4.449 + UndetVar uv = (UndetVar)from; 4.450 + for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) { 4.451 + Type boundAsPrimitive = types.unboxedType(t); 4.452 + if (boundAsPrimitive == null) continue; 4.453 + if (types.isConvertible(boundAsPrimitive, to)) { 4.454 + //effectively skip return-type constraint generation (compatibility) 4.455 + return syms.objectType; 4.456 + } 4.457 + } 4.458 + return types.boxedClass(to).type; 4.459 + } else { 4.460 + return to; 4.461 } 4.462 } 4.463 - List<Type> hibounds = hiboundsNoVars.toList(); 4.464 - Type hb = null; 4.465 - if (hibounds.isEmpty()) 4.466 - hb = syms.objectType; 4.467 - else if (hibounds.tail.isEmpty()) 4.468 - hb = hibounds.head; 4.469 - else 4.470 - hb = types.glb(hibounds); 4.471 - if (hb == null || hb.isErroneous()) 4.472 - reportBoundError(uv, BoundErrorKind.BAD_UPPER); 4.473 - } 4.474 4.475 - enum BoundErrorKind { 4.476 - BAD_UPPER() { 4.477 - @Override 4.478 - InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.479 - return ex.setMessage("incompatible.upper.bounds", uv.qtype, 4.480 - uv.getBounds(InferenceBound.UPPER)); 4.481 + /** 4.482 + * Infer cyclic inference variables as described in 15.12.2.8. 4.483 + */ 4.484 + private void instantiateAsUninferredVars(List<Type> vars, InferenceContext inferenceContext) { 4.485 + ListBuffer<Type> todo = ListBuffer.lb(); 4.486 + //step 1 - create fresh tvars 4.487 + for (Type t : vars) { 4.488 + UndetVar uv = (UndetVar)inferenceContext.asFree(t); 4.489 + List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER); 4.490 + if (Type.containsAny(upperBounds, vars)) { 4.491 + TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner); 4.492 + fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null); 4.493 + todo.append(uv); 4.494 + uv.inst = fresh_tvar.type; 4.495 + } else if (upperBounds.nonEmpty()) { 4.496 + uv.inst = types.glb(upperBounds); 4.497 + } else { 4.498 + uv.inst = syms.objectType; 4.499 } 4.500 - }, 4.501 - BAD_EQ_UPPER() { 4.502 - @Override 4.503 - InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.504 - return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype, 4.505 - uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER)); 4.506 + } 4.507 + //step 2 - replace fresh tvars in their bounds 4.508 + List<Type> formals = vars; 4.509 + for (Type t : todo) { 4.510 + UndetVar uv = (UndetVar)t; 4.511 + TypeVar ct = (TypeVar)uv.inst; 4.512 + ct.bound = types.glb(inferenceContext.asInstTypes(types.getBounds(ct))); 4.513 + if (ct.bound.isErroneous()) { 4.514 + //report inference error if glb fails 4.515 + reportBoundError(uv, BoundErrorKind.BAD_UPPER); 4.516 } 4.517 - }, 4.518 - BAD_EQ_LOWER() { 4.519 - @Override 4.520 - InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.521 - return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype, 4.522 - uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER)); 4.523 - } 4.524 - }, 4.525 - UPPER() { 4.526 - @Override 4.527 - InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.528 - return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst, 4.529 - uv.getBounds(InferenceBound.UPPER)); 4.530 - } 4.531 - }, 4.532 - LOWER() { 4.533 - @Override 4.534 - InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.535 - return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst, 4.536 - uv.getBounds(InferenceBound.LOWER)); 4.537 - } 4.538 - }, 4.539 - EQ() { 4.540 - @Override 4.541 - InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.542 - return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst, 4.543 - uv.getBounds(InferenceBound.EQ)); 4.544 - } 4.545 - }; 4.546 - 4.547 - abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv); 4.548 - } 4.549 - //where 4.550 - void reportBoundError(UndetVar uv, BoundErrorKind bk) { 4.551 - throw bk.setMessage(inferenceException, uv); 4.552 - } 4.553 - 4.554 - // <editor-fold desc="functional interface instantiation"> 4.555 - /** 4.556 - * This method is used to infer a suitable target functional interface in case 4.557 - * the original parameterized interface contains wildcards. An inference process 4.558 - * is applied so that wildcard bounds, as well as explicit lambda/method ref parameters 4.559 - * (where applicable) are used to constraint the solution. 4.560 - */ 4.561 - public Type instantiateFunctionalInterface(DiagnosticPosition pos, Type funcInterface, 4.562 - List<Type> paramTypes, Check.CheckContext checkContext) { 4.563 - if (types.capture(funcInterface) == funcInterface) { 4.564 - //if capture doesn't change the type then return the target unchanged 4.565 - //(this means the target contains no wildcards!) 4.566 - return funcInterface; 4.567 - } else { 4.568 - Type formalInterface = funcInterface.tsym.type; 4.569 - InferenceContext funcInterfaceContext = 4.570 - new InferenceContext(funcInterface.tsym.type.getTypeArguments()); 4.571 - Assert.check(paramTypes != null); 4.572 - //get constraints from explicit params (this is done by 4.573 - //checking that explicit param types are equal to the ones 4.574 - //in the functional interface descriptors) 4.575 - List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes(); 4.576 - if (descParameterTypes.size() != paramTypes.size()) { 4.577 - checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda")); 4.578 - return types.createErrorType(funcInterface); 4.579 - } 4.580 - for (Type p : descParameterTypes) { 4.581 - if (!types.isSameType(funcInterfaceContext.asFree(p), paramTypes.head)) { 4.582 - checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); 4.583 - return types.createErrorType(funcInterface); 4.584 - } 4.585 - paramTypes = paramTypes.tail; 4.586 - } 4.587 - List<Type> actualTypeargs = funcInterface.getTypeArguments(); 4.588 - for (Type t : funcInterfaceContext.undetvars) { 4.589 - UndetVar uv = (UndetVar)t; 4.590 - if (funcInterfaceContext.boundedVars().contains(uv.qtype)) { 4.591 - minimizeInst(uv, types.noWarnings); 4.592 - if (uv.inst == null && 4.593 - Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) { 4.594 - maximizeInst(uv, types.noWarnings); 4.595 - } 4.596 - } else { 4.597 - uv.inst = actualTypeargs.head; 4.598 - } 4.599 - Assert.check(uv.inst != null); 4.600 - actualTypeargs = actualTypeargs.tail; 4.601 - } 4.602 - Type owntype = funcInterfaceContext.asInstType(formalInterface); 4.603 - if (!chk.checkValidGenericType(owntype)) { 4.604 - //if the inferred functional interface type is not well-formed, 4.605 - //or if it's not a subtype of the original target, issue an error 4.606 - checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); 4.607 - } 4.608 - return owntype; 4.609 + formals = formals.tail; 4.610 } 4.611 } 4.612 - // </editor-fold> 4.613 4.614 /** 4.615 * Compute a synthetic method type corresponding to the requested polymorphic 4.616 @@ -573,7 +339,7 @@ 4.617 class ImplicitArgType extends DeferredAttr.DeferredTypeMap { 4.618 4.619 public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) { 4.620 - deferredAttr.super(AttrMode.SPECULATIVE, msym, phase); 4.621 + rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase); 4.622 } 4.623 4.624 public Type apply(Type t) { 4.625 @@ -587,6 +353,920 @@ 4.626 } 4.627 4.628 /** 4.629 + * This method is used to infer a suitable target SAM in case the original 4.630 + * SAM type contains one or more wildcards. An inference process is applied 4.631 + * so that wildcard bounds, as well as explicit lambda/method ref parameters 4.632 + * (where applicable) are used to constraint the solution. 4.633 + */ 4.634 + public Type instantiateFunctionalInterface(DiagnosticPosition pos, Type funcInterface, 4.635 + List<Type> paramTypes, Check.CheckContext checkContext) { 4.636 + if (types.capture(funcInterface) == funcInterface) { 4.637 + //if capture doesn't change the type then return the target unchanged 4.638 + //(this means the target contains no wildcards!) 4.639 + return funcInterface; 4.640 + } else { 4.641 + Type formalInterface = funcInterface.tsym.type; 4.642 + InferenceContext funcInterfaceContext = 4.643 + new InferenceContext(funcInterface.tsym.type.getTypeArguments()); 4.644 + 4.645 + Assert.check(paramTypes != null); 4.646 + //get constraints from explicit params (this is done by 4.647 + //checking that explicit param types are equal to the ones 4.648 + //in the functional interface descriptors) 4.649 + List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes(); 4.650 + if (descParameterTypes.size() != paramTypes.size()) { 4.651 + checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda")); 4.652 + return types.createErrorType(funcInterface); 4.653 + } 4.654 + for (Type p : descParameterTypes) { 4.655 + if (!types.isSameType(funcInterfaceContext.asFree(p), paramTypes.head)) { 4.656 + checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); 4.657 + return types.createErrorType(funcInterface); 4.658 + } 4.659 + paramTypes = paramTypes.tail; 4.660 + } 4.661 + 4.662 + try { 4.663 + funcInterfaceContext.solve(funcInterfaceContext.boundedVars(), types.noWarnings); 4.664 + } catch (InferenceException ex) { 4.665 + checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); 4.666 + } 4.667 + 4.668 + List<Type> actualTypeargs = funcInterface.getTypeArguments(); 4.669 + for (Type t : funcInterfaceContext.undetvars) { 4.670 + UndetVar uv = (UndetVar)t; 4.671 + if (uv.inst == null) { 4.672 + uv.inst = actualTypeargs.head; 4.673 + } 4.674 + actualTypeargs = actualTypeargs.tail; 4.675 + } 4.676 + 4.677 + Type owntype = funcInterfaceContext.asInstType(formalInterface); 4.678 + if (!chk.checkValidGenericType(owntype)) { 4.679 + //if the inferred functional interface type is not well-formed, 4.680 + //or if it's not a subtype of the original target, issue an error 4.681 + checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); 4.682 + } 4.683 + return owntype; 4.684 + } 4.685 + } 4.686 + // </editor-fold> 4.687 + 4.688 + // <editor-fold defaultstate="collapsed" desc="Bound checking"> 4.689 + /** 4.690 + * Check bounds and perform incorporation 4.691 + */ 4.692 + void checkWithinBounds(InferenceContext inferenceContext, 4.693 + Warner warn) throws InferenceException { 4.694 + MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars); 4.695 + try { 4.696 + while (true) { 4.697 + mlistener.reset(); 4.698 + if (!allowGraphInference) { 4.699 + //in legacy mode we lack of transitivity, so bound check 4.700 + //cannot be run in parallel with other incoprporation rounds 4.701 + for (Type t : inferenceContext.undetvars) { 4.702 + UndetVar uv = (UndetVar)t; 4.703 + IncorporationStep.CHECK_BOUNDS.apply(uv, inferenceContext, warn); 4.704 + } 4.705 + } 4.706 + for (Type t : inferenceContext.undetvars) { 4.707 + UndetVar uv = (UndetVar)t; 4.708 + //bound incorporation 4.709 + EnumSet<IncorporationStep> incorporationSteps = allowGraphInference ? 4.710 + incorporationStepsGraph : incorporationStepsLegacy; 4.711 + for (IncorporationStep is : incorporationSteps) { 4.712 + is.apply(uv, inferenceContext, warn); 4.713 + } 4.714 + } 4.715 + if (!mlistener.changed || !allowGraphInference) break; 4.716 + } 4.717 + } 4.718 + finally { 4.719 + mlistener.detach(); 4.720 + } 4.721 + } 4.722 + //where 4.723 + /** 4.724 + * This listener keeps track of changes on a group of inference variable 4.725 + * bounds. Note: the listener must be detached (calling corresponding 4.726 + * method) to make sure that the underlying inference variable is 4.727 + * left in a clean state. 4.728 + */ 4.729 + class MultiUndetVarListener implements UndetVar.UndetVarListener { 4.730 + 4.731 + int rounds; 4.732 + boolean changed; 4.733 + List<Type> undetvars; 4.734 + 4.735 + public MultiUndetVarListener(List<Type> undetvars) { 4.736 + this.undetvars = undetvars; 4.737 + for (Type t : undetvars) { 4.738 + UndetVar uv = (UndetVar)t; 4.739 + uv.listener = this; 4.740 + } 4.741 + } 4.742 + 4.743 + public void varChanged(UndetVar uv, Set<InferenceBound> ibs) { 4.744 + //avoid non-termination 4.745 + if (rounds < MAX_INCORPORATION_STEPS) { 4.746 + changed = true; 4.747 + } 4.748 + } 4.749 + 4.750 + void reset() { 4.751 + rounds++; 4.752 + changed = false; 4.753 + } 4.754 + 4.755 + void detach() { 4.756 + for (Type t : undetvars) { 4.757 + UndetVar uv = (UndetVar)t; 4.758 + uv.listener = null; 4.759 + } 4.760 + } 4.761 + }; 4.762 + 4.763 + /** max number of incorporation rounds */ 4.764 + static final int MAX_INCORPORATION_STEPS = 100; 4.765 + 4.766 + /** 4.767 + * This enumeration defines an entry point for doing inference variable 4.768 + * bound incorporation - it can be used to inject custom incorporation 4.769 + * logic into the basic bound checking routine 4.770 + */ 4.771 + enum IncorporationStep { 4.772 + /** 4.773 + * Performs basic bound checking - i.e. is the instantiated type for a given 4.774 + * inference variable compatible with its bounds? 4.775 + */ 4.776 + CHECK_BOUNDS() { 4.777 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.778 + Infer infer = inferenceContext.infer(); 4.779 + uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types); 4.780 + infer.checkCompatibleUpperBounds(uv, inferenceContext); 4.781 + if (uv.inst != null) { 4.782 + Type inst = uv.inst; 4.783 + for (Type u : uv.getBounds(InferenceBound.UPPER)) { 4.784 + if (!infer.types.isSubtypeUnchecked(inst, inferenceContext.asFree(u), warn)) { 4.785 + infer.reportBoundError(uv, BoundErrorKind.UPPER); 4.786 + } 4.787 + } 4.788 + for (Type l : uv.getBounds(InferenceBound.LOWER)) { 4.789 + if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), inst, warn)) { 4.790 + infer.reportBoundError(uv, BoundErrorKind.LOWER); 4.791 + } 4.792 + } 4.793 + for (Type e : uv.getBounds(InferenceBound.EQ)) { 4.794 + if (!infer.types.isSameType(inst, inferenceContext.asFree(e))) { 4.795 + infer.reportBoundError(uv, BoundErrorKind.EQ); 4.796 + } 4.797 + } 4.798 + } 4.799 + } 4.800 + }, 4.801 + /** 4.802 + * Check consistency of equality constraints. This is a slightly more aggressive 4.803 + * inference routine that is designed as to maximize compatibility with JDK 7. 4.804 + * Note: this is not used in graph mode. 4.805 + */ 4.806 + EQ_CHECK_LEGACY() { 4.807 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.808 + Infer infer = inferenceContext.infer(); 4.809 + Type eq = null; 4.810 + for (Type e : uv.getBounds(InferenceBound.EQ)) { 4.811 + Assert.check(!inferenceContext.free(e)); 4.812 + if (eq != null && !infer.types.isSameType(e, eq)) { 4.813 + infer.reportBoundError(uv, BoundErrorKind.EQ); 4.814 + } 4.815 + eq = e; 4.816 + for (Type l : uv.getBounds(InferenceBound.LOWER)) { 4.817 + Assert.check(!inferenceContext.free(l)); 4.818 + if (!infer.types.isSubtypeUnchecked(l, e, warn)) { 4.819 + infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); 4.820 + } 4.821 + } 4.822 + for (Type u : uv.getBounds(InferenceBound.UPPER)) { 4.823 + if (inferenceContext.free(u)) continue; 4.824 + if (!infer.types.isSubtypeUnchecked(e, u, warn)) { 4.825 + infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); 4.826 + } 4.827 + } 4.828 + } 4.829 + } 4.830 + }, 4.831 + /** 4.832 + * Check consistency of equality constraints. 4.833 + */ 4.834 + EQ_CHECK() { 4.835 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.836 + Infer infer = inferenceContext.infer(); 4.837 + for (Type e : uv.getBounds(InferenceBound.EQ)) { 4.838 + if (e.containsAny(inferenceContext.inferenceVars())) continue; 4.839 + for (Type u : uv.getBounds(InferenceBound.UPPER)) { 4.840 + if (!infer.types.isSubtypeUnchecked(e, inferenceContext.asFree(u), warn)) { 4.841 + infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); 4.842 + } 4.843 + } 4.844 + for (Type l : uv.getBounds(InferenceBound.LOWER)) { 4.845 + if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), e, warn)) { 4.846 + infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); 4.847 + } 4.848 + } 4.849 + } 4.850 + } 4.851 + }, 4.852 + /** 4.853 + * Given a bound set containing {@code alpha <: T} and {@code alpha :> S} 4.854 + * perform {@code S <: T} (which could lead to new bounds). 4.855 + */ 4.856 + CROSS_UPPER_LOWER() { 4.857 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.858 + Infer infer = inferenceContext.infer(); 4.859 + for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { 4.860 + for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { 4.861 + if (!inferenceContext.inferenceVars().contains(b1) && 4.862 + !inferenceContext.inferenceVars().contains(b2) && 4.863 + infer.types.asSuper(b2, b1.tsym) != null) { 4.864 + infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 4.865 + } 4.866 + } 4.867 + } 4.868 + } 4.869 + }, 4.870 + /** 4.871 + * Given a bound set containing {@code alpha <: T} and {@code alpha == S} 4.872 + * perform {@code S <: T} (which could lead to new bounds). 4.873 + */ 4.874 + CROSS_UPPER_EQ() { 4.875 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.876 + Infer infer = inferenceContext.infer(); 4.877 + for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { 4.878 + for (Type b2 : uv.getBounds(InferenceBound.EQ)) { 4.879 + if (!inferenceContext.inferenceVars().contains(b1) && 4.880 + !inferenceContext.inferenceVars().contains(b2) && 4.881 + infer.types.asSuper(b2, b1.tsym) != null) { 4.882 + infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 4.883 + } 4.884 + } 4.885 + } 4.886 + } 4.887 + }, 4.888 + /** 4.889 + * Given a bound set containing {@code alpha :> S} and {@code alpha == T} 4.890 + * perform {@code S <: T} (which could lead to new bounds). 4.891 + */ 4.892 + CROSS_EQ_LOWER() { 4.893 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.894 + Infer infer = inferenceContext.infer(); 4.895 + for (Type b1 : uv.getBounds(InferenceBound.EQ)) { 4.896 + for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { 4.897 + if (!inferenceContext.inferenceVars().contains(b1) && 4.898 + !inferenceContext.inferenceVars().contains(b2) && 4.899 + infer.types.asSuper(b2, b1.tsym) != null) { 4.900 + infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 4.901 + } 4.902 + } 4.903 + } 4.904 + } 4.905 + }, 4.906 + /** 4.907 + * Given a bound set containing {@code alpha <: beta} propagate lower bounds 4.908 + * from alpha to beta; also propagate upper bounds from beta to alpha. 4.909 + */ 4.910 + PROP_UPPER() { 4.911 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.912 + Infer infer = inferenceContext.infer(); 4.913 + for (Type b : uv.getBounds(InferenceBound.UPPER)) { 4.914 + if (inferenceContext.inferenceVars().contains(b)) { 4.915 + UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); 4.916 + //alpha <: beta 4.917 + //1. copy alpha's lower to beta's 4.918 + for (Type l : uv.getBounds(InferenceBound.LOWER)) { 4.919 + uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); 4.920 + } 4.921 + //2. copy beta's upper to alpha's 4.922 + for (Type u : uv2.getBounds(InferenceBound.UPPER)) { 4.923 + uv.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); 4.924 + } 4.925 + } 4.926 + } 4.927 + } 4.928 + }, 4.929 + /** 4.930 + * Given a bound set containing {@code alpha :> beta} propagate lower bounds 4.931 + * from beta to alpha; also propagate upper bounds from alpha to beta. 4.932 + */ 4.933 + PROP_LOWER() { 4.934 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.935 + Infer infer = inferenceContext.infer(); 4.936 + for (Type b : uv.getBounds(InferenceBound.LOWER)) { 4.937 + if (inferenceContext.inferenceVars().contains(b)) { 4.938 + UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); 4.939 + //alpha :> beta 4.940 + //1. copy alpha's upper to beta's 4.941 + for (Type u : uv.getBounds(InferenceBound.UPPER)) { 4.942 + uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); 4.943 + } 4.944 + //2. copy beta's lower to alpha's 4.945 + for (Type l : uv2.getBounds(InferenceBound.LOWER)) { 4.946 + uv.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); 4.947 + } 4.948 + } 4.949 + } 4.950 + } 4.951 + }, 4.952 + /** 4.953 + * Given a bound set containing {@code alpha == beta} propagate lower/upper 4.954 + * bounds from alpha to beta and back. 4.955 + */ 4.956 + PROP_EQ() { 4.957 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 4.958 + Infer infer = inferenceContext.infer(); 4.959 + for (Type b : uv.getBounds(InferenceBound.EQ)) { 4.960 + if (inferenceContext.inferenceVars().contains(b)) { 4.961 + UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); 4.962 + //alpha == beta 4.963 + //1. copy all alpha's bounds to beta's 4.964 + for (InferenceBound ib : InferenceBound.values()) { 4.965 + for (Type b2 : uv.getBounds(ib)) { 4.966 + if (b2 != uv2) { 4.967 + uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types); 4.968 + } 4.969 + } 4.970 + } 4.971 + //2. copy all beta's bounds to alpha's 4.972 + for (InferenceBound ib : InferenceBound.values()) { 4.973 + for (Type b2 : uv2.getBounds(ib)) { 4.974 + if (b2 != uv) { 4.975 + uv.addBound(ib, inferenceContext.asInstType(b2), infer.types); 4.976 + } 4.977 + } 4.978 + } 4.979 + } 4.980 + } 4.981 + } 4.982 + }; 4.983 + 4.984 + abstract void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn); 4.985 + } 4.986 + 4.987 + /** incorporation steps to be executed when running in legacy mode */ 4.988 + EnumSet<IncorporationStep> incorporationStepsLegacy = EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY); 4.989 + 4.990 + /** incorporation steps to be executed when running in graph mode */ 4.991 + EnumSet<IncorporationStep> incorporationStepsGraph = 4.992 + EnumSet.complementOf(EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY)); 4.993 + 4.994 + /** 4.995 + * Make sure that the upper bounds we got so far lead to a solvable inference 4.996 + * variable by making sure that a glb exists. 4.997 + */ 4.998 + void checkCompatibleUpperBounds(UndetVar uv, InferenceContext inferenceContext) { 4.999 + List<Type> hibounds = 4.1000 + Type.filter(uv.getBounds(InferenceBound.UPPER), new BoundFilter(inferenceContext)); 4.1001 + Type hb = null; 4.1002 + if (hibounds.isEmpty()) 4.1003 + hb = syms.objectType; 4.1004 + else if (hibounds.tail.isEmpty()) 4.1005 + hb = hibounds.head; 4.1006 + else 4.1007 + hb = types.glb(hibounds); 4.1008 + if (hb == null || hb.isErroneous()) 4.1009 + reportBoundError(uv, BoundErrorKind.BAD_UPPER); 4.1010 + } 4.1011 + //where 4.1012 + protected static class BoundFilter implements Filter<Type> { 4.1013 + 4.1014 + InferenceContext inferenceContext; 4.1015 + 4.1016 + public BoundFilter(InferenceContext inferenceContext) { 4.1017 + this.inferenceContext = inferenceContext; 4.1018 + } 4.1019 + 4.1020 + @Override 4.1021 + public boolean accepts(Type t) { 4.1022 + return !t.isErroneous() && !inferenceContext.free(t) && 4.1023 + !t.hasTag(BOT); 4.1024 + } 4.1025 + }; 4.1026 + 4.1027 + /** 4.1028 + * This enumeration defines all possible bound-checking related errors. 4.1029 + */ 4.1030 + enum BoundErrorKind { 4.1031 + /** 4.1032 + * The (uninstantiated) inference variable has incompatible upper bounds. 4.1033 + */ 4.1034 + BAD_UPPER() { 4.1035 + @Override 4.1036 + InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.1037 + return ex.setMessage("incompatible.upper.bounds", uv.qtype, 4.1038 + uv.getBounds(InferenceBound.UPPER)); 4.1039 + } 4.1040 + }, 4.1041 + /** 4.1042 + * An equality constraint is not compatible with an upper bound. 4.1043 + */ 4.1044 + BAD_EQ_UPPER() { 4.1045 + @Override 4.1046 + InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.1047 + return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype, 4.1048 + uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER)); 4.1049 + } 4.1050 + }, 4.1051 + /** 4.1052 + * An equality constraint is not compatible with a lower bound. 4.1053 + */ 4.1054 + BAD_EQ_LOWER() { 4.1055 + @Override 4.1056 + InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.1057 + return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype, 4.1058 + uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER)); 4.1059 + } 4.1060 + }, 4.1061 + /** 4.1062 + * Instantiated inference variable is not compatible with an upper bound. 4.1063 + */ 4.1064 + UPPER() { 4.1065 + @Override 4.1066 + InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.1067 + return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst, 4.1068 + uv.getBounds(InferenceBound.UPPER)); 4.1069 + } 4.1070 + }, 4.1071 + /** 4.1072 + * Instantiated inference variable is not compatible with a lower bound. 4.1073 + */ 4.1074 + LOWER() { 4.1075 + @Override 4.1076 + InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.1077 + return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst, 4.1078 + uv.getBounds(InferenceBound.LOWER)); 4.1079 + } 4.1080 + }, 4.1081 + /** 4.1082 + * Instantiated inference variable is not compatible with an equality constraint. 4.1083 + */ 4.1084 + EQ() { 4.1085 + @Override 4.1086 + InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) { 4.1087 + return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst, 4.1088 + uv.getBounds(InferenceBound.EQ)); 4.1089 + } 4.1090 + }; 4.1091 + 4.1092 + abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv); 4.1093 + } 4.1094 + 4.1095 + /** 4.1096 + * Report a bound-checking error of given kind 4.1097 + */ 4.1098 + void reportBoundError(UndetVar uv, BoundErrorKind bk) { 4.1099 + throw bk.setMessage(inferenceException, uv); 4.1100 + } 4.1101 + // </editor-fold> 4.1102 + 4.1103 + // <editor-fold defaultstate="collapsed" desc="Inference engine"> 4.1104 + /** 4.1105 + * Graph inference strategy - act as an input to the inference solver; a strategy is 4.1106 + * composed of two ingredients: (i) find a node to solve in the inference graph, 4.1107 + * and (ii) tell th engine when we are done fixing inference variables 4.1108 + */ 4.1109 + interface GraphStrategy { 4.1110 + /** 4.1111 + * Pick the next node (leaf) to solve in the graph 4.1112 + */ 4.1113 + Node pickNode(InferenceGraph g); 4.1114 + /** 4.1115 + * Is this the last step? 4.1116 + */ 4.1117 + boolean done(); 4.1118 + } 4.1119 + 4.1120 + /** 4.1121 + * Simple solver strategy class that locates all leaves inside a graph 4.1122 + * and picks the first leaf as the next node to solve 4.1123 + */ 4.1124 + abstract class LeafSolver implements GraphStrategy { 4.1125 + public Node pickNode(InferenceGraph g) { 4.1126 + Assert.check(!g.nodes.isEmpty(), "No nodes to solve!"); 4.1127 + return g.nodes.get(0); 4.1128 + } 4.1129 + } 4.1130 + 4.1131 + /** 4.1132 + * This solver uses an heuristic to pick the best leaf - the heuristic 4.1133 + * tries to select the node that has maximal probability to contain one 4.1134 + * or more inference variables in a given list 4.1135 + */ 4.1136 + abstract class BestLeafSolver extends LeafSolver { 4.1137 + 4.1138 + List<Type> varsToSolve; 4.1139 + 4.1140 + BestLeafSolver(List<Type> varsToSolve) { 4.1141 + this.varsToSolve = varsToSolve; 4.1142 + } 4.1143 + 4.1144 + /** 4.1145 + * Computes the cost associated with a given node; the cost is computed 4.1146 + * as the total number of type-variables that should be eagerly instantiated 4.1147 + * in order to get to some of the variables in {@code varsToSolve} from 4.1148 + * a given node 4.1149 + */ 4.1150 + void computeCostIfNeeded(Node n, Map<Node, Integer> costMap) { 4.1151 + if (costMap.containsKey(n)) { 4.1152 + return; 4.1153 + } else if (!Collections.disjoint(n.data, varsToSolve)) { 4.1154 + costMap.put(n, n.data.size()); 4.1155 + } else { 4.1156 + int subcost = Integer.MAX_VALUE; 4.1157 + costMap.put(n, subcost); //avoid loops 4.1158 + for (Node n2 : n.getDependencies()) { 4.1159 + computeCostIfNeeded(n2, costMap); 4.1160 + subcost = Math.min(costMap.get(n2), subcost); 4.1161 + } 4.1162 + //update cost map to reflect real cost 4.1163 + costMap.put(n, subcost == Integer.MAX_VALUE ? 4.1164 + Integer.MAX_VALUE : 4.1165 + n.data.size() + subcost); 4.1166 + } 4.1167 + } 4.1168 + 4.1169 + /** 4.1170 + * Pick the leaf that minimize cost 4.1171 + */ 4.1172 + @Override 4.1173 + public Node pickNode(final InferenceGraph g) { 4.1174 + final Map<Node, Integer> costMap = new HashMap<Node, Integer>(); 4.1175 + ArrayList<Node> leaves = new ArrayList<Node>(); 4.1176 + for (Node n : g.nodes) { 4.1177 + computeCostIfNeeded(n, costMap); 4.1178 + if (n.isLeaf(n)) { 4.1179 + leaves.add(n); 4.1180 + } 4.1181 + } 4.1182 + Assert.check(!leaves.isEmpty(), "No nodes to solve!"); 4.1183 + Collections.sort(leaves, new java.util.Comparator<Node>() { 4.1184 + public int compare(Node n1, Node n2) { 4.1185 + return costMap.get(n1) - costMap.get(n2); 4.1186 + } 4.1187 + }); 4.1188 + return leaves.get(0); 4.1189 + } 4.1190 + } 4.1191 + 4.1192 + /** 4.1193 + * The inference process can be thought of as a sequence of steps. Each step 4.1194 + * instantiates an inference variable using a subset of the inference variable 4.1195 + * bounds, if certain condition are met. Decisions such as the sequence in which 4.1196 + * steps are applied, or which steps are to be applied are left to the inference engine. 4.1197 + */ 4.1198 + enum InferenceStep { 4.1199 + 4.1200 + /** 4.1201 + * Instantiate an inference variables using one of its (ground) equality 4.1202 + * constraints 4.1203 + */ 4.1204 + EQ(InferenceBound.EQ) { 4.1205 + @Override 4.1206 + Type solve(UndetVar uv, InferenceContext inferenceContext) { 4.1207 + return filterBounds(uv, inferenceContext).head; 4.1208 + } 4.1209 + }, 4.1210 + /** 4.1211 + * Instantiate an inference variables using its (ground) lower bounds. Such 4.1212 + * bounds are merged together using lub(). 4.1213 + */ 4.1214 + LOWER(InferenceBound.LOWER) { 4.1215 + @Override 4.1216 + Type solve(UndetVar uv, InferenceContext inferenceContext) { 4.1217 + Infer infer = inferenceContext.infer(); 4.1218 + List<Type> lobounds = filterBounds(uv, inferenceContext); 4.1219 + Type owntype = infer.types.lub(lobounds); 4.1220 + if (owntype.hasTag(ERROR)) { 4.1221 + throw infer.inferenceException 4.1222 + .setMessage("no.unique.minimal.instance.exists", 4.1223 + uv.qtype, lobounds); 4.1224 + } else { 4.1225 + return owntype; 4.1226 + } 4.1227 + } 4.1228 + }, 4.1229 + /** 4.1230 + * Instantiate an inference variables using its (ground) upper bounds. Such 4.1231 + * bounds are merged together using glb(). 4.1232 + */ 4.1233 + UPPER(InferenceBound.UPPER) { 4.1234 + @Override 4.1235 + Type solve(UndetVar uv, InferenceContext inferenceContext) { 4.1236 + Infer infer = inferenceContext.infer(); 4.1237 + List<Type> hibounds = filterBounds(uv, inferenceContext); 4.1238 + Type owntype = infer.types.glb(hibounds); 4.1239 + if (owntype.isErroneous()) { 4.1240 + throw infer.inferenceException 4.1241 + .setMessage("no.unique.maximal.instance.exists", 4.1242 + uv.qtype, hibounds); 4.1243 + } else { 4.1244 + return owntype; 4.1245 + } 4.1246 + } 4.1247 + }, 4.1248 + /** 4.1249 + * Like the former; the only difference is that this step can only be applied 4.1250 + * if all upper bounds are ground. 4.1251 + */ 4.1252 + UPPER_LEGACY(InferenceBound.UPPER) { 4.1253 + @Override 4.1254 + public boolean accepts(UndetVar t, InferenceContext inferenceContext) { 4.1255 + return !inferenceContext.free(t.getBounds(ib)); 4.1256 + } 4.1257 + 4.1258 + @Override 4.1259 + Type solve(UndetVar uv, InferenceContext inferenceContext) { 4.1260 + return UPPER.solve(uv, inferenceContext); 4.1261 + } 4.1262 + }; 4.1263 + 4.1264 + final InferenceBound ib; 4.1265 + 4.1266 + InferenceStep(InferenceBound ib) { 4.1267 + this.ib = ib; 4.1268 + } 4.1269 + 4.1270 + /** 4.1271 + * Find an instantiated type for a given inference variable within 4.1272 + * a given inference context 4.1273 + */ 4.1274 + abstract Type solve(UndetVar uv, InferenceContext inferenceContext); 4.1275 + 4.1276 + /** 4.1277 + * Can the inference variable be instantiated using this step? 4.1278 + */ 4.1279 + public boolean accepts(UndetVar t, InferenceContext inferenceContext) { 4.1280 + return filterBounds(t, inferenceContext).nonEmpty(); 4.1281 + } 4.1282 + 4.1283 + /** 4.1284 + * Return the subset of ground bounds in a given bound set (i.e. eq/lower/upper) 4.1285 + */ 4.1286 + List<Type> filterBounds(UndetVar uv, InferenceContext inferenceContext) { 4.1287 + return Type.filter(uv.getBounds(ib), new BoundFilter(inferenceContext)); 4.1288 + } 4.1289 + } 4.1290 + 4.1291 + /** 4.1292 + * This enumeration defines the sequence of steps to be applied when the 4.1293 + * solver works in legacy mode. The steps in this enumeration reflect 4.1294 + * the behavior of old inference routine (see JLS SE 7 15.12.2.7/15.12.2.8). 4.1295 + */ 4.1296 + enum LegacyInferenceSteps { 4.1297 + 4.1298 + EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)), 4.1299 + EQ_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.UPPER_LEGACY)); 4.1300 + 4.1301 + final EnumSet<InferenceStep> steps; 4.1302 + 4.1303 + LegacyInferenceSteps(EnumSet<InferenceStep> steps) { 4.1304 + this.steps = steps; 4.1305 + } 4.1306 + } 4.1307 + 4.1308 + /** 4.1309 + * This enumeration defines the sequence of steps to be applied when the 4.1310 + * graph solver is used. This order is defined so as to maximize compatibility 4.1311 + * w.r.t. old inference routine (see JLS SE 7 15.12.2.7/15.12.2.8). 4.1312 + */ 4.1313 + enum GraphInferenceSteps { 4.1314 + 4.1315 + EQ(EnumSet.of(InferenceStep.EQ)), 4.1316 + EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)), 4.1317 + EQ_LOWER_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.UPPER)); 4.1318 + 4.1319 + final EnumSet<InferenceStep> steps; 4.1320 + 4.1321 + GraphInferenceSteps(EnumSet<InferenceStep> steps) { 4.1322 + this.steps = steps; 4.1323 + } 4.1324 + } 4.1325 + 4.1326 + /** 4.1327 + * This is the graph inference solver - the solver organizes all inference variables in 4.1328 + * a given inference context by bound dependencies - in the general case, such dependencies 4.1329 + * would lead to a cyclic directed graph (hence the name); the dependency info is used to build 4.1330 + * an acyclic graph, where all cyclic variables are bundled together. An inference 4.1331 + * step corresponds to solving a node in the acyclic graph - this is done by 4.1332 + * relying on a given strategy (see GraphStrategy). 4.1333 + */ 4.1334 + class GraphSolver { 4.1335 + 4.1336 + InferenceContext inferenceContext; 4.1337 + Warner warn; 4.1338 + 4.1339 + GraphSolver(InferenceContext inferenceContext, Warner warn) { 4.1340 + this.inferenceContext = inferenceContext; 4.1341 + this.warn = warn; 4.1342 + } 4.1343 + 4.1344 + /** 4.1345 + * Solve variables in a given inference context. The amount of variables 4.1346 + * to be solved, and the way in which the underlying acyclic graph is explored 4.1347 + * depends on the selected solver strategy. 4.1348 + */ 4.1349 + void solve(GraphStrategy sstrategy) { 4.1350 + checkWithinBounds(inferenceContext, warn); //initial propagation of bounds 4.1351 + InferenceGraph inferenceGraph = new InferenceGraph(); 4.1352 + while (!sstrategy.done()) { 4.1353 + InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph); 4.1354 + List<Type> varsToSolve = List.from(nodeToSolve.data); 4.1355 + inferenceContext.save(); 4.1356 + try { 4.1357 + //repeat until all variables are solved 4.1358 + outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) { 4.1359 + //for each inference phase 4.1360 + for (GraphInferenceSteps step : GraphInferenceSteps.values()) { 4.1361 + if (inferenceContext.solveBasic(varsToSolve, step.steps)) { 4.1362 + checkWithinBounds(inferenceContext, warn); 4.1363 + continue outer; 4.1364 + } 4.1365 + } 4.1366 + //no progress 4.1367 + throw inferenceException; 4.1368 + } 4.1369 + } 4.1370 + catch (InferenceException ex) { 4.1371 + inferenceContext.rollback(); 4.1372 + instantiateAsUninferredVars(varsToSolve, inferenceContext); 4.1373 + checkWithinBounds(inferenceContext, warn); 4.1374 + } 4.1375 + inferenceGraph.deleteNode(nodeToSolve); 4.1376 + } 4.1377 + } 4.1378 + 4.1379 + /** 4.1380 + * The dependencies between the inference variables that need to be solved 4.1381 + * form a (possibly cyclic) graph. This class reduces the original dependency graph 4.1382 + * to an acyclic version, where cyclic nodes are folded into a single 'super node'. 4.1383 + */ 4.1384 + class InferenceGraph { 4.1385 + 4.1386 + /** 4.1387 + * This class represents a node in the graph. Each node corresponds 4.1388 + * to an inference variable and has edges (dependencies) on other 4.1389 + * nodes. The node defines an entry point that can be used to receive 4.1390 + * updates on the structure of the graph this node belongs to (used to 4.1391 + * keep dependencies in sync). 4.1392 + */ 4.1393 + class Node extends GraphUtils.TarjanNode<ListBuffer<Type>> { 4.1394 + 4.1395 + Set<Node> deps; 4.1396 + 4.1397 + Node(Type ivar) { 4.1398 + super(ListBuffer.of(ivar)); 4.1399 + this.deps = new HashSet<Node>(); 4.1400 + } 4.1401 + 4.1402 + @Override 4.1403 + public Iterable<? extends Node> getDependencies() { 4.1404 + return deps; 4.1405 + } 4.1406 + 4.1407 + @Override 4.1408 + public String printDependency(GraphUtils.Node<ListBuffer<Type>> to) { 4.1409 + StringBuilder buf = new StringBuilder(); 4.1410 + String sep = ""; 4.1411 + for (Type from : data) { 4.1412 + UndetVar uv = (UndetVar)inferenceContext.asFree(from); 4.1413 + for (Type bound : uv.getBounds(InferenceBound.values())) { 4.1414 + if (bound.containsAny(List.from(to.data))) { 4.1415 + buf.append(sep); 4.1416 + buf.append(bound); 4.1417 + sep = ","; 4.1418 + } 4.1419 + } 4.1420 + } 4.1421 + return buf.toString(); 4.1422 + } 4.1423 + 4.1424 + boolean isLeaf(Node n) { 4.1425 + //no deps, or only one self dep 4.1426 + return (n.deps.isEmpty() || 4.1427 + n.deps.size() == 1 && n.deps.contains(n)); 4.1428 + } 4.1429 + 4.1430 + void mergeWith(List<? extends Node> nodes) { 4.1431 + for (Node n : nodes) { 4.1432 + Assert.check(n.data.length() == 1, "Attempt to merge a compound node!"); 4.1433 + data.appendList(n.data); 4.1434 + deps.addAll(n.deps); 4.1435 + } 4.1436 + //update deps 4.1437 + Set<Node> deps2 = new HashSet<Node>(); 4.1438 + for (Node d : deps) { 4.1439 + if (data.contains(d.data.first())) { 4.1440 + deps2.add(this); 4.1441 + } else { 4.1442 + deps2.add(d); 4.1443 + } 4.1444 + } 4.1445 + deps = deps2; 4.1446 + } 4.1447 + 4.1448 + void graphChanged(Node from, Node to) { 4.1449 + if (deps.contains(from)) { 4.1450 + deps.remove(from); 4.1451 + if (to != null) { 4.1452 + deps.add(to); 4.1453 + } 4.1454 + } 4.1455 + } 4.1456 + } 4.1457 + 4.1458 + /** the nodes in the inference graph */ 4.1459 + ArrayList<Node> nodes; 4.1460 + 4.1461 + InferenceGraph() { 4.1462 + initNodes(); 4.1463 + } 4.1464 + 4.1465 + /** 4.1466 + * Delete a node from the graph. This update the underlying structure 4.1467 + * of the graph (including dependencies) via listeners updates. 4.1468 + */ 4.1469 + public void deleteNode(Node n) { 4.1470 + Assert.check(nodes.contains(n)); 4.1471 + nodes.remove(n); 4.1472 + notifyUpdate(n, null); 4.1473 + } 4.1474 + 4.1475 + /** 4.1476 + * Notify all nodes of a change in the graph. If the target node is 4.1477 + * {@code null} the source node is assumed to be removed. 4.1478 + */ 4.1479 + void notifyUpdate(Node from, Node to) { 4.1480 + for (Node n : nodes) { 4.1481 + n.graphChanged(from, to); 4.1482 + } 4.1483 + } 4.1484 + 4.1485 + /** 4.1486 + * Create the graph nodes. First a simple node is created for every inference 4.1487 + * variables to be solved. Then Tarjan is used to found all connected components 4.1488 + * in the graph. For each component containing more than one node, a super node is 4.1489 + * created, effectively replacing the original cyclic nodes. 4.1490 + */ 4.1491 + void initNodes() { 4.1492 + ArrayList<Node> nodes = new ArrayList<Node>(); 4.1493 + for (Type t : inferenceContext.restvars()) { 4.1494 + nodes.add(new Node(t)); 4.1495 + } 4.1496 + for (Node n_i : nodes) { 4.1497 + Type i = n_i.data.first(); 4.1498 + for (Node n_j : nodes) { 4.1499 + Type j = n_j.data.first(); 4.1500 + UndetVar uv_i = (UndetVar)inferenceContext.asFree(i); 4.1501 + if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) { 4.1502 + //update i's deps 4.1503 + n_i.deps.add(n_j); 4.1504 + //update j's deps - only if i's bounds contain _exactly_ j 4.1505 + if (uv_i.getBounds(InferenceBound.values()).contains(j)) { 4.1506 + n_j.deps.add(n_i); 4.1507 + } 4.1508 + } 4.1509 + } 4.1510 + } 4.1511 + this.nodes = new ArrayList<Node>(); 4.1512 + for (List<? extends Node> conSubGraph : GraphUtils.tarjan(nodes)) { 4.1513 + if (conSubGraph.length() > 1) { 4.1514 + Node root = conSubGraph.head; 4.1515 + root.mergeWith(conSubGraph.tail); 4.1516 + for (Node n : conSubGraph) { 4.1517 + notifyUpdate(n, root); 4.1518 + } 4.1519 + } 4.1520 + this.nodes.add(conSubGraph.head); 4.1521 + } 4.1522 + } 4.1523 + 4.1524 + /** 4.1525 + * Debugging: dot representation of this graph 4.1526 + */ 4.1527 + String toDot() { 4.1528 + StringBuilder buf = new StringBuilder(); 4.1529 + for (Type t : inferenceContext.undetvars) { 4.1530 + UndetVar uv = (UndetVar)t; 4.1531 + buf.append(String.format("var %s - upper bounds = %s, lower bounds = %s, eq bounds = %s\\n", 4.1532 + uv.qtype, uv.getBounds(InferenceBound.UPPER), uv.getBounds(InferenceBound.LOWER), 4.1533 + uv.getBounds(InferenceBound.EQ))); 4.1534 + } 4.1535 + return GraphUtils.toDot(nodes, "inferenceGraph" + hashCode(), buf.toString()); 4.1536 + } 4.1537 + } 4.1538 + } 4.1539 + // </editor-fold> 4.1540 + 4.1541 + // <editor-fold defaultstate="collapsed" desc="Inference context"> 4.1542 + /** 4.1543 * Functional interface for defining inference callbacks. Certain actions 4.1544 * (i.e. subtyping checks) might need to be redone after all inference variables 4.1545 * have been fixed. 4.1546 @@ -603,7 +1283,7 @@ 4.1547 * it can be used as an entry point for performing upper/lower bound inference 4.1548 * (see InferenceKind). 4.1549 */ 4.1550 - class InferenceContext { 4.1551 + class InferenceContext { 4.1552 4.1553 /** list of inference vars as undet vars */ 4.1554 List<Type> undetvars; 4.1555 @@ -611,6 +1291,9 @@ 4.1556 /** list of inference vars in this context */ 4.1557 List<Type> inferencevars; 4.1558 4.1559 + /** backed up inference variables */ 4.1560 + List<Type> saved_undet; 4.1561 + 4.1562 java.util.Map<FreeTypeListener, List<Type>> freeTypeListeners = 4.1563 new java.util.HashMap<FreeTypeListener, List<Type>>(); 4.1564 4.1565 @@ -782,10 +1465,14 @@ 4.1566 * of all deferred checks. 4.1567 */ 4.1568 void notifyChange() { 4.1569 + notifyChange(inferencevars.diff(restvars())); 4.1570 + } 4.1571 + 4.1572 + void notifyChange(List<Type> inferredVars) { 4.1573 InferenceException thrownEx = null; 4.1574 for (Map.Entry<FreeTypeListener, List<Type>> entry : 4.1575 new HashMap<FreeTypeListener, List<Type>>(freeTypeListeners).entrySet()) { 4.1576 - if (!Type.containsAny(entry.getValue(), restvars())) { 4.1577 + if (!Type.containsAny(entry.getValue(), inferencevars.diff(inferredVars))) { 4.1578 try { 4.1579 entry.getKey().typesInferred(this); 4.1580 freeTypeListeners.remove(entry.getKey()); 4.1581 @@ -803,20 +1490,153 @@ 4.1582 } 4.1583 } 4.1584 4.1585 - void solveAny(List<Type> varsToSolve) { 4.1586 - boolean progress = false; 4.1587 - for (Type t : varsToSolve) { 4.1588 + /** 4.1589 + * Save the state of this inference context 4.1590 + */ 4.1591 + void save() { 4.1592 + ListBuffer<Type> buf = ListBuffer.lb(); 4.1593 + for (Type t : undetvars) { 4.1594 + UndetVar uv = (UndetVar)t; 4.1595 + UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types); 4.1596 + for (InferenceBound ib : InferenceBound.values()) { 4.1597 + for (Type b : uv.getBounds(ib)) { 4.1598 + uv2.addBound(ib, b, types); 4.1599 + } 4.1600 + } 4.1601 + uv2.inst = uv.inst; 4.1602 + buf.add(uv2); 4.1603 + } 4.1604 + saved_undet = buf.toList(); 4.1605 + } 4.1606 + 4.1607 + /** 4.1608 + * Restore the state of this inference context to the previous known checkpoint 4.1609 + */ 4.1610 + void rollback() { 4.1611 + Assert.check(saved_undet != null && saved_undet.length() == undetvars.length()); 4.1612 + undetvars = saved_undet; 4.1613 + saved_undet = null; 4.1614 + } 4.1615 + 4.1616 + /** 4.1617 + * Copy variable in this inference context to the given context 4.1618 + */ 4.1619 + void dupTo(final InferenceContext that) { 4.1620 + that.inferencevars = that.inferencevars.appendList(inferencevars); 4.1621 + that.undetvars = that.undetvars.appendList(undetvars); 4.1622 + //set up listeners to notify original inference contexts as 4.1623 + //propagated vars are inferred in new context 4.1624 + for (Type t : inferencevars) { 4.1625 + that.freeTypeListeners.put(new FreeTypeListener() { 4.1626 + public void typesInferred(InferenceContext inferenceContext) { 4.1627 + InferenceContext.this.notifyChange(); 4.1628 + } 4.1629 + }, List.of(t)); 4.1630 + } 4.1631 + } 4.1632 + 4.1633 + /** 4.1634 + * Solve with given graph strategy. 4.1635 + */ 4.1636 + private void solve(GraphStrategy ss, Warner warn) { 4.1637 + GraphSolver s = new GraphSolver(this, warn); 4.1638 + s.solve(ss); 4.1639 + } 4.1640 + 4.1641 + /** 4.1642 + * Solve all variables in this context. 4.1643 + */ 4.1644 + public void solve(Warner warn) { 4.1645 + solve(new LeafSolver() { 4.1646 + public boolean done() { 4.1647 + return restvars().isEmpty(); 4.1648 + } 4.1649 + }, warn); 4.1650 + } 4.1651 + 4.1652 + /** 4.1653 + * Solve all variables in the given list. 4.1654 + */ 4.1655 + public void solve(final List<Type> vars, Warner warn) { 4.1656 + solve(new BestLeafSolver(vars) { 4.1657 + public boolean done() { 4.1658 + return !free(asInstTypes(vars)); 4.1659 + } 4.1660 + }, warn); 4.1661 + } 4.1662 + 4.1663 + /** 4.1664 + * Solve at least one variable in given list. 4.1665 + */ 4.1666 + public void solveAny(List<Type> varsToSolve, Warner warn) { 4.1667 + checkWithinBounds(this, warn); //propagate bounds 4.1668 + List<Type> boundedVars = boundedVars().intersect(restvars()).intersect(varsToSolve); 4.1669 + if (boundedVars.isEmpty()) { 4.1670 + throw inferenceException.setMessage("cyclic.inference", 4.1671 + freeVarsIn(varsToSolve)); 4.1672 + } 4.1673 + solve(new BestLeafSolver(boundedVars) { 4.1674 + public boolean done() { 4.1675 + return instvars().intersect(varsToSolve).nonEmpty(); 4.1676 + } 4.1677 + }, warn); 4.1678 + } 4.1679 + 4.1680 + /** 4.1681 + * Apply a set of inference steps 4.1682 + */ 4.1683 + private boolean solveBasic(EnumSet<InferenceStep> steps) { 4.1684 + return solveBasic(inferencevars, steps); 4.1685 + } 4.1686 + 4.1687 + private boolean solveBasic(List<Type> varsToSolve, EnumSet<InferenceStep> steps) { 4.1688 + boolean changed = false; 4.1689 + for (Type t : varsToSolve.intersect(restvars())) { 4.1690 UndetVar uv = (UndetVar)asFree(t); 4.1691 - if (uv.inst == null) { 4.1692 - minimizeInst(uv, types.noWarnings); 4.1693 - if (uv.inst != null) { 4.1694 - progress = true; 4.1695 + for (InferenceStep step : steps) { 4.1696 + if (step.accepts(uv, this)) { 4.1697 + uv.inst = step.solve(uv, this); 4.1698 + changed = true; 4.1699 + break; 4.1700 } 4.1701 } 4.1702 } 4.1703 - if (!progress) { 4.1704 - throw inferenceException.setMessage("cyclic.inference", varsToSolve); 4.1705 + return changed; 4.1706 + } 4.1707 + 4.1708 + /** 4.1709 + * Instantiate inference variables in legacy mode (JLS 15.12.2.7, 15.12.2.8). 4.1710 + * During overload resolution, instantiation is done by doing a partial 4.1711 + * inference process using eq/lower bound instantiation. During check, 4.1712 + * we also instantiate any remaining vars by repeatedly using eq/upper 4.1713 + * instantiation, until all variables are solved. 4.1714 + */ 4.1715 + public void solveLegacy(boolean partial, Warner warn, EnumSet<InferenceStep> steps) { 4.1716 + while (true) { 4.1717 + boolean stuck = !solveBasic(steps); 4.1718 + if (restvars().isEmpty() || partial) { 4.1719 + //all variables have been instantiated - exit 4.1720 + break; 4.1721 + } else if (stuck) { 4.1722 + //some variables could not be instantiated because of cycles in 4.1723 + //upper bounds - provide a (possibly recursive) default instantiation 4.1724 + instantiateAsUninferredVars(restvars(), this); 4.1725 + break; 4.1726 + } else { 4.1727 + //some variables have been instantiated - replace newly instantiated 4.1728 + //variables in remaining upper bounds and continue 4.1729 + for (Type t : undetvars) { 4.1730 + UndetVar uv = (UndetVar)t; 4.1731 + uv.substBounds(inferenceVars(), instTypes(), types); 4.1732 + } 4.1733 + } 4.1734 } 4.1735 + checkWithinBounds(this, warn); 4.1736 + } 4.1737 + 4.1738 + private Infer infer() { 4.1739 + //back-door to infer 4.1740 + return Infer.this; 4.1741 } 4.1742 } 4.1743
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/share/classes/com/sun/tools/javac/util/GraphUtils.java Tue Feb 12 19:25:09 2013 +0000 5.3 @@ -0,0 +1,145 @@ 5.4 +/* 5.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. Oracle designates this 5.11 + * particular file as subject to the "Classpath" exception as provided 5.12 + * by Oracle in the LICENSE file that accompanied this code. 5.13 + * 5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.17 + * version 2 for more details (a copy is included in the LICENSE file that 5.18 + * accompanied this code). 5.19 + * 5.20 + * You should have received a copy of the GNU General Public License version 5.21 + * 2 along with this work; if not, write to the Free Software Foundation, 5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.23 + * 5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.25 + * or visit www.oracle.com if you need additional information or have any 5.26 + * questions. 5.27 + */ 5.28 + 5.29 +package com.sun.tools.javac.util; 5.30 + 5.31 +/** <p><b>This is NOT part of any supported API. 5.32 + * If you write code that depends on this, you do so at your own risk. 5.33 + * This code and its internal interfaces are subject to change or 5.34 + * deletion without notice.</b> 5.35 + */ 5.36 +public class GraphUtils { 5.37 + 5.38 + /** 5.39 + * This class is a basic abstract class for representing a node. 5.40 + * A node is associated with a given data. 5.41 + */ 5.42 + public static abstract class Node<D> { 5.43 + public final D data; 5.44 + 5.45 + public Node(D data) { 5.46 + this.data = data; 5.47 + } 5.48 + 5.49 + public abstract Iterable<? extends Node<D>> getDependencies(); 5.50 + 5.51 + public abstract String printDependency(Node<D> to); 5.52 + 5.53 + @Override 5.54 + public String toString() { 5.55 + return data.toString(); 5.56 + } 5.57 + } 5.58 + 5.59 + /** 5.60 + * This class specialized Node, by adding elements that are required in order 5.61 + * to perform Tarjan computation of strongly connected components. 5.62 + */ 5.63 + public static abstract class TarjanNode<D> extends Node<D> implements Comparable<TarjanNode<D>> { 5.64 + int index = -1; 5.65 + int lowlink; 5.66 + boolean active; 5.67 + 5.68 + public TarjanNode(D data) { 5.69 + super(data); 5.70 + } 5.71 + 5.72 + public abstract Iterable<? extends TarjanNode<D>> getDependencies(); 5.73 + 5.74 + public int compareTo(TarjanNode<D> o) { 5.75 + return (index < o.index) ? -1 : (index == o.index) ? 0 : 1; 5.76 + } 5.77 + } 5.78 + 5.79 + /** 5.80 + * Tarjan's algorithm to determine strongly connected components of a 5.81 + * directed graph in linear time. Works on TarjanNode. 5.82 + */ 5.83 + public static <D, N extends TarjanNode<D>> List<? extends List<? extends N>> tarjan(Iterable<? extends N> nodes) { 5.84 + ListBuffer<List<N>> cycles = ListBuffer.lb(); 5.85 + ListBuffer<N> stack = ListBuffer.lb(); 5.86 + int index = 0; 5.87 + for (N node: nodes) { 5.88 + if (node.index == -1) { 5.89 + index += tarjan(node, index, stack, cycles); 5.90 + } 5.91 + } 5.92 + return cycles.toList(); 5.93 + } 5.94 + 5.95 + private static <D, N extends TarjanNode<D>> int tarjan(N v, int index, ListBuffer<N> stack, ListBuffer<List<N>> cycles) { 5.96 + v.index = index; 5.97 + v.lowlink = index; 5.98 + index++; 5.99 + stack.prepend(v); 5.100 + v.active = true; 5.101 + for (TarjanNode<D> nd: v.getDependencies()) { 5.102 + @SuppressWarnings("unchecked") 5.103 + N n = (N)nd; 5.104 + if (n.index == -1) { 5.105 + tarjan(n, index, stack, cycles); 5.106 + v.lowlink = Math.min(v.lowlink, n.lowlink); 5.107 + } else if (stack.contains(n)) { 5.108 + v.lowlink = Math.min(v.lowlink, n.index); 5.109 + } 5.110 + } 5.111 + if (v.lowlink == v.index) { 5.112 + N n; 5.113 + ListBuffer<N> cycle = ListBuffer.lb(); 5.114 + do { 5.115 + n = stack.remove(); 5.116 + n.active = false; 5.117 + cycle.add(n); 5.118 + } while (n != v); 5.119 + cycles.add(cycle.toList()); 5.120 + } 5.121 + return index; 5.122 + } 5.123 + 5.124 + /** 5.125 + * Debugging: dot representation of a set of connected nodes. The resulting 5.126 + * dot representation will use {@code Node.toString} to display node labels 5.127 + * and {@code Node.printDependency} to display edge labels. The resulting 5.128 + * representation is also customizable with a graph name and a header. 5.129 + */ 5.130 + public static <D> String toDot(Iterable<? extends TarjanNode<D>> nodes, String name, String header) { 5.131 + StringBuilder buf = new StringBuilder(); 5.132 + buf.append(String.format("digraph %s {\n", name)); 5.133 + buf.append(String.format("label = \"%s\";\n", header)); 5.134 + //dump nodes 5.135 + for (TarjanNode<D> n : nodes) { 5.136 + buf.append(String.format("%s [label = \"%s\"];\n", n.hashCode(), n.toString())); 5.137 + } 5.138 + //dump arcs 5.139 + for (TarjanNode<D> from : nodes) { 5.140 + for (TarjanNode<D> to : from.getDependencies()) { 5.141 + buf.append(String.format("%s -> %s [label = \" %s \"];\n", 5.142 + from.hashCode(), to.hashCode(), from.printDependency(to))); 5.143 + } 5.144 + } 5.145 + buf.append("}\n"); 5.146 + return buf.toString(); 5.147 + } 5.148 +}
6.1 --- a/test/tools/javac/6758789/T6758789b.out Tue Feb 12 13:36:56 2013 +0000 6.2 +++ b/test/tools/javac/6758789/T6758789b.out Tue Feb 12 19:25:09 2013 +0000 6.3 @@ -1,4 +1,4 @@ 6.4 -T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X> 6.5 +T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<java.lang.Object> 6.6 T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a 6.7 - compiler.err.warnings.and.werror 6.8 1 error
7.1 --- a/test/tools/javac/Diagnostics/6799605/T6799605.out Tue Feb 12 13:36:56 2013 +0000 7.2 +++ b/test/tools/javac/Diagnostics/6799605/T6799605.out Tue Feb 12 19:25:09 2013 +0000 7.3 @@ -1,4 +1,4 @@ 7.4 -T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))} 7.5 +T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.incompatible.eq.upper.bounds: T, compiler.misc.type.captureof: 1, ?, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))} 7.6 T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))} 7.7 T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?))} 7.8 3 errors
8.1 --- a/test/tools/javac/diags/examples/CantApplyDiamond1.java Tue Feb 12 13:36:56 2013 +0000 8.2 +++ b/test/tools/javac/diags/examples/CantApplyDiamond1.java Tue Feb 12 19:25:09 2013 +0000 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -23,7 +23,7 @@ 8.11 8.12 // key: compiler.err.prob.found.req 8.13 // key: compiler.misc.cant.apply.diamond.1 8.14 -// key: compiler.misc.inferred.do.not.conform.to.upper.bounds 8.15 +// key: compiler.misc.incompatible.eq.upper.bounds 8.16 // key: compiler.misc.diamond 8.17 8.18 class CantApplyDiamond1<X> {
9.1 --- a/test/tools/javac/diags/examples/InferredDoNotConformToEq.java Tue Feb 12 13:36:56 2013 +0000 9.2 +++ b/test/tools/javac/diags/examples/InferredDoNotConformToEq.java Tue Feb 12 19:25:09 2013 +0000 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -23,6 +23,7 @@ 9.11 9.12 // key: compiler.err.cant.apply.symbol 9.13 // key: compiler.misc.inferred.do.not.conform.to.eq.bounds 9.14 +// options: -source 7 -Xlint:-options 9.15 9.16 import java.util.*; 9.17
10.1 --- a/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java Tue Feb 12 13:36:56 2013 +0000 10.2 +++ b/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java Tue Feb 12 19:25:09 2013 +0000 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -23,6 +23,7 @@ 10.11 10.12 // key: compiler.err.cant.apply.symbol 10.13 // key: compiler.misc.inferred.do.not.conform.to.upper.bounds 10.14 +// options: -source 7 -Xlint:-options 10.15 10.16 import java.util.*; 10.17
11.1 --- a/test/tools/javac/diags/examples/WhereFreshTvar.java Tue Feb 12 13:36:56 2013 +0000 11.2 +++ b/test/tools/javac/diags/examples/WhereFreshTvar.java Tue Feb 12 19:25:09 2013 +0000 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -24,7 +24,7 @@ 11.11 // key: compiler.misc.where.fresh.typevar 11.12 // key: compiler.misc.where.description.typevar 11.13 // key: compiler.err.prob.found.req 11.14 -// key: compiler.misc.inferred.do.not.conform.to.upper.bounds 11.15 +// key: compiler.misc.inconvertible.types 11.16 // options: -XDdiags=where,simpleNames 11.17 // run: simple 11.18 11.19 @@ -33,5 +33,5 @@ 11.20 class WhereFreshTvar { 11.21 <T extends List<T>> T m() {} 11.22 11.23 - { List<String> ls = m(); } 11.24 + { Object o = (List<String>)m(); } 11.25 }
12.1 --- a/test/tools/javac/generics/7015430/T7015430.out Tue Feb 12 13:36:56 2013 +0000 12.2 +++ b/test/tools/javac/generics/7015430/T7015430.out Tue Feb 12 19:25:09 2013 +0000 12.3 @@ -1,14 +1,14 @@ 12.4 -T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E> 12.5 +T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception> 12.6 T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430 12.7 T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException> 12.8 T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430 12.9 -T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E> 12.10 +T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception> 12.11 T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430 12.12 T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException> 12.13 T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430 12.14 T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException> 12.15 T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430 12.16 -T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E> 12.17 +T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception> 12.18 T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430 12.19 T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception 12.20 T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
13.1 --- a/test/tools/javac/generics/7151802/T7151802.out Tue Feb 12 13:36:56 2013 +0000 13.2 +++ b/test/tools/javac/generics/7151802/T7151802.out Tue Feb 12 19:25:09 2013 +0000 13.3 @@ -1,5 +1,5 @@ 13.4 T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802 13.5 -T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<Z> 13.6 +T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.Object> 13.7 T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo<Z>, T7151802.Foo, kindname.class, T7151802 13.8 T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802 13.9 T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.String>
14.1 --- a/test/tools/javac/generics/diamond/neg/Neg06.out Tue Feb 12 13:36:56 2013 +0000 14.2 +++ b/test/tools/javac/generics/diamond/neg/Neg06.out Tue Feb 12 19:25:09 2013 +0000 14.3 @@ -1,2 +1,2 @@ 14.4 -Neg06.java:16:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)) 14.5 +Neg06.java:16:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) 14.6 1 error
15.1 --- a/test/tools/javac/generics/inference/6278587/T6278587Neg.java Tue Feb 12 13:36:56 2013 +0000 15.2 +++ b/test/tools/javac/generics/inference/6278587/T6278587Neg.java Tue Feb 12 19:25:09 2013 +0000 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -23,10 +23,11 @@ 15.11 15.12 /* 15.13 * @test 15.14 - * @bug 6278587 15.15 + * @bug 6278587 8007464 15.16 * @summary Inference broken for subtypes of subtypes of F-bounded types 15.17 * @author Peter von der Ah\u00e9 15.18 - * @compile/fail T6278587Neg.java 15.19 + * @compile/fail -source 7 T6278587Neg.java 15.20 + * @compile T6278587Neg.java 15.21 */ 15.22 15.23 public abstract class T6278587Neg {
16.1 --- a/test/tools/javac/generics/inference/6638712/T6638712d.out Tue Feb 12 13:36:56 2013 +0000 16.2 +++ b/test/tools/javac/generics/inference/6638712/T6638712d.out Tue Feb 12 19:25:09 2013 +0000 16.3 @@ -1,2 +1,2 @@ 16.4 -T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.String, java.lang.Integer) 16.5 +T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.incompatible.eq.lower.bounds: U, java.lang.String, java.lang.Integer) 16.6 1 error
17.1 --- a/test/tools/javac/generics/inference/6638712/T6638712e.out Tue Feb 12 13:36:56 2013 +0000 17.2 +++ b/test/tools/javac/generics/inference/6638712/T6638712e.out Tue Feb 12 19:25:09 2013 +0000 17.3 @@ -1,2 +1,2 @@ 17.4 -T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Boolean,java.lang.Object) 17.5 +T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Boolean,java.lang.Object) 17.6 1 error
18.1 --- a/test/tools/javac/generics/inference/7154127/T7154127.java Tue Feb 12 13:36:56 2013 +0000 18.2 +++ b/test/tools/javac/generics/inference/7154127/T7154127.java Tue Feb 12 19:25:09 2013 +0000 18.3 @@ -1,8 +1,9 @@ 18.4 /** 18.5 * @test /nodynamiccopyright/ 18.6 - * @bug 7154127 18.7 + * @bug 7154127 8007464 18.8 * @summary Inference cleanup: remove bound check analysis from visitors in Types.java 18.9 - * @compile/fail/ref=T7154127.out -XDrawDiagnostics T7154127.java 18.10 + * @compile/fail/ref=T7154127.out -Xlint:-options -source 7 -XDrawDiagnostics T7154127.java 18.11 + * @compile T7154127.java 18.12 */ 18.13 class T7154127 { 18.14
19.1 --- a/test/tools/javac/generics/inference/7154127/T7154127.out Tue Feb 12 13:36:56 2013 +0000 19.2 +++ b/test/tools/javac/generics/inference/7154127/T7154127.out Tue Feb 12 19:25:09 2013 +0000 19.3 @@ -1,2 +1,2 @@ 19.4 -T7154127.java:19:49: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: Y, T7154127.B<U>,T7154127.D) 19.5 +T7154127.java:20:49: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: Y, T7154127.B<U>,T7154127.D) 19.6 1 error
20.1 --- a/test/tools/javac/generics/inference/7177306/T7177306a.out Tue Feb 12 13:36:56 2013 +0000 20.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306a.out Tue Feb 12 19:25:09 2013 +0000 20.3 @@ -1,4 +1,4 @@ 20.4 -T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<E> 20.5 +T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<java.lang.Object> 20.6 T7177306a.java:13:33: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, java.util.List<E>, java.util.List, kindname.class, T7177306a 20.7 T7177306a.java:13:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7177306a, T7177306a<java.lang.Object> 20.8 - compiler.err.warnings.and.werror
21.1 --- a/test/tools/javac/generics/inference/7177306/T7177306e.java Tue Feb 12 13:36:56 2013 +0000 21.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306e.java Tue Feb 12 19:25:09 2013 +0000 21.3 @@ -1,8 +1,9 @@ 21.4 /** 21.5 * @test /nodynamiccopyright/ 21.6 - * @bug 7177306 21.7 + * @bug 7177306 8007464 21.8 * @summary Regression: unchecked method call does not erase return type 21.9 - * @compile/fail/ref=T7177306e.out -XDrawDiagnostics T7177306e.java 21.10 + * @compile/fail/ref=T7177306e.out -source 7 -Xlint:-options -XDrawDiagnostics T7177306e.java 21.11 + * @compile/fail T7177306e.java 21.12 */ 21.13 21.14 import java.util.List;
22.1 --- a/test/tools/javac/generics/inference/7177306/T7177306e.out Tue Feb 12 13:36:56 2013 +0000 22.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306e.out Tue Feb 12 19:25:09 2013 +0000 22.3 @@ -1,2 +1,2 @@ 22.4 -T7177306e.java:15:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>) 22.5 +T7177306e.java:16:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>) 22.6 1 error
23.1 --- a/test/tools/javac/generics/odersky/BadTest4.java Tue Feb 12 13:36:56 2013 +0000 23.2 +++ b/test/tools/javac/generics/odersky/BadTest4.java Tue Feb 12 19:25:09 2013 +0000 23.3 @@ -23,11 +23,12 @@ 23.4 23.5 /* 23.6 * @test 23.7 - * @ bug 23.8 + * @bug 8007464 23.9 * @summary Negative regression test from odersky 23.10 * @author odersky 23.11 * 23.12 - * @compile/fail BadTest4.java 23.13 + * @compile/fail -source 7 BadTest4.java 23.14 + * @compile BadTest4.java 23.15 */ 23.16 23.17 class BadTest4 {
24.1 --- a/test/tools/javac/lambda/TargetType14.out Tue Feb 12 13:36:56 2013 +0000 24.2 +++ b/test/tools/javac/lambda/TargetType14.out Tue Feb 12 19:25:09 2013 +0000 24.3 @@ -1,2 +1,2 @@ 24.4 -TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String) 24.5 +TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.lower.bounds: X, java.lang.Integer, java.lang.String) 24.6 1 error
25.1 --- a/test/tools/javac/lambda/TargetType20.java Tue Feb 12 13:36:56 2013 +0000 25.2 +++ b/test/tools/javac/lambda/TargetType20.java Tue Feb 12 19:25:09 2013 +0000 25.3 @@ -1,10 +1,33 @@ 25.4 /* 25.5 - * @test /nodynamiccopyright/ 25.6 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 25.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.8 + * 25.9 + * This code is free software; you can redistribute it and/or modify it 25.10 + * under the terms of the GNU General Public License version 2 only, as 25.11 + * published by the Free Software Foundation. 25.12 + * 25.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 25.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25.16 + * version 2 for more details (a copy is included in the LICENSE file that 25.17 + * accompanied this code). 25.18 + * 25.19 + * You should have received a copy of the GNU General Public License version 25.20 + * 2 along with this work; if not, write to the Free Software Foundation, 25.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 25.22 + * 25.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 25.24 + * or visit www.oracle.com if you need additional information or have any 25.25 + * questions. 25.26 + */ 25.27 + 25.28 +/* 25.29 + * @test 25.30 * @bug 8003280 25.31 * @summary Add lambda tests 25.32 * complex case of lambda return type that depends on generic method 25.33 * inference variable 25.34 - * @compile/fail/ref=TargetType20.out -XDrawDiagnostics TargetType20.java 25.35 + * @compile -XDrawDiagnostics TargetType20.java 25.36 */ 25.37 import java.util.*; 25.38
26.1 --- a/test/tools/javac/lambda/TargetType20.out Tue Feb 12 13:36:56 2013 +0000 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,2 +0,0 @@ 26.4 -TargetType20.java:19:10: compiler.err.cant.apply.symbol: kindname.method, call, TargetType20.SAM2<Z>,TargetType20.SAM2<Z>, @428,@459, kindname.class, TargetType20.Test, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object) 26.5 -1 error
27.1 --- a/test/tools/javac/lambda/TargetType28.out Tue Feb 12 13:36:56 2013 +0000 27.2 +++ b/test/tools/javac/lambda/TargetType28.out Tue Feb 12 19:25:09 2013 +0000 27.3 @@ -1,3 +1,2 @@ 27.4 -TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.String) 27.5 -TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.Integer) 27.6 -2 errors 27.7 +TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String,X, java.lang.Object,java.lang.Number) 27.8 +1 error
28.1 --- a/test/tools/javac/lambda/TargetType50.java Tue Feb 12 13:36:56 2013 +0000 28.2 +++ b/test/tools/javac/lambda/TargetType50.java Tue Feb 12 19:25:09 2013 +0000 28.3 @@ -1,9 +1,32 @@ 28.4 /* 28.5 - * @test /nodynamiccopyright/ 28.6 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 28.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 + * 28.9 + * This code is free software; you can redistribute it and/or modify it 28.10 + * under the terms of the GNU General Public License version 2 only, as 28.11 + * published by the Free Software Foundation. 28.12 + * 28.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 28.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 28.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 28.16 + * version 2 for more details (a copy is included in the LICENSE file that 28.17 + * accompanied this code). 28.18 + * 28.19 + * You should have received a copy of the GNU General Public License version 28.20 + * 2 along with this work; if not, write to the Free Software Foundation, 28.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28.22 + * 28.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28.24 + * or visit www.oracle.com if you need additional information or have any 28.25 + * questions. 28.26 + */ 28.27 + 28.28 +/* 28.29 + * @test 28.30 * @bug 8003280 28.31 * @summary Add lambda tests 28.32 * bad stuck check for method reference leads to javac crash 28.33 - * @compile/fail/ref=TargetType50.out -XDrawDiagnostics TargetType50.java 28.34 + * @compile TargetType50.java 28.35 */ 28.36 import java.util.*; 28.37 28.38 @@ -17,7 +40,7 @@ 28.39 static <Z> Sink<Z> make() { return null; } 28.40 } 28.41 28.42 - <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) { } 28.43 + <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) { return null; } 28.44 28.45 void test() { 28.46 List<?> l1 = m(Sink::new);
29.1 --- a/test/tools/javac/lambda/TargetType50.out Tue Feb 12 13:36:56 2013 +0000 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,3 +0,0 @@ 29.4 -TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>) 29.5 -TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>) 29.6 -2 errors
30.1 --- a/test/tools/javac/lambda/TargetType51.java Tue Feb 12 13:36:56 2013 +0000 30.2 +++ b/test/tools/javac/lambda/TargetType51.java Tue Feb 12 19:25:09 2013 +0000 30.3 @@ -23,7 +23,9 @@ 30.4 30.5 /* 30.6 * @test 30.7 - * @summary smoke test for combinator-like stuck analysis 30.8 + * @bug 8005244 30.9 + * @summary Implement overload resolution as per latest spec EDR 30.10 + * smoke test for combinator-like stuck analysis 30.11 * @author Maurizio Cimadamore 30.12 * @compile TargetType51.java 30.13 */
31.1 --- a/test/tools/javac/lambda/TargetType52.java Tue Feb 12 13:36:56 2013 +0000 31.2 +++ b/test/tools/javac/lambda/TargetType52.java Tue Feb 12 19:25:09 2013 +0000 31.3 @@ -1,6 +1,8 @@ 31.4 /* 31.5 * @test /nodynamiccopyright/ 31.6 - * @summary uncatched sam conversion failure exception lead to javac crash 31.7 + * @bug 8005244 31.8 + * @summary Implement overload resolution as per latest spec EDR 31.9 + * uncatched sam conversion failure exception lead to javac crash 31.10 * @compile/fail/ref=TargetType52.out -XDrawDiagnostics TargetType52.java 31.11 */ 31.12 class TargetType52 {
32.1 --- a/test/tools/javac/lambda/TargetType52.out Tue Feb 12 13:36:56 2013 +0000 32.2 +++ b/test/tools/javac/lambda/TargetType52.out Tue Feb 12 19:25:09 2013 +0000 32.3 @@ -1,2 +1,2 @@ 32.4 -TargetType52.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @444, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>)) 32.5 +TargetType52.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @525, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>)) 32.6 1 error
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/tools/javac/lambda/TargetType53.java Tue Feb 12 19:25:09 2013 +0000 33.3 @@ -0,0 +1,47 @@ 33.4 +/* 33.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. 33.11 + * 33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 + * version 2 for more details (a copy is included in the LICENSE file that 33.16 + * accompanied this code). 33.17 + * 33.18 + * You should have received a copy of the GNU General Public License version 33.19 + * 2 along with this work; if not, write to the Free Software Foundation, 33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 + * 33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 + * or visit www.oracle.com if you need additional information or have any 33.24 + * questions. 33.25 + */ 33.26 + 33.27 +/* 33.28 + * @test 33.29 + * @bug 8007464 33.30 + * @summary Add graph inference support 33.31 + * smoke test for graph inference 33.32 + * @ignore awaits stream API: 800NNNN 33.33 + * @compile TargetType53.java 33.34 + */ 33.35 +import java.util.*; 33.36 +import java.util.stream.*; 33.37 +import java.util.function.*; 33.38 + 33.39 +class TargetType53 { 33.40 + 33.41 + <P> List<List<P>> perm(List<P> l) { return null; } 33.42 + 33.43 + void g(List<List<UnaryOperator<IntStream>>> l) { } 33.44 + 33.45 + void test() { 33.46 + List<List<UnaryOperator<IntStream>>> l = 33.47 + perm(Arrays.asList(s -> s.sorted())); 33.48 + g(perm(Arrays.asList(s -> s.sorted()))); 33.49 + } 33.50 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/test/tools/javac/lambda/TargetType54.java Tue Feb 12 19:25:09 2013 +0000 34.3 @@ -0,0 +1,45 @@ 34.4 +/* 34.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.7 + * 34.8 + * This code is free software; you can redistribute it and/or modify it 34.9 + * under the terms of the GNU General Public License version 2 only, as 34.10 + * published by the Free Software Foundation. 34.11 + * 34.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 34.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 34.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 34.15 + * version 2 for more details (a copy is included in the LICENSE file that 34.16 + * accompanied this code). 34.17 + * 34.18 + * You should have received a copy of the GNU General Public License version 34.19 + * 2 along with this work; if not, write to the Free Software Foundation, 34.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 34.21 + * 34.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 34.23 + * or visit www.oracle.com if you need additional information or have any 34.24 + * questions. 34.25 + */ 34.26 + 34.27 +/* 34.28 + * @test 34.29 + * @bug 8007464 34.30 + * @summary Add graph inference support 34.31 + * smoke test for graph inference 34.32 + * @ignore awaits stream API: 800NNNN 34.33 + * @compile TargetType54.java 34.34 + */ 34.35 +import java.util.stream.*; 34.36 +import java.util.*; 34.37 +import static java.util.stream.Collectors.*; 34.38 + 34.39 +class TargetType54 { 34.40 + void test(Stream<Integer> si) { 34.41 + List<Integer> l1 = si.collect(toList()); 34.42 + List<Integer> l2 = si.collect(toCollection(ArrayList::new)); 34.43 + m(si.collect(toList())); 34.44 + m(si.collect(toCollection(ArrayList::new))); 34.45 + } 34.46 + 34.47 + void m(List<Integer> l) { } 34.48 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/test/tools/javac/lambda/TargetType55.java Tue Feb 12 19:25:09 2013 +0000 35.3 @@ -0,0 +1,42 @@ 35.4 +/* 35.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 35.7 + * 35.8 + * This code is free software; you can redistribute it and/or modify it 35.9 + * under the terms of the GNU General Public License version 2 only, as 35.10 + * published by the Free Software Foundation. 35.11 + * 35.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 35.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 35.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 35.15 + * version 2 for more details (a copy is included in the LICENSE file that 35.16 + * accompanied this code). 35.17 + * 35.18 + * You should have received a copy of the GNU General Public License version 35.19 + * 2 along with this work; if not, write to the Free Software Foundation, 35.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 35.21 + * 35.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 35.23 + * or visit www.oracle.com if you need additional information or have any 35.24 + * questions. 35.25 + */ 35.26 + 35.27 +/* 35.28 + * @test 35.29 + * @bug 8007464 35.30 + * @summary Add graph inference 35.31 + * support smoke test for graph inference 35.32 + * @compile TargetType55.java 35.33 + */ 35.34 +import java.util.function.*; 35.35 + 35.36 +class TargetType55 { 35.37 + 35.38 + <R> void m(Function<Integer, R> collector) { } 35.39 + 35.40 + <T, D> Function<T, Integer> g(D d, BinaryOperator<D> reducer) { return null; } 35.41 + 35.42 + public void test() { 35.43 + m(g((Integer)null, (x,y)->1)); 35.44 + } 35.45 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/test/tools/javac/lambda/TargetType56.java Tue Feb 12 19:25:09 2013 +0000 36.3 @@ -0,0 +1,40 @@ 36.4 +/* 36.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.7 + * 36.8 + * This code is free software; you can redistribute it and/or modify it 36.9 + * under the terms of the GNU General Public License version 2 only, as 36.10 + * published by the Free Software Foundation. 36.11 + * 36.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 36.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 36.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36.15 + * version 2 for more details (a copy is included in the LICENSE file that 36.16 + * accompanied this code). 36.17 + * 36.18 + * You should have received a copy of the GNU General Public License version 36.19 + * 2 along with this work; if not, write to the Free Software Foundation, 36.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 36.21 + * 36.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 36.23 + * or visit www.oracle.com if you need additional information or have any 36.24 + * questions. 36.25 + */ 36.26 + 36.27 +/* 36.28 + * @test 36.29 + * @bug 8007464 36.30 + * @summary Add graph inference support 36.31 + * smoke test for graph inference 36.32 + * @compile TargetType56.java 36.33 + */ 36.34 +class TargetType56 { 36.35 + <Z> Z m(Z z) { return null; } 36.36 + 36.37 + void test() { 36.38 + double d1 = m(1); 36.39 + double d2 = m((Integer)null); 36.40 + double d3 = m(m(1)); 36.41 + double d4 = m(m((Integer)null)); 36.42 + } 36.43 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/test/tools/javac/lambda/TargetType57.java Tue Feb 12 19:25:09 2013 +0000 37.3 @@ -0,0 +1,20 @@ 37.4 +/* 37.5 + * @test /nodynamiccopyright/ 37.6 + * @bug 8007464 37.7 + * @summary Add graph inference support 37.8 + * more smoke tests for graph inference 37.9 + * @compile/fail/ref=TargetType57.out -XDrawDiagnostics TargetType57.java 37.10 + */ 37.11 +import java.util.*; 37.12 +import java.util.function.*; 37.13 + 37.14 +class TargetType57 { 37.15 + 37.16 + void test(List<Integer> list) { 37.17 + m(list, s -> s.intValue(), s -> s.nonExistentMethod()); 37.18 + } 37.19 + 37.20 + <U, R, S_IN, S_OUT> R m(List<S_IN> list, 37.21 + Function<S_IN, S_OUT> f1, 37.22 + Function<S_OUT, R> f2) { return null; } 37.23 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/test/tools/javac/lambda/TargetType57.out Tue Feb 12 19:25:09 2013 +0000 38.3 @@ -0,0 +1,2 @@ 38.4 +TargetType57.java:14:42: compiler.err.cant.resolve.location.args: kindname.method, nonExistentMethod, , , (compiler.misc.location.1: kindname.variable, s, java.lang.Integer) 38.5 +1 error
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/test/tools/javac/lambda/TargetType58.java Tue Feb 12 19:25:09 2013 +0000 39.3 @@ -0,0 +1,46 @@ 39.4 +/* 39.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 39.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 39.7 + * 39.8 + * This code is free software; you can redistribute it and/or modify it 39.9 + * under the terms of the GNU General Public License version 2 only, as 39.10 + * published by the Free Software Foundation. 39.11 + * 39.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 39.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 39.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 39.15 + * version 2 for more details (a copy is included in the LICENSE file that 39.16 + * accompanied this code). 39.17 + * 39.18 + * You should have received a copy of the GNU General Public License version 39.19 + * 2 along with this work; if not, write to the Free Software Foundation, 39.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 39.21 + * 39.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 39.23 + * or visit www.oracle.com if you need additional information or have any 39.24 + * questions. 39.25 + */ 39.26 + 39.27 +/* 39.28 + * @test 39.29 + * @bug 8007464 39.30 + * @summary Add graph inference support 39.31 + * more smoke tests for graph inference 39.32 + * @ignore awaits stream API: 800NNNN 39.33 + * @compile TargetType58.java 39.34 + */ 39.35 +import java.util.*; 39.36 +import java.util.function.*; 39.37 +import java.util.stream.*; 39.38 + 39.39 +class TargetType58 { 39.40 + 39.41 + void test(List<Integer> li) { 39.42 + g(li, s -> s.substream(200), Collections.emptyList()); 39.43 + } 39.44 + 39.45 + <T, U, S_OUT extends Stream<U>, 39.46 + I extends Iterable<U>> Collection<U> g(Collection<T> coll, Function<Stream<T>, S_OUT> f, I i) { 39.47 + return null; 39.48 + } 39.49 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/test/tools/javac/lambda/TargetType59.java Tue Feb 12 19:25:09 2013 +0000 40.3 @@ -0,0 +1,49 @@ 40.4 +/* 40.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 40.7 + * 40.8 + * This code is free software; you can redistribute it and/or modify it 40.9 + * under the terms of the GNU General Public License version 2 only, as 40.10 + * published by the Free Software Foundation. 40.11 + * 40.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 40.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 40.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 40.15 + * version 2 for more details (a copy is included in the LICENSE file that 40.16 + * accompanied this code). 40.17 + * 40.18 + * You should have received a copy of the GNU General Public License version 40.19 + * 2 along with this work; if not, write to the Free Software Foundation, 40.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 40.21 + * 40.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 40.23 + * or visit www.oracle.com if you need additional information or have any 40.24 + * questions. 40.25 + */ 40.26 + 40.27 +/* 40.28 + * @test 40.29 + * @bug 8007464 40.30 + * @summary Add graph inference support 40.31 + * more smoke tests for graph inference 40.32 + * @ignore awaits stream API: 800NNNN 40.33 + * @compile TargetType59.java 40.34 + */ 40.35 +import java.util.*; 40.36 +import java.util.function.*; 40.37 +import java.util.stream.*; 40.38 + 40.39 +class TargetType59 { 40.40 + 40.41 + <T, R> Collector<T, R> m(Supplier<? extends R> supplier, BiConsumer<R, T> accumulator) { 40.42 + return null; 40.43 + } 40.44 + 40.45 + <T, C extends Collection<T>> Collector<T,C> test1(Supplier<C> collectionFactory) { 40.46 + return m(collectionFactory, Collection::add); 40.47 + } 40.48 + 40.49 + Collector<String, StringBuilder> test2(Supplier<StringBuilder> sb) { 40.50 + return m(sb, StringBuilder::append); 40.51 + } 40.52 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/tools/javac/lambda/TargetType61.java Tue Feb 12 19:25:09 2013 +0000 41.3 @@ -0,0 +1,47 @@ 41.4 +/* 41.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.7 + * 41.8 + * This code is free software; you can redistribute it and/or modify it 41.9 + * under the terms of the GNU General Public License version 2 only, as 41.10 + * published by the Free Software Foundation. 41.11 + * 41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 41.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 41.15 + * version 2 for more details (a copy is included in the LICENSE file that 41.16 + * accompanied this code). 41.17 + * 41.18 + * You should have received a copy of the GNU General Public License version 41.19 + * 2 along with this work; if not, write to the Free Software Foundation, 41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 41.21 + * 41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 41.23 + * or visit www.oracle.com if you need additional information or have any 41.24 + * questions. 41.25 + */ 41.26 + 41.27 +/* 41.28 + * @test 41.29 + * @bug 8007464 41.30 + * @summary Add graph inference support 41.31 + * check that new wildcards inference strategy doesn't run into 7190296 41.32 + * @compile TargetType61.java 41.33 + */ 41.34 +class TargetType61 { 41.35 + 41.36 + interface Stream<T> { 41.37 + void forEach(Sink<? super T> sink); 41.38 + } 41.39 + 41.40 + interface Sink<T> { 41.41 + void put(T t); 41.42 + } 41.43 + 41.44 + public boolean add(CharSequence s) { return false; } 41.45 + 41.46 + public void addAll(Stream<? extends CharSequence> stream) { 41.47 + stream.forEach(this::add); 41.48 + stream.forEach(e -> { add(e); }); 41.49 + } 41.50 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/test/tools/javac/lambda/TargetType62.java Tue Feb 12 19:25:09 2013 +0000 42.3 @@ -0,0 +1,46 @@ 42.4 +/* 42.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42.7 + * 42.8 + * This code is free software; you can redistribute it and/or modify it 42.9 + * under the terms of the GNU General Public License version 2 only, as 42.10 + * published by the Free Software Foundation. 42.11 + * 42.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 42.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 42.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 42.15 + * version 2 for more details (a copy is included in the LICENSE file that 42.16 + * accompanied this code). 42.17 + * 42.18 + * You should have received a copy of the GNU General Public License version 42.19 + * 2 along with this work; if not, write to the Free Software Foundation, 42.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 42.21 + * 42.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 42.23 + * or visit www.oracle.com if you need additional information or have any 42.24 + * questions. 42.25 + */ 42.26 + 42.27 +/* 42.28 + * @test 42.29 + * @bug 8007464 42.30 + * @summary Add graph inference support 42.31 + * check that new wildcards inference strategy doesn't run into 7190296 42.32 + * @ignore awaits stream API: 800NNNN 42.33 + * @compile TargetType62.java 42.34 + */ 42.35 +import java.util.*; 42.36 +import java.util.function.*; 42.37 +import java.util.stream.*; 42.38 + 42.39 +class TargetType61 { 42.40 + 42.41 + Collector test(Function<Integer, Integer> classifier) { 42.42 + return g(classifier, TreeMap::new, m(HashSet::new)); 42.43 + } 42.44 + 42.45 + <R> Collector<Integer, R> m(Supplier<R> s) { return null; } 42.46 + 42.47 + <T, K, D, M extends Map<K, D>> 42.48 + Collector<T, M> g(Function<T, K> classifier, Supplier<M> mapFactory, Collector<T, D> downstream) { return null; } 42.49 +}