186 public void instantiateUninferred(DiagnosticPosition pos, |
190 public void instantiateUninferred(DiagnosticPosition pos, |
187 InferenceContext inferenceContext, |
191 InferenceContext inferenceContext, |
188 MethodType mtype, |
192 MethodType mtype, |
189 Attr.ResultInfo resultInfo, |
193 Attr.ResultInfo resultInfo, |
190 Warner warn) throws InferenceException { |
194 Warner warn) throws InferenceException { |
191 Type to = resultInfo.pt; |
|
192 if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) { |
|
193 to = mtype.getReturnType().isPrimitiveOrVoid() ? |
|
194 mtype.getReturnType() : syms.objectType; |
|
195 } |
|
196 Type qtype1 = inferenceContext.asFree(mtype.getReturnType(), types); |
|
197 if (!types.isSubtype(qtype1, |
|
198 qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) { |
|
199 throw inferenceException |
|
200 .setMessage("infer.no.conforming.instance.exists", |
|
201 inferenceContext.restvars(), mtype.getReturnType(), to); |
|
202 } |
|
203 |
|
204 while (true) { |
195 while (true) { |
205 boolean stuck = true; |
196 boolean stuck = true; |
206 for (Type t : inferenceContext.undetvars) { |
197 for (Type t : inferenceContext.undetvars) { |
207 UndetVar uv = (UndetVar)t; |
198 UndetVar uv = (UndetVar)t; |
208 if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() || |
199 if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() || |
281 resolveContext.deferredAttrContext(msym, inferenceContext); |
272 resolveContext.deferredAttrContext(msym, inferenceContext); |
282 |
273 |
283 try { |
274 try { |
284 methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn); |
275 methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn); |
285 |
276 |
|
277 if (resultInfo != null && allowEarlyReturnConstraints && |
|
278 !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { |
|
279 generateReturnConstraints(mt, inferenceContext, resultInfo); |
|
280 } |
|
281 |
286 deferredAttrContext.complete(); |
282 deferredAttrContext.complete(); |
287 |
283 |
288 // minimize as yet undetermined type variables |
284 // minimize as yet undetermined type variables |
289 for (Type t : inferenceContext.undetvars) { |
285 for (Type t : inferenceContext.undetvars) { |
290 minimizeInst((UndetVar)t, warn); |
286 minimizeInst((UndetVar)t, warn); |
296 |
292 |
297 List<Type> restvars = inferenceContext.restvars(); |
293 List<Type> restvars = inferenceContext.restvars(); |
298 |
294 |
299 if (!restvars.isEmpty()) { |
295 if (!restvars.isEmpty()) { |
300 if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { |
296 if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { |
|
297 if (!allowEarlyReturnConstraints) { |
|
298 generateReturnConstraints(mt, inferenceContext, resultInfo); |
|
299 } |
301 instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn); |
300 instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn); |
302 checkWithinBounds(inferenceContext, warn); |
301 checkWithinBounds(inferenceContext, warn); |
303 mt = (MethodType)inferenceContext.asInstType(mt, types); |
302 mt = (MethodType)inferenceContext.asInstType(mt, types); |
304 if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { |
303 if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { |
305 log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt); |
304 log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt); |
311 return mt; |
310 return mt; |
312 } finally { |
311 } finally { |
313 inferenceContext.notifyChange(types); |
312 inferenceContext.notifyChange(types); |
314 } |
313 } |
315 } |
314 } |
|
315 //where |
|
316 void generateReturnConstraints(Type mt, InferenceContext inferenceContext, Attr.ResultInfo resultInfo) { |
|
317 if (resultInfo != null) { |
|
318 Type to = resultInfo.pt; |
|
319 if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) { |
|
320 to = mt.getReturnType().isPrimitiveOrVoid() ? |
|
321 mt.getReturnType() : syms.objectType; |
|
322 } |
|
323 Type qtype1 = inferenceContext.asFree(mt.getReturnType(), types); |
|
324 if (!types.isSubtype(qtype1, |
|
325 qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) { |
|
326 throw inferenceException |
|
327 .setMessage("infer.no.conforming.instance.exists", |
|
328 inferenceContext.restvars(), mt.getReturnType(), to); |
|
329 } |
|
330 } |
|
331 } |
316 |
332 |
317 /** check that type parameters are within their bounds. |
333 /** check that type parameters are within their bounds. |
318 */ |
334 */ |
319 void checkWithinBounds(InferenceContext inferenceContext, |
335 void checkWithinBounds(InferenceContext inferenceContext, |
320 Warner warn) throws InferenceException { |
336 Warner warn) throws InferenceException { |
459 return funcInterface; |
475 return funcInterface; |
460 } else { |
476 } else { |
461 Type formalInterface = funcInterface.tsym.type; |
477 Type formalInterface = funcInterface.tsym.type; |
462 InferenceContext funcInterfaceContext = |
478 InferenceContext funcInterfaceContext = |
463 new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false); |
479 new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false); |
464 if (paramTypes != null) { |
480 Assert.check(paramTypes != null); |
465 //get constraints from explicit params (this is done by |
481 //get constraints from explicit params (this is done by |
466 //checking that explicit param types are equal to the ones |
482 //checking that explicit param types are equal to the ones |
467 //in the functional interface descriptors) |
483 //in the functional interface descriptors) |
468 List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes(); |
484 List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes(); |
469 if (descParameterTypes.size() != paramTypes.size()) { |
485 if (descParameterTypes.size() != paramTypes.size()) { |
470 checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda")); |
486 checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda")); |
|
487 return types.createErrorType(funcInterface); |
|
488 } |
|
489 for (Type p : descParameterTypes) { |
|
490 if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) { |
|
491 checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); |
471 return types.createErrorType(funcInterface); |
492 return types.createErrorType(funcInterface); |
472 } |
493 } |
473 for (Type p : descParameterTypes) { |
494 paramTypes = paramTypes.tail; |
474 if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) { |
495 } |
475 checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); |
|
476 return types.createErrorType(funcInterface); |
|
477 } |
|
478 paramTypes = paramTypes.tail; |
|
479 } |
|
480 for (Type t : funcInterfaceContext.undetvars) { |
|
481 UndetVar uv = (UndetVar)t; |
|
482 minimizeInst(uv, types.noWarnings); |
|
483 if (uv.inst == null && |
|
484 Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) { |
|
485 maximizeInst(uv, types.noWarnings); |
|
486 } |
|
487 } |
|
488 |
|
489 formalInterface = funcInterfaceContext.asInstType(formalInterface, types); |
|
490 } |
|
491 ListBuffer<Type> typeargs = ListBuffer.lb(); |
|
492 List<Type> actualTypeargs = funcInterface.getTypeArguments(); |
496 List<Type> actualTypeargs = funcInterface.getTypeArguments(); |
493 //for remaining uninferred type-vars in the functional interface type, |
497 for (Type t : funcInterfaceContext.undetvars) { |
494 //simply replace the wildcards with its bound |
498 UndetVar uv = (UndetVar)t; |
495 for (Type t : formalInterface.getTypeArguments()) { |
499 minimizeInst(uv, types.noWarnings); |
496 if (actualTypeargs.head.hasTag(WILDCARD)) { |
500 if (uv.inst == null && |
497 WildcardType wt = (WildcardType)actualTypeargs.head; |
501 Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) { |
498 typeargs.append(wt.type); |
502 maximizeInst(uv, types.noWarnings); |
499 } else { |
503 } |
500 typeargs.append(actualTypeargs.head); |
504 if (uv.inst == null) { |
|
505 uv.inst = actualTypeargs.head; |
501 } |
506 } |
502 actualTypeargs = actualTypeargs.tail; |
507 actualTypeargs = actualTypeargs.tail; |
503 } |
508 } |
504 Type owntype = types.subst(formalInterface, funcInterfaceContext.inferenceVars(), typeargs.toList()); |
509 Type owntype = funcInterfaceContext.asInstType(formalInterface, types); |
505 if (!chk.checkValidGenericType(owntype)) { |
510 if (!chk.checkValidGenericType(owntype)) { |
506 //if the inferred functional interface type is not well-formed, |
511 //if the inferred functional interface type is not well-formed, |
507 //or if it's not a subtype of the original target, issue an error |
512 //or if it's not a subtype of the original target, issue an error |
508 checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); |
513 checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); |
509 return types.createErrorType(funcInterface); |
|
510 } |
514 } |
511 return owntype; |
515 return owntype; |
512 } |
516 } |
513 } |
517 } |
514 // </editor-fold> |
518 // </editor-fold> |