langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
changeset 31937 ad43a6639c4a
parent 30014 fc1f2b200c1f
child 32709 55d136799f79
equal deleted inserted replaced
31936:02f1cfc234a0 31937:ad43a6639c4a
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.javac.comp;
    26 package com.sun.tools.javac.comp;
    27 
    27 
    28 import com.sun.tools.javac.code.Type.TypeMapping;
       
    29 import com.sun.tools.javac.tree.JCTree;
    28 import com.sun.tools.javac.tree.JCTree;
    30 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
    29 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
    31 import com.sun.tools.javac.tree.TreeInfo;
    30 import com.sun.tools.javac.tree.TreeInfo;
    32 import com.sun.tools.javac.util.*;
    31 import com.sun.tools.javac.util.*;
    33 import com.sun.tools.javac.util.GraphUtils.DottableNode;
    32 import com.sun.tools.javac.util.GraphUtils.DottableNode;
   110         Options options = Options.instance(context);
   109         Options options = Options.instance(context);
   111         allowGraphInference = Source.instance(context).allowGraphInference()
   110         allowGraphInference = Source.instance(context).allowGraphInference()
   112                 && options.isUnset("useLegacyInference");
   111                 && options.isUnset("useLegacyInference");
   113         dependenciesFolder = options.get("dumpInferenceGraphsTo");
   112         dependenciesFolder = options.get("dumpInferenceGraphsTo");
   114         pendingGraphs = List.nil();
   113         pendingGraphs = List.nil();
       
   114 
       
   115         emptyContext = new InferenceContext(this, List.<Type>nil());
   115     }
   116     }
   116 
   117 
   117     /** A value for prototypes that admit any type, including polymorphic ones. */
   118     /** A value for prototypes that admit any type, including polymorphic ones. */
   118     public static final Type anyPoly = new JCNoType();
   119     public static final Type anyPoly = new JCNoType();
   119 
   120 
   168                             boolean allowBoxing,
   169                             boolean allowBoxing,
   169                             boolean useVarargs,
   170                             boolean useVarargs,
   170                             Resolve.MethodResolutionContext resolveContext,
   171                             Resolve.MethodResolutionContext resolveContext,
   171                             Warner warn) throws InferenceException {
   172                             Warner warn) throws InferenceException {
   172         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
   173         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
   173         final InferenceContext inferenceContext = new InferenceContext(tvars);  //B0
   174         final InferenceContext inferenceContext = new InferenceContext(this, tvars);  //B0
   174         inferenceException.clear();
   175         inferenceException.clear();
   175         try {
   176         try {
   176             DeferredAttr.DeferredAttrContext deferredAttrContext =
   177             DeferredAttr.DeferredAttrContext deferredAttrContext =
   177                         resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
   178                         resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
   178 
   179 
   408     }
   409     }
   409 
   410 
   410     /**
   411     /**
   411       * Infer cyclic inference variables as described in 15.12.2.8.
   412       * Infer cyclic inference variables as described in 15.12.2.8.
   412       */
   413       */
   413     private void instantiateAsUninferredVars(List<Type> vars, InferenceContext inferenceContext) {
   414     void instantiateAsUninferredVars(List<Type> vars, InferenceContext inferenceContext) {
   414         ListBuffer<Type> todo = new ListBuffer<>();
   415         ListBuffer<Type> todo = new ListBuffer<>();
   415         //step 1 - create fresh tvars
   416         //step 1 - create fresh tvars
   416         for (Type t : vars) {
   417         for (Type t : vars) {
   417             UndetVar uv = (UndetVar)inferenceContext.asUndetVar(t);
   418             UndetVar uv = (UndetVar)inferenceContext.asUndetVar(t);
   418             List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
   419             List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
   526             //(this means the target contains no wildcards!)
   527             //(this means the target contains no wildcards!)
   527             return funcInterface;
   528             return funcInterface;
   528         } else {
   529         } else {
   529             Type formalInterface = funcInterface.tsym.type;
   530             Type formalInterface = funcInterface.tsym.type;
   530             InferenceContext funcInterfaceContext =
   531             InferenceContext funcInterfaceContext =
   531                     new InferenceContext(funcInterface.tsym.type.getTypeArguments());
   532                     new InferenceContext(this, funcInterface.tsym.type.getTypeArguments());
   532 
   533 
   533             Assert.check(paramTypes != null);
   534             Assert.check(paramTypes != null);
   534             //get constraints from explicit params (this is done by
   535             //get constraints from explicit params (this is done by
   535             //checking that explicit param types are equal to the ones
   536             //checking that explicit param types are equal to the ones
   536             //in the functional interface descriptors)
   537             //in the functional interface descriptors)
   708          * Performs basic bound checking - i.e. is the instantiated type for a given
   709          * Performs basic bound checking - i.e. is the instantiated type for a given
   709          * inference variable compatible with its bounds?
   710          * inference variable compatible with its bounds?
   710          */
   711          */
   711         CHECK_BOUNDS() {
   712         CHECK_BOUNDS() {
   712             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   713             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   713                 Infer infer = inferenceContext.infer();
   714                 Infer infer = inferenceContext.infer;
   714                 uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types);
   715                 uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types);
   715                 infer.checkCompatibleUpperBounds(uv, inferenceContext);
   716                 infer.checkCompatibleUpperBounds(uv, inferenceContext);
   716                 if (uv.inst != null) {
   717                 if (uv.inst != null) {
   717                     Type inst = uv.inst;
   718                     Type inst = uv.inst;
   718                     for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   719                     for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   744          * inference routine that is designed as to maximize compatibility with JDK 7.
   745          * inference routine that is designed as to maximize compatibility with JDK 7.
   745          * Note: this is not used in graph mode.
   746          * Note: this is not used in graph mode.
   746          */
   747          */
   747         EQ_CHECK_LEGACY() {
   748         EQ_CHECK_LEGACY() {
   748             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   749             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   749                 Infer infer = inferenceContext.infer();
   750                 Infer infer = inferenceContext.infer;
   750                 Type eq = null;
   751                 Type eq = null;
   751                 for (Type e : uv.getBounds(InferenceBound.EQ)) {
   752                 for (Type e : uv.getBounds(InferenceBound.EQ)) {
   752                     Assert.check(!inferenceContext.free(e));
   753                     Assert.check(!inferenceContext.free(e));
   753                     if (eq != null && !isSameType(e, eq, infer)) {
   754                     if (eq != null && !isSameType(e, eq, infer)) {
   754                         infer.reportBoundError(uv, BoundErrorKind.EQ);
   755                         infer.reportBoundError(uv, BoundErrorKind.EQ);
   778          * Check consistency of equality constraints.
   779          * Check consistency of equality constraints.
   779          */
   780          */
   780         EQ_CHECK() {
   781         EQ_CHECK() {
   781             @Override
   782             @Override
   782             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   783             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   783                 Infer infer = inferenceContext.infer();
   784                 Infer infer = inferenceContext.infer;
   784                 for (Type e : uv.getBounds(InferenceBound.EQ)) {
   785                 for (Type e : uv.getBounds(InferenceBound.EQ)) {
   785                     if (e.containsAny(inferenceContext.inferenceVars())) continue;
   786                     if (e.containsAny(inferenceContext.inferenceVars())) continue;
   786                     for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   787                     for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   787                         if (!isSubtype(e, inferenceContext.asUndetVar(u), warn, infer)) {
   788                         if (!isSubtype(e, inferenceContext.asUndetVar(u), warn, infer)) {
   788                             infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
   789                             infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
   805          * Given a bound set containing {@code alpha <: T} and {@code alpha :> S}
   806          * Given a bound set containing {@code alpha <: T} and {@code alpha :> S}
   806          * perform {@code S <: T} (which could lead to new bounds).
   807          * perform {@code S <: T} (which could lead to new bounds).
   807          */
   808          */
   808         CROSS_UPPER_LOWER() {
   809         CROSS_UPPER_LOWER() {
   809             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   810             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   810                 Infer infer = inferenceContext.infer();
   811                 Infer infer = inferenceContext.infer;
   811                 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
   812                 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
   812                     for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
   813                     for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
   813                         if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn , infer)) {
   814                         if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn , infer)) {
   814                             infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER_LOWER);
   815                             infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER_LOWER);
   815                         }
   816                         }
   828          * Given a bound set containing {@code alpha <: T} and {@code alpha == S}
   829          * Given a bound set containing {@code alpha <: T} and {@code alpha == S}
   829          * perform {@code S <: T} (which could lead to new bounds).
   830          * perform {@code S <: T} (which could lead to new bounds).
   830          */
   831          */
   831         CROSS_UPPER_EQ() {
   832         CROSS_UPPER_EQ() {
   832             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   833             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   833                 Infer infer = inferenceContext.infer();
   834                 Infer infer = inferenceContext.infer;
   834                 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
   835                 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
   835                     for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
   836                     for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
   836                         if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer)) {
   837                         if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer)) {
   837                             infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER_EQUAL);
   838                             infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER_EQUAL);
   838                         }
   839                         }
   851          * Given a bound set containing {@code alpha :> S} and {@code alpha == T}
   852          * Given a bound set containing {@code alpha :> S} and {@code alpha == T}
   852          * perform {@code S <: T} (which could lead to new bounds).
   853          * perform {@code S <: T} (which could lead to new bounds).
   853          */
   854          */
   854         CROSS_EQ_LOWER() {
   855         CROSS_EQ_LOWER() {
   855             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   856             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   856                 Infer infer = inferenceContext.infer();
   857                 Infer infer = inferenceContext.infer;
   857                 for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
   858                 for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
   858                     for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
   859                     for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
   859                         if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer)) {
   860                         if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer)) {
   860                             infer.reportBoundError(uv, BoundErrorKind.BAD_EQUAL_LOWER);
   861                             infer.reportBoundError(uv, BoundErrorKind.BAD_EQUAL_LOWER);
   861                         }
   862                         }
   876          * perform {@code T = S} (which could lead to new bounds).
   877          * perform {@code T = S} (which could lead to new bounds).
   877          */
   878          */
   878         CROSS_UPPER_UPPER() {
   879         CROSS_UPPER_UPPER() {
   879             @Override
   880             @Override
   880             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   881             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   881                 Infer infer = inferenceContext.infer();
   882                 Infer infer = inferenceContext.infer;
   882                 List<Type> boundList = uv.getBounds(InferenceBound.UPPER).stream()
   883                 List<Type> boundList = uv.getBounds(InferenceBound.UPPER).stream()
   883                         .collect(infer.types.closureCollector(true, infer.types::isSameType));
   884                         .collect(infer.types.closureCollector(true, infer.types::isSameType));
   884                 List<Type> boundListTail = boundList.tail;
   885                 List<Type> boundListTail = boundList.tail;
   885                 while (boundList.nonEmpty()) {
   886                 while (boundList.nonEmpty()) {
   886                     List<Type> tmpTail = boundListTail;
   887                     List<Type> tmpTail = boundListTail;
   926          * Given a bound set containing {@code alpha == S} and {@code alpha == T}
   927          * Given a bound set containing {@code alpha == S} and {@code alpha == T}
   927          * perform {@code S == T} (which could lead to new bounds).
   928          * perform {@code S == T} (which could lead to new bounds).
   928          */
   929          */
   929         CROSS_EQ_EQ() {
   930         CROSS_EQ_EQ() {
   930             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   931             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   931                 Infer infer = inferenceContext.infer();
   932                 Infer infer = inferenceContext.infer;
   932                 for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
   933                 for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
   933                     for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
   934                     for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
   934                         if (b1 != b2) {
   935                         if (b1 != b2) {
   935                             if (!isSameType(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), infer)) {
   936                             if (!isSameType(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), infer)) {
   936                                 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ);
   937                                 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ);
   950          * Given a bound set containing {@code alpha <: beta} propagate lower bounds
   951          * Given a bound set containing {@code alpha <: beta} propagate lower bounds
   951          * from alpha to beta; also propagate upper bounds from beta to alpha.
   952          * from alpha to beta; also propagate upper bounds from beta to alpha.
   952          */
   953          */
   953         PROP_UPPER() {
   954         PROP_UPPER() {
   954             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   955             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   955                 Infer infer = inferenceContext.infer();
   956                 Infer infer = inferenceContext.infer;
   956                 for (Type b : uv.getBounds(InferenceBound.UPPER)) {
   957                 for (Type b : uv.getBounds(InferenceBound.UPPER)) {
   957                     if (inferenceContext.inferenceVars().contains(b)) {
   958                     if (inferenceContext.inferenceVars().contains(b)) {
   958                         UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b);
   959                         UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b);
   959                         if (uv2.isCaptured()) continue;
   960                         if (uv2.isCaptured()) continue;
   960                         //alpha <: beta
   961                         //alpha <: beta
   982          * Given a bound set containing {@code alpha :> beta} propagate lower bounds
   983          * Given a bound set containing {@code alpha :> beta} propagate lower bounds
   983          * from beta to alpha; also propagate upper bounds from alpha to beta.
   984          * from beta to alpha; also propagate upper bounds from alpha to beta.
   984          */
   985          */
   985         PROP_LOWER() {
   986         PROP_LOWER() {
   986             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   987             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
   987                 Infer infer = inferenceContext.infer();
   988                 Infer infer = inferenceContext.infer;
   988                 for (Type b : uv.getBounds(InferenceBound.LOWER)) {
   989                 for (Type b : uv.getBounds(InferenceBound.LOWER)) {
   989                     if (inferenceContext.inferenceVars().contains(b)) {
   990                     if (inferenceContext.inferenceVars().contains(b)) {
   990                         UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b);
   991                         UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b);
   991                         if (uv2.isCaptured()) continue;
   992                         if (uv2.isCaptured()) continue;
   992                         //alpha :> beta
   993                         //alpha :> beta
  1014          * Given a bound set containing {@code alpha == beta} propagate lower/upper
  1015          * Given a bound set containing {@code alpha == beta} propagate lower/upper
  1015          * bounds from alpha to beta and back.
  1016          * bounds from alpha to beta and back.
  1016          */
  1017          */
  1017         PROP_EQ() {
  1018         PROP_EQ() {
  1018             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
  1019             public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
  1019                 Infer infer = inferenceContext.infer();
  1020                 Infer infer = inferenceContext.infer;
  1020                 for (Type b : uv.getBounds(InferenceBound.EQ)) {
  1021                 for (Type b : uv.getBounds(InferenceBound.EQ)) {
  1021                     if (inferenceContext.inferenceVars().contains(b)) {
  1022                     if (inferenceContext.inferenceVars().contains(b)) {
  1022                         UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b);
  1023                         UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b);
  1023                         if (uv2.isCaptured()) continue;
  1024                         if (uv2.isCaptured()) continue;
  1024                         //alpha == beta
  1025                         //alpha == beta
  1522          * bounds are merged together using lub().
  1523          * bounds are merged together using lub().
  1523          */
  1524          */
  1524         LOWER(InferenceBound.LOWER) {
  1525         LOWER(InferenceBound.LOWER) {
  1525             @Override
  1526             @Override
  1526             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1527             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1527                 Infer infer = inferenceContext.infer();
  1528                 Infer infer = inferenceContext.infer;
  1528                 List<Type> lobounds = filterBounds(uv, inferenceContext);
  1529                 List<Type> lobounds = filterBounds(uv, inferenceContext);
  1529                 //note: lobounds should have at least one element
  1530                 //note: lobounds should have at least one element
  1530                 Type owntype = lobounds.tail.tail == null  ? lobounds.head : infer.types.lub(lobounds);
  1531                 Type owntype = lobounds.tail.tail == null  ? lobounds.head : infer.types.lub(lobounds);
  1531                 if (owntype.isPrimitive() || owntype.hasTag(ERROR)) {
  1532                 if (owntype.isPrimitive() || owntype.hasTag(ERROR)) {
  1532                     throw infer.inferenceException
  1533                     throw infer.inferenceException
  1551                 if (t.getBounds(InferenceBound.EQ, InferenceBound.LOWER, InferenceBound.UPPER)
  1552                 if (t.getBounds(InferenceBound.EQ, InferenceBound.LOWER, InferenceBound.UPPER)
  1552                             .diff(t.getDeclaredBounds()).nonEmpty()) {
  1553                             .diff(t.getDeclaredBounds()).nonEmpty()) {
  1553                     //not an unbounded undet var
  1554                     //not an unbounded undet var
  1554                     return false;
  1555                     return false;
  1555                 }
  1556                 }
  1556                 Infer infer = inferenceContext.infer();
  1557                 Infer infer = inferenceContext.infer;
  1557                 for (Type db : t.getDeclaredBounds()) {
  1558                 for (Type db : t.getDeclaredBounds()) {
  1558                     if (t.isInterface()) continue;
  1559                     if (t.isInterface()) continue;
  1559                     if (infer.types.asSuper(infer.syms.runtimeExceptionType, db.tsym) != null) {
  1560                     if (infer.types.asSuper(infer.syms.runtimeExceptionType, db.tsym) != null) {
  1560                         //declared bound is a supertype of RuntimeException
  1561                         //declared bound is a supertype of RuntimeException
  1561                         return true;
  1562                         return true;
  1565                 return false;
  1566                 return false;
  1566             }
  1567             }
  1567 
  1568 
  1568             @Override
  1569             @Override
  1569             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1570             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1570                 return inferenceContext.infer().syms.runtimeExceptionType;
  1571                 return inferenceContext.infer.syms.runtimeExceptionType;
  1571             }
  1572             }
  1572         },
  1573         },
  1573         /**
  1574         /**
  1574          * Instantiate an inference variables using its (ground) upper bounds. Such
  1575          * Instantiate an inference variables using its (ground) upper bounds. Such
  1575          * bounds are merged together using glb().
  1576          * bounds are merged together using glb().
  1576          */
  1577          */
  1577         UPPER(InferenceBound.UPPER) {
  1578         UPPER(InferenceBound.UPPER) {
  1578             @Override
  1579             @Override
  1579             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1580             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1580                 Infer infer = inferenceContext.infer();
  1581                 Infer infer = inferenceContext.infer;
  1581                 List<Type> hibounds = filterBounds(uv, inferenceContext);
  1582                 List<Type> hibounds = filterBounds(uv, inferenceContext);
  1582                 //note: hibounds should have at least one element
  1583                 //note: hibounds should have at least one element
  1583                 Type owntype = hibounds.tail.tail == null  ? hibounds.head : infer.types.glb(hibounds);
  1584                 Type owntype = hibounds.tail.tail == null  ? hibounds.head : infer.types.glb(hibounds);
  1584                 if (owntype.isPrimitive() || owntype.hasTag(ERROR)) {
  1585                 if (owntype.isPrimitive() || owntype.hasTag(ERROR)) {
  1585                     throw infer.inferenceException
  1586                     throw infer.inferenceException
  1616                         !inferenceContext.free(t.getBounds(InferenceBound.UPPER, InferenceBound.LOWER));
  1617                         !inferenceContext.free(t.getBounds(InferenceBound.UPPER, InferenceBound.LOWER));
  1617             }
  1618             }
  1618 
  1619 
  1619             @Override
  1620             @Override
  1620             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1621             Type solve(UndetVar uv, InferenceContext inferenceContext) {
  1621                 Infer infer = inferenceContext.infer();
  1622                 Infer infer = inferenceContext.infer;
  1622                 Type upper = UPPER.filterBounds(uv, inferenceContext).nonEmpty() ?
  1623                 Type upper = UPPER.filterBounds(uv, inferenceContext).nonEmpty() ?
  1623                         UPPER.solve(uv, inferenceContext) :
  1624                         UPPER.solve(uv, inferenceContext) :
  1624                         infer.syms.objectType;
  1625                         infer.syms.objectType;
  1625                 Type lower = LOWER.filterBounds(uv, inferenceContext).nonEmpty() ?
  1626                 Type lower = LOWER.filterBounds(uv, inferenceContext).nonEmpty() ?
  1626                         LOWER.solve(uv, inferenceContext) :
  1627                         LOWER.solve(uv, inferenceContext) :
  2080      */
  2081      */
  2081     interface FreeTypeListener {
  2082     interface FreeTypeListener {
  2082         void typesInferred(InferenceContext inferenceContext);
  2083         void typesInferred(InferenceContext inferenceContext);
  2083     }
  2084     }
  2084 
  2085 
  2085     /**
  2086     final InferenceContext emptyContext;
  2086      * An inference context keeps track of the set of variables that are free
       
  2087      * in the current context. It provides utility methods for opening/closing
       
  2088      * types to their corresponding free/closed forms. It also provide hooks for
       
  2089      * attaching deferred post-inference action (see PendingCheck). Finally,
       
  2090      * it can be used as an entry point for performing upper/lower bound inference
       
  2091      * (see InferenceKind).
       
  2092      */
       
  2093      class InferenceContext {
       
  2094 
       
  2095         /** list of inference vars as undet vars */
       
  2096         List<Type> undetvars;
       
  2097 
       
  2098         /** list of inference vars in this context */
       
  2099         List<Type> inferencevars;
       
  2100 
       
  2101         Map<FreeTypeListener, List<Type>> freeTypeListeners = new HashMap<>();
       
  2102 
       
  2103         List<FreeTypeListener> freetypeListeners = List.nil();
       
  2104 
       
  2105         public InferenceContext(List<Type> inferencevars) {
       
  2106             this.undetvars = inferencevars.map(fromTypeVarFun);
       
  2107             this.inferencevars = inferencevars;
       
  2108         }
       
  2109         //where
       
  2110             TypeMapping<Void> fromTypeVarFun = new TypeMapping<Void>() {
       
  2111                 @Override
       
  2112                 public Type visitTypeVar(TypeVar tv, Void aVoid) {
       
  2113                     return new UndetVar(tv, types);
       
  2114                 }
       
  2115 
       
  2116                 @Override
       
  2117                 public Type visitCapturedType(CapturedType t, Void aVoid) {
       
  2118                     return new CapturedUndetVar(t, types);
       
  2119                 }
       
  2120             };
       
  2121 
       
  2122         /**
       
  2123          * add a new inference var to this inference context
       
  2124          */
       
  2125         void addVar(TypeVar t) {
       
  2126             this.undetvars = this.undetvars.prepend(fromTypeVarFun.apply(t));
       
  2127             this.inferencevars = this.inferencevars.prepend(t);
       
  2128         }
       
  2129 
       
  2130         /**
       
  2131          * returns the list of free variables (as type-variables) in this
       
  2132          * inference context
       
  2133          */
       
  2134         List<Type> inferenceVars() {
       
  2135             return inferencevars;
       
  2136         }
       
  2137 
       
  2138         /**
       
  2139          * returns the list of uninstantiated variables (as type-variables) in this
       
  2140          * inference context
       
  2141          */
       
  2142         List<Type> restvars() {
       
  2143             return filterVars(new Filter<UndetVar>() {
       
  2144                 public boolean accepts(UndetVar uv) {
       
  2145                     return uv.inst == null;
       
  2146                 }
       
  2147             });
       
  2148         }
       
  2149 
       
  2150         /**
       
  2151          * returns the list of instantiated variables (as type-variables) in this
       
  2152          * inference context
       
  2153          */
       
  2154         List<Type> instvars() {
       
  2155             return filterVars(new Filter<UndetVar>() {
       
  2156                 public boolean accepts(UndetVar uv) {
       
  2157                     return uv.inst != null;
       
  2158                 }
       
  2159             });
       
  2160         }
       
  2161 
       
  2162         /**
       
  2163          * Get list of bounded inference variables (where bound is other than
       
  2164          * declared bounds).
       
  2165          */
       
  2166         final List<Type> boundedVars() {
       
  2167             return filterVars(new Filter<UndetVar>() {
       
  2168                 public boolean accepts(UndetVar uv) {
       
  2169                     return uv.getBounds(InferenceBound.UPPER)
       
  2170                              .diff(uv.getDeclaredBounds())
       
  2171                              .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
       
  2172                 }
       
  2173             });
       
  2174         }
       
  2175 
       
  2176         /* Returns the corresponding inference variables.
       
  2177          */
       
  2178         private List<Type> filterVars(Filter<UndetVar> fu) {
       
  2179             ListBuffer<Type> res = new ListBuffer<>();
       
  2180             for (Type t : undetvars) {
       
  2181                 UndetVar uv = (UndetVar)t;
       
  2182                 if (fu.accepts(uv)) {
       
  2183                     res.append(uv.qtype);
       
  2184                 }
       
  2185             }
       
  2186             return res.toList();
       
  2187         }
       
  2188 
       
  2189         /**
       
  2190          * is this type free?
       
  2191          */
       
  2192         final boolean free(Type t) {
       
  2193             return t.containsAny(inferencevars);
       
  2194         }
       
  2195 
       
  2196         final boolean free(List<Type> ts) {
       
  2197             for (Type t : ts) {
       
  2198                 if (free(t)) return true;
       
  2199             }
       
  2200             return false;
       
  2201         }
       
  2202 
       
  2203         /**
       
  2204          * Returns a list of free variables in a given type
       
  2205          */
       
  2206         final List<Type> freeVarsIn(Type t) {
       
  2207             ListBuffer<Type> buf = new ListBuffer<>();
       
  2208             for (Type iv : inferenceVars()) {
       
  2209                 if (t.contains(iv)) {
       
  2210                     buf.add(iv);
       
  2211                 }
       
  2212             }
       
  2213             return buf.toList();
       
  2214         }
       
  2215 
       
  2216         final List<Type> freeVarsIn(List<Type> ts) {
       
  2217             ListBuffer<Type> buf = new ListBuffer<>();
       
  2218             for (Type t : ts) {
       
  2219                 buf.appendList(freeVarsIn(t));
       
  2220             }
       
  2221             ListBuffer<Type> buf2 = new ListBuffer<>();
       
  2222             for (Type t : buf) {
       
  2223                 if (!buf2.contains(t)) {
       
  2224                     buf2.add(t);
       
  2225                 }
       
  2226             }
       
  2227             return buf2.toList();
       
  2228         }
       
  2229 
       
  2230         /**
       
  2231          * Replace all free variables in a given type with corresponding
       
  2232          * undet vars (used ahead of subtyping/compatibility checks to allow propagation
       
  2233          * of inference constraints).
       
  2234          */
       
  2235         final Type asUndetVar(Type t) {
       
  2236             return types.subst(t, inferencevars, undetvars);
       
  2237         }
       
  2238 
       
  2239         final List<Type> asUndetVars(List<Type> ts) {
       
  2240             ListBuffer<Type> buf = new ListBuffer<>();
       
  2241             for (Type t : ts) {
       
  2242                 buf.append(asUndetVar(t));
       
  2243             }
       
  2244             return buf.toList();
       
  2245         }
       
  2246 
       
  2247         List<Type> instTypes() {
       
  2248             ListBuffer<Type> buf = new ListBuffer<>();
       
  2249             for (Type t : undetvars) {
       
  2250                 UndetVar uv = (UndetVar)t;
       
  2251                 buf.append(uv.inst != null ? uv.inst : uv.qtype);
       
  2252             }
       
  2253             return buf.toList();
       
  2254         }
       
  2255 
       
  2256         /**
       
  2257          * Replace all free variables in a given type with corresponding
       
  2258          * instantiated types - if one or more free variable has not been
       
  2259          * fully instantiated, it will still be available in the resulting type.
       
  2260          */
       
  2261         Type asInstType(Type t) {
       
  2262             return types.subst(t, inferencevars, instTypes());
       
  2263         }
       
  2264 
       
  2265         List<Type> asInstTypes(List<Type> ts) {
       
  2266             ListBuffer<Type> buf = new ListBuffer<>();
       
  2267             for (Type t : ts) {
       
  2268                 buf.append(asInstType(t));
       
  2269             }
       
  2270             return buf.toList();
       
  2271         }
       
  2272 
       
  2273         /**
       
  2274          * Add custom hook for performing post-inference action
       
  2275          */
       
  2276         void addFreeTypeListener(List<Type> types, FreeTypeListener ftl) {
       
  2277             freeTypeListeners.put(ftl, freeVarsIn(types));
       
  2278         }
       
  2279 
       
  2280         /**
       
  2281          * Mark the inference context as complete and trigger evaluation
       
  2282          * of all deferred checks.
       
  2283          */
       
  2284         void notifyChange() {
       
  2285             notifyChange(inferencevars.diff(restvars()));
       
  2286         }
       
  2287 
       
  2288         void notifyChange(List<Type> inferredVars) {
       
  2289             InferenceException thrownEx = null;
       
  2290             for (Map.Entry<FreeTypeListener, List<Type>> entry :
       
  2291                     new HashMap<>(freeTypeListeners).entrySet()) {
       
  2292                 if (!Type.containsAny(entry.getValue(), inferencevars.diff(inferredVars))) {
       
  2293                     try {
       
  2294                         entry.getKey().typesInferred(this);
       
  2295                         freeTypeListeners.remove(entry.getKey());
       
  2296                     } catch (InferenceException ex) {
       
  2297                         if (thrownEx == null) {
       
  2298                             thrownEx = ex;
       
  2299                         }
       
  2300                     }
       
  2301                 }
       
  2302             }
       
  2303             //inference exception multiplexing - present any inference exception
       
  2304             //thrown when processing listeners as a single one
       
  2305             if (thrownEx != null) {
       
  2306                 throw thrownEx;
       
  2307             }
       
  2308         }
       
  2309 
       
  2310         /**
       
  2311          * Save the state of this inference context
       
  2312          */
       
  2313         List<Type> save() {
       
  2314             ListBuffer<Type> buf = new ListBuffer<>();
       
  2315             for (Type t : undetvars) {
       
  2316                 UndetVar uv = (UndetVar)t;
       
  2317                 UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types);
       
  2318                 for (InferenceBound ib : InferenceBound.values()) {
       
  2319                     for (Type b : uv.getBounds(ib)) {
       
  2320                         uv2.addBound(ib, b, types);
       
  2321                     }
       
  2322                 }
       
  2323                 uv2.inst = uv.inst;
       
  2324                 buf.add(uv2);
       
  2325             }
       
  2326             return buf.toList();
       
  2327         }
       
  2328 
       
  2329         /**
       
  2330          * Restore the state of this inference context to the previous known checkpoint
       
  2331          */
       
  2332         void rollback(List<Type> saved_undet) {
       
  2333              Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
       
  2334             //restore bounds (note: we need to preserve the old instances)
       
  2335             for (Type t : undetvars) {
       
  2336                 UndetVar uv = (UndetVar)t;
       
  2337                 UndetVar uv_saved = (UndetVar)saved_undet.head;
       
  2338                 for (InferenceBound ib : InferenceBound.values()) {
       
  2339                     uv.setBounds(ib, uv_saved.getBounds(ib));
       
  2340                 }
       
  2341                 uv.inst = uv_saved.inst;
       
  2342                 saved_undet = saved_undet.tail;
       
  2343             }
       
  2344         }
       
  2345 
       
  2346         /**
       
  2347          * Copy variable in this inference context to the given context
       
  2348          */
       
  2349         void dupTo(final InferenceContext that) {
       
  2350             that.inferencevars = that.inferencevars.appendList(
       
  2351                     inferencevars.diff(that.inferencevars));
       
  2352             that.undetvars = that.undetvars.appendList(
       
  2353                     undetvars.diff(that.undetvars));
       
  2354             //set up listeners to notify original inference contexts as
       
  2355             //propagated vars are inferred in new context
       
  2356             for (Type t : inferencevars) {
       
  2357                 that.freeTypeListeners.put(new FreeTypeListener() {
       
  2358                     public void typesInferred(InferenceContext inferenceContext) {
       
  2359                         InferenceContext.this.notifyChange();
       
  2360                     }
       
  2361                 }, List.of(t));
       
  2362             }
       
  2363         }
       
  2364 
       
  2365         private void solve(GraphStrategy ss, Warner warn) {
       
  2366             solve(ss, new HashMap<Type, Set<Type>>(), warn);
       
  2367         }
       
  2368 
       
  2369         /**
       
  2370          * Solve with given graph strategy.
       
  2371          */
       
  2372         private void solve(GraphStrategy ss, Map<Type, Set<Type>> stuckDeps, Warner warn) {
       
  2373             GraphSolver s = new GraphSolver(this, stuckDeps, warn);
       
  2374             s.solve(ss);
       
  2375         }
       
  2376 
       
  2377         /**
       
  2378          * Solve all variables in this context.
       
  2379          */
       
  2380         public void solve(Warner warn) {
       
  2381             solve(new LeafSolver() {
       
  2382                 public boolean done() {
       
  2383                     return restvars().isEmpty();
       
  2384                 }
       
  2385             }, warn);
       
  2386         }
       
  2387 
       
  2388         /**
       
  2389          * Solve all variables in the given list.
       
  2390          */
       
  2391         public void solve(final List<Type> vars, Warner warn) {
       
  2392             solve(new BestLeafSolver(vars) {
       
  2393                 public boolean done() {
       
  2394                     return !free(asInstTypes(vars));
       
  2395                 }
       
  2396             }, warn);
       
  2397         }
       
  2398 
       
  2399         /**
       
  2400          * Solve at least one variable in given list.
       
  2401          */
       
  2402         public void solveAny(List<Type> varsToSolve, Map<Type, Set<Type>> optDeps, Warner warn) {
       
  2403             solve(new BestLeafSolver(varsToSolve.intersect(restvars())) {
       
  2404                 public boolean done() {
       
  2405                     return instvars().intersect(varsToSolve).nonEmpty();
       
  2406                 }
       
  2407             }, optDeps, warn);
       
  2408         }
       
  2409 
       
  2410         /**
       
  2411          * Apply a set of inference steps
       
  2412          */
       
  2413         private boolean solveBasic(EnumSet<InferenceStep> steps) {
       
  2414             return solveBasic(inferencevars, steps);
       
  2415         }
       
  2416 
       
  2417         private boolean solveBasic(List<Type> varsToSolve, EnumSet<InferenceStep> steps) {
       
  2418             boolean changed = false;
       
  2419             for (Type t : varsToSolve.intersect(restvars())) {
       
  2420                 UndetVar uv = (UndetVar)asUndetVar(t);
       
  2421                 for (InferenceStep step : steps) {
       
  2422                     if (step.accepts(uv, this)) {
       
  2423                         uv.inst = step.solve(uv, this);
       
  2424                         changed = true;
       
  2425                         break;
       
  2426                     }
       
  2427                 }
       
  2428             }
       
  2429             return changed;
       
  2430         }
       
  2431 
       
  2432         /**
       
  2433          * Instantiate inference variables in legacy mode (JLS 15.12.2.7, 15.12.2.8).
       
  2434          * During overload resolution, instantiation is done by doing a partial
       
  2435          * inference process using eq/lower bound instantiation. During check,
       
  2436          * we also instantiate any remaining vars by repeatedly using eq/upper
       
  2437          * instantiation, until all variables are solved.
       
  2438          */
       
  2439         public void solveLegacy(boolean partial, Warner warn, EnumSet<InferenceStep> steps) {
       
  2440             while (true) {
       
  2441                 boolean stuck = !solveBasic(steps);
       
  2442                 if (restvars().isEmpty() || partial) {
       
  2443                     //all variables have been instantiated - exit
       
  2444                     break;
       
  2445                 } else if (stuck) {
       
  2446                     //some variables could not be instantiated because of cycles in
       
  2447                     //upper bounds - provide a (possibly recursive) default instantiation
       
  2448                     instantiateAsUninferredVars(restvars(), this);
       
  2449                     break;
       
  2450                 } else {
       
  2451                     //some variables have been instantiated - replace newly instantiated
       
  2452                     //variables in remaining upper bounds and continue
       
  2453                     for (Type t : undetvars) {
       
  2454                         UndetVar uv = (UndetVar)t;
       
  2455                         uv.substBounds(inferenceVars(), instTypes(), types);
       
  2456                     }
       
  2457                 }
       
  2458             }
       
  2459             checkWithinBounds(this, warn);
       
  2460         }
       
  2461 
       
  2462         private Infer infer() {
       
  2463             //back-door to infer
       
  2464             return Infer.this;
       
  2465         }
       
  2466 
       
  2467         @Override
       
  2468         public String toString() {
       
  2469             return "Inference vars: " + inferencevars + '\n' +
       
  2470                    "Undet vars: " + undetvars;
       
  2471         }
       
  2472 
       
  2473         /* Method Types.capture() generates a new type every time it's applied
       
  2474          * to a wildcard parameterized type. This is intended functionality but
       
  2475          * there are some cases when what you need is not to generate a new
       
  2476          * captured type but to check that a previously generated captured type
       
  2477          * is correct. There are cases when caching a captured type for later
       
  2478          * reuse is sound. In general two captures from the same AST are equal.
       
  2479          * This is why the tree is used as the key of the map below. This map
       
  2480          * stores a Type per AST.
       
  2481          */
       
  2482         Map<JCTree, Type> captureTypeCache = new HashMap<>();
       
  2483 
       
  2484         Type cachedCapture(JCTree tree, Type t, boolean readOnly) {
       
  2485             Type captured = captureTypeCache.get(tree);
       
  2486             if (captured != null) {
       
  2487                 return captured;
       
  2488             }
       
  2489 
       
  2490             Type result = types.capture(t);
       
  2491             if (result != t && !readOnly) { // then t is a wildcard parameterized type
       
  2492                 captureTypeCache.put(tree, result);
       
  2493             }
       
  2494             return result;
       
  2495         }
       
  2496     }
       
  2497 
       
  2498     final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());
       
  2499     // </editor-fold>
  2087     // </editor-fold>
  2500 }
  2088 }