373 * @param req The type that was required. |
373 * @param req The type that was required. |
374 */ |
374 */ |
375 Type checkType(DiagnosticPosition pos, Type found, Type req) { |
375 Type checkType(DiagnosticPosition pos, Type found, Type req) { |
376 if (req.tag == ERROR) |
376 if (req.tag == ERROR) |
377 return req; |
377 return req; |
|
378 if (found.tag == FORALL) |
|
379 return instantiatePoly(pos, (ForAll)found, req, convertWarner(pos, found, req)); |
378 if (req.tag == NONE) |
380 if (req.tag == NONE) |
379 return found; |
381 return found; |
380 if (types.isAssignable(found, req, convertWarner(pos, found, req))) |
382 if (types.isAssignable(found, req, convertWarner(pos, found, req))) |
381 return found; |
383 return found; |
382 if (found.tag <= DOUBLE && req.tag <= DOUBLE) |
384 if (found.tag <= DOUBLE && req.tag <= DOUBLE) |
390 return types.createErrorType(found); |
392 return types.createErrorType(found); |
391 } |
393 } |
392 return typeError(pos, diags.fragment("incompatible.types"), found, req); |
394 return typeError(pos, diags.fragment("incompatible.types"), found, req); |
393 } |
395 } |
394 |
396 |
395 Type checkReturnType(DiagnosticPosition pos, Type found, Type req) { |
|
396 if (found.tag == FORALL) { |
|
397 try { |
|
398 return instantiatePoly(pos, (ForAll) found, req, convertWarner(pos, found, req)); |
|
399 } catch (Infer.NoInstanceException ex) { |
|
400 if (ex.isAmbiguous) { |
|
401 JCDiagnostic d = ex.getDiagnostic(); |
|
402 log.error(pos, |
|
403 "undetermined.type" + (d != null ? ".1" : ""), |
|
404 found, d); |
|
405 return types.createErrorType(req); |
|
406 } else { |
|
407 JCDiagnostic d = ex.getDiagnostic(); |
|
408 return typeError(pos, |
|
409 diags.fragment("incompatible.types" + (d != null ? ".1" : ""), d), |
|
410 found, req); |
|
411 } |
|
412 } catch (Infer.InvalidInstanceException ex) { |
|
413 JCDiagnostic d = ex.getDiagnostic(); |
|
414 log.error(pos, "invalid.inferred.types", ((ForAll)found).tvars, d); |
|
415 return types.createErrorType(req); |
|
416 } |
|
417 } else { |
|
418 return checkType(pos, found, req); |
|
419 } |
|
420 } |
|
421 |
|
422 /** Instantiate polymorphic type to some prototype, unless |
397 /** Instantiate polymorphic type to some prototype, unless |
423 * prototype is `anyPoly' in which case polymorphic type |
398 * prototype is `anyPoly' in which case polymorphic type |
424 * is returned unchanged. |
399 * is returned unchanged. |
425 */ |
400 */ |
426 Type instantiatePoly(DiagnosticPosition pos, ForAll t, Type pt, Warner warn) throws Infer.NoInstanceException { |
401 Type instantiatePoly(DiagnosticPosition pos, ForAll t, Type pt, Warner warn) throws Infer.NoInstanceException { |
430 Type newpt = t.qtype.tag <= VOID ? t.qtype : syms.objectType; |
405 Type newpt = t.qtype.tag <= VOID ? t.qtype : syms.objectType; |
431 return instantiatePoly(pos, t, newpt, warn); |
406 return instantiatePoly(pos, t, newpt, warn); |
432 } else if (pt.tag == ERROR) { |
407 } else if (pt.tag == ERROR) { |
433 return pt; |
408 return pt; |
434 } else { |
409 } else { |
435 return infer.instantiateExpr(t, pt, warn); |
410 try { |
436 } |
411 return infer.instantiateExpr(t, pt, warn); |
437 } |
412 } catch (Infer.NoInstanceException ex) { |
|
413 if (ex.isAmbiguous) { |
|
414 JCDiagnostic d = ex.getDiagnostic(); |
|
415 log.error(pos, |
|
416 "undetermined.type" + (d!=null ? ".1" : ""), |
|
417 t, d); |
|
418 return types.createErrorType(pt); |
|
419 } else { |
|
420 JCDiagnostic d = ex.getDiagnostic(); |
|
421 return typeError(pos, |
|
422 diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d), |
|
423 t, pt); |
|
424 } |
|
425 } catch (Infer.InvalidInstanceException ex) { |
|
426 JCDiagnostic d = ex.getDiagnostic(); |
|
427 log.error(pos, "invalid.inferred.types", t.tvars, d); |
|
428 return types.createErrorType(pt); |
|
429 } |
|
430 } |
|
431 } |
438 |
432 |
439 /** Check that a given type can be cast to a given target type. |
433 /** Check that a given type can be cast to a given target type. |
440 * Return the result of the cast. |
434 * Return the result of the cast. |
441 * @param pos Position to be used for error reporting. |
435 * @param pos Position to be used for error reporting. |
442 * @param found The type that is being cast. |
436 * @param found The type that is being cast. |
553 args.head); |
547 args.head); |
554 args = args.tail; |
548 args = args.tail; |
555 } |
549 } |
556 } |
550 } |
557 return t; |
551 return t; |
558 } |
|
559 |
|
560 /** Check that type is a valid type for a new expression. If the type contains |
|
561 * some uninferred type variables, instantiate them exploiting the expected |
|
562 * type. |
|
563 * |
|
564 * @param pos Position to be used for error reporting. |
|
565 * @param t The type to be checked. |
|
566 * @param noBounds True if type bounds are illegal here. |
|
567 * @param pt Expected type (used with diamond operator) |
|
568 */ |
|
569 Type checkNewClassType(DiagnosticPosition pos, Type t, boolean noBounds, Type pt) { |
|
570 if (t.tag == FORALL) { |
|
571 try { |
|
572 t = instantiatePoly(pos, (ForAll)t, pt, Warner.noWarnings); |
|
573 } |
|
574 catch (Infer.NoInstanceException ex) { |
|
575 JCDiagnostic d = ex.getDiagnostic(); |
|
576 log.error(pos, "cant.apply.diamond", t.getTypeArguments(), d); |
|
577 return types.createErrorType(pt); |
|
578 } |
|
579 } |
|
580 return checkClassType(pos, t, noBounds); |
|
581 } |
552 } |
582 |
553 |
583 /** Check that type is a reifiable class, interface or array type. |
554 /** Check that type is a reifiable class, interface or array type. |
584 * @param pos Position to be used for error reporting. |
555 * @param pos Position to be used for error reporting. |
585 * @param t The type to be checked. |
556 * @param t The type to be checked. |
934 args = args.tail; |
905 args = args.tail; |
935 tvars = tvars.tail; |
906 tvars = tvars.tail; |
936 } |
907 } |
937 |
908 |
938 checkCapture(tree); |
909 checkCapture(tree); |
939 } |
910 |
940 if (tree.type.tag == CLASS || tree.type.tag == FORALL) { |
|
941 // Check that this type is either fully parameterized, or |
911 // Check that this type is either fully parameterized, or |
942 // not parameterized at all. |
912 // not parameterized at all. |
943 if (tree.type.getEnclosingType().isRaw()) |
913 if (tree.type.getEnclosingType().isRaw()) |
944 log.error(tree.pos(), "improperly.formed.type.inner.raw.param"); |
914 log.error(tree.pos(), "improperly.formed.type.inner.raw.param"); |
945 if (tree.clazz.getTag() == JCTree.SELECT) |
915 if (tree.clazz.getTag() == JCTree.SELECT) |