src/share/classes/com/sun/tools/javac/comp/Infer.java

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

mercurial