langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
changeset 18904 3c4c6457ec5b
parent 18646 e628560a86d1
child 18909 8f9fc5d876e4
equal deleted inserted replaced
18903:99f42bd11bc2 18904:3c4c6457ec5b
   416      * Check bounds and perform incorporation
   416      * Check bounds and perform incorporation
   417      */
   417      */
   418     void checkWithinBounds(InferenceContext inferenceContext,
   418     void checkWithinBounds(InferenceContext inferenceContext,
   419                              Warner warn) throws InferenceException {
   419                              Warner warn) throws InferenceException {
   420         MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars);
   420         MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars);
       
   421         List<Type> saved_undet = inferenceContext.save();
   421         try {
   422         try {
   422             while (true) {
   423             while (true) {
   423                 mlistener.reset();
   424                 mlistener.reset();
   424                 if (!allowGraphInference) {
   425                 if (!allowGraphInference) {
   425                     //in legacy mode we lack of transitivity, so bound check
   426                     //in legacy mode we lack of transitivity, so bound check
   441                 if (!mlistener.changed || !allowGraphInference) break;
   442                 if (!mlistener.changed || !allowGraphInference) break;
   442             }
   443             }
   443         }
   444         }
   444         finally {
   445         finally {
   445             mlistener.detach();
   446             mlistener.detach();
       
   447             if (mlistener.rounds == MAX_INCORPORATION_STEPS) {
       
   448                 inferenceContext.rollback(saved_undet);
       
   449             }
   446         }
   450         }
   447     }
   451     }
   448     //where
   452     //where
   449         /**
   453         /**
   450          * This listener keeps track of changes on a group of inference variable
   454          * This listener keeps track of changes on a group of inference variable
   643                 for (Type b : uv.getBounds(InferenceBound.UPPER)) {
   647                 for (Type b : uv.getBounds(InferenceBound.UPPER)) {
   644                     if (inferenceContext.inferenceVars().contains(b)) {
   648                     if (inferenceContext.inferenceVars().contains(b)) {
   645                         UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
   649                         UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
   646                         //alpha <: beta
   650                         //alpha <: beta
   647                         //0. set beta :> alpha
   651                         //0. set beta :> alpha
   648                         uv2.addBound(InferenceBound.LOWER, uv.qtype, infer.types);
   652                         uv2.addBound(InferenceBound.LOWER, uv, infer.types);
   649                         //1. copy alpha's lower to beta's
   653                         //1. copy alpha's lower to beta's
   650                         for (Type l : uv.getBounds(InferenceBound.LOWER)) {
   654                         for (Type l : uv.getBounds(InferenceBound.LOWER)) {
   651                             uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
   655                             uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
   652                         }
   656                         }
   653                         //2. copy beta's upper to alpha's
   657                         //2. copy beta's upper to alpha's
   668                 for (Type b : uv.getBounds(InferenceBound.LOWER)) {
   672                 for (Type b : uv.getBounds(InferenceBound.LOWER)) {
   669                     if (inferenceContext.inferenceVars().contains(b)) {
   673                     if (inferenceContext.inferenceVars().contains(b)) {
   670                         UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
   674                         UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
   671                         //alpha :> beta
   675                         //alpha :> beta
   672                         //0. set beta <: alpha
   676                         //0. set beta <: alpha
   673                         uv2.addBound(InferenceBound.UPPER, uv.qtype, infer.types);
   677                         uv2.addBound(InferenceBound.UPPER, uv, infer.types);
   674                         //1. copy alpha's upper to beta's
   678                         //1. copy alpha's upper to beta's
   675                         for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   679                         for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   676                             uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
   680                             uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
   677                         }
   681                         }
   678                         //2. copy beta's lower to alpha's
   682                         //2. copy beta's lower to alpha's
   693                 for (Type b : uv.getBounds(InferenceBound.EQ)) {
   697                 for (Type b : uv.getBounds(InferenceBound.EQ)) {
   694                     if (inferenceContext.inferenceVars().contains(b)) {
   698                     if (inferenceContext.inferenceVars().contains(b)) {
   695                         UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
   699                         UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
   696                         //alpha == beta
   700                         //alpha == beta
   697                         //0. set beta == alpha
   701                         //0. set beta == alpha
   698                         uv2.addBound(InferenceBound.EQ, uv.qtype, infer.types);
   702                         uv2.addBound(InferenceBound.EQ, uv, infer.types);
   699                         //1. copy all alpha's bounds to beta's
   703                         //1. copy all alpha's bounds to beta's
   700                         for (InferenceBound ib : InferenceBound.values()) {
   704                         for (InferenceBound ib : InferenceBound.values()) {
   701                             for (Type b2 : uv.getBounds(ib)) {
   705                             for (Type b2 : uv.getBounds(ib)) {
   702                                 if (b2 != uv2) {
   706                                 if (b2 != uv2) {
   703                                     uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types);
   707                                     uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types);
  1088             checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
  1092             checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
  1089             InferenceGraph inferenceGraph = new InferenceGraph();
  1093             InferenceGraph inferenceGraph = new InferenceGraph();
  1090             while (!sstrategy.done()) {
  1094             while (!sstrategy.done()) {
  1091                 InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
  1095                 InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
  1092                 List<Type> varsToSolve = List.from(nodeToSolve.data);
  1096                 List<Type> varsToSolve = List.from(nodeToSolve.data);
  1093                 inferenceContext.save();
  1097                 List<Type> saved_undet = inferenceContext.save();
  1094                 try {
  1098                 try {
  1095                     //repeat until all variables are solved
  1099                     //repeat until all variables are solved
  1096                     outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
  1100                     outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
  1097                         //for each inference phase
  1101                         //for each inference phase
  1098                         for (GraphInferenceSteps step : GraphInferenceSteps.values()) {
  1102                         for (GraphInferenceSteps step : GraphInferenceSteps.values()) {
  1105                         throw inferenceException.setMessage();
  1109                         throw inferenceException.setMessage();
  1106                     }
  1110                     }
  1107                 }
  1111                 }
  1108                 catch (InferenceException ex) {
  1112                 catch (InferenceException ex) {
  1109                     //did we fail because of interdependent ivars?
  1113                     //did we fail because of interdependent ivars?
  1110                     inferenceContext.rollback();
  1114                     inferenceContext.rollback(saved_undet);
  1111                     instantiateAsUninferredVars(varsToSolve, inferenceContext);
  1115                     instantiateAsUninferredVars(varsToSolve, inferenceContext);
  1112                     checkWithinBounds(inferenceContext, warn);
  1116                     checkWithinBounds(inferenceContext, warn);
  1113                 }
  1117                 }
  1114                 inferenceGraph.deleteNode(nodeToSolve);
  1118                 inferenceGraph.deleteNode(nodeToSolve);
  1115             }
  1119             }
  1500         }
  1504         }
  1501 
  1505 
  1502         /**
  1506         /**
  1503          * Save the state of this inference context
  1507          * Save the state of this inference context
  1504          */
  1508          */
  1505         void save() {
  1509         List<Type> save() {
  1506             ListBuffer<Type> buf = ListBuffer.lb();
  1510             ListBuffer<Type> buf = ListBuffer.lb();
  1507             for (Type t : undetvars) {
  1511             for (Type t : undetvars) {
  1508                 UndetVar uv = (UndetVar)t;
  1512                 UndetVar uv = (UndetVar)t;
  1509                 UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types);
  1513                 UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types);
  1510                 for (InferenceBound ib : InferenceBound.values()) {
  1514                 for (InferenceBound ib : InferenceBound.values()) {
  1513                     }
  1517                     }
  1514                 }
  1518                 }
  1515                 uv2.inst = uv.inst;
  1519                 uv2.inst = uv.inst;
  1516                 buf.add(uv2);
  1520                 buf.add(uv2);
  1517             }
  1521             }
  1518             saved_undet = buf.toList();
  1522             return buf.toList();
  1519         }
  1523         }
  1520 
  1524 
  1521         /**
  1525         /**
  1522          * Restore the state of this inference context to the previous known checkpoint
  1526          * Restore the state of this inference context to the previous known checkpoint
  1523          */
  1527          */
  1524         void rollback() {
  1528         void rollback(List<Type> saved_undet) {
  1525             Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
  1529              Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
  1526             undetvars = saved_undet;
  1530             //restore bounds (note: we need to preserve the old instances)
  1527             saved_undet = null;
  1531             for (Type t : undetvars) {
       
  1532                 UndetVar uv = (UndetVar)t;
       
  1533                 UndetVar uv_saved = (UndetVar)saved_undet.head;
       
  1534                 for (InferenceBound ib : InferenceBound.values()) {
       
  1535                     uv.setBounds(ib, uv_saved.getBounds(ib));
       
  1536                 }
       
  1537                 uv.inst = uv_saved.inst;
       
  1538                 saved_undet = saved_undet.tail;
       
  1539             }
  1528         }
  1540         }
  1529 
  1541 
  1530         /**
  1542         /**
  1531          * Copy variable in this inference context to the given context
  1543          * Copy variable in this inference context to the given context
  1532          */
  1544          */