Bring the lambda compiler in sync with latest spec draft:
authormcimadamore
Fri May 20 17:19:01 2011 +0100 (2 years ago)
changeset 104090f2041aa943
parent 1039ff3d911a5488
child 1041d7da41f40abf
Bring the lambda compiler in sync with latest spec draft:
*) Add support for poly types/poly expressions
*) Add support for deferred attribution of poly expressions
*) Improved lambda inference support
*) Refactor code towards unification of lambda/method refs
*) New inference scheme for wildcards in SAM type
*) Add type-parameters to method types
*) Unify method checks in Resolve/Infer
*) Support re-entrant overload resolution
*) Support outwards propagation of constraints/inference variables from lambda body
*) Remove support for function type AST
*) Remove support for function types
src/share/classes/com/sun/source/tree/FunctionTypeTree.java
src/share/classes/com/sun/source/tree/Tree.java
src/share/classes/com/sun/source/tree/TreeVisitor.java
src/share/classes/com/sun/source/util/SimpleTreeVisitor.java
src/share/classes/com/sun/source/util/TreeScanner.java
src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java
src/share/classes/com/sun/tools/javac/code/Flags.java
src/share/classes/com/sun/tools/javac/code/Printer.java
src/share/classes/com/sun/tools/javac/code/Symbol.java
src/share/classes/com/sun/tools/javac/code/Type.java
src/share/classes/com/sun/tools/javac/code/TypeTags.java
src/share/classes/com/sun/tools/javac/code/Types.java
src/share/classes/com/sun/tools/javac/comp/Attr.java
src/share/classes/com/sun/tools/javac/comp/Check.java
src/share/classes/com/sun/tools/javac/comp/Flow.java
src/share/classes/com/sun/tools/javac/comp/Infer.java
src/share/classes/com/sun/tools/javac/comp/Lower.java
src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
src/share/classes/com/sun/tools/javac/comp/Resolve.java
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
src/share/classes/com/sun/tools/javac/comp/Unlambda.java
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
src/share/classes/com/sun/tools/javac/model/JavacTypes.java
src/share/classes/com/sun/tools/javac/parser/JavacParser.java
src/share/classes/com/sun/tools/javac/resources/compiler.properties
src/share/classes/com/sun/tools/javac/tree/JCTree.java
src/share/classes/com/sun/tools/javac/tree/Pretty.java
src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java
test/tools/javac/Diagnostics/6862608/T6862608a.out
test/tools/javac/diags/examples.not-yet.txt
test/tools/javac/diags/examples/UndeterminedType1.java
test/tools/javac/generics/inference/6315770/T6315770.out
test/tools/javac/generics/inference/6638712/T6638712a.out
test/tools/javac/generics/inference/6638712/T6638712b.out
test/tools/javac/generics/inference/6638712/T6638712e.out
test/tools/javac/lambda/BadConv01.java
test/tools/javac/lambda/BadConv02.java
test/tools/javac/lambda/BadConv03.out
test/tools/javac/lambda/BadLambdaPos.out
test/tools/javac/lambda/BadReturn.out
test/tools/javac/lambda/BadTargetType.out
test/tools/javac/lambda/FuncType01.java
test/tools/javac/lambda/LambdaCapture04.java
test/tools/javac/lambda/LambdaCapture05.java
test/tools/javac/lambda/LambdaConv02.out
test/tools/javac/lambda/LambdaConv03.java
test/tools/javac/lambda/LambdaConv04.java
test/tools/javac/lambda/LambdaConv09.out
test/tools/javac/lambda/LambdaConv10.out
test/tools/javac/lambda/LambdaExprNotVoid.out
test/tools/javac/lambda/MethodReference04.out
test/tools/javac/lambda/MethodReference09.out
test/tools/javac/lambda/MethodReference20.out
test/tools/javac/lambda/TargetType01.java
test/tools/javac/lambda/TargetType01.out
test/tools/javac/lambda/TargetType04.out
test/tools/javac/lambda/TargetType06.java
test/tools/javac/lambda/TargetType06.out
test/tools/javac/lambda/TargetType09.java
test/tools/javac/lambda/TargetType10.java
test/tools/javac/lambda/TargetType10.out
test/tools/javac/lambda/TargetType11.java
test/tools/javac/lambda/TargetType11.out
test/tools/javac/lambda/TargetType14.out
test/tools/javac/lambda/TargetType19.java
test/tools/javac/lambda/TargetType19.out
test/tools/javac/lambda/TargetType20.java
test/tools/javac/lambda/badMemberRefBytecode/Main.java
test/tools/javac/lambda/sqe/SAM_types/NonSAM1.out
test/tools/javac/lambda/sqe/SAM_types/NonSAM3.out
test/tools/javac/types/TypeHarness.java
--- a/src/share/classes/com/sun/source/tree/Tree.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/source/tree/Tree.java Fri May 20 17:19:01 2011 +0100
@@ -245,11 +245,6 @@ public interface Tree {
* Used for instances of {@link DisjunctiveTypeTree}.
*/
DISJUNCTIVE_TYPE(DisjunctiveTypeTree.class),
-
- /**
- * Used for instances of {@link FunctionTypeTree}.
- */
- FUNCTION_TYPE(FunctionTypeTree.class),
/**
* Used for instances of {@link TypeCastTree}.
--- a/src/share/classes/com/sun/source/tree/TreeVisitor.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java Fri May 20 17:19:01 2011 +0100
@@ -98,7 +98,6 @@ public interface TreeVisitor<R,P> {
R visitTry(TryTree node, P p);
R visitParameterizedType(ParameterizedTypeTree node, P p);
R visitDisjunctiveType(DisjunctiveTypeTree node, P p);
- R visitFunctionType(FunctionTypeTree node, P p);
R visitArrayType(ArrayTypeTree node, P p);
R visitTypeCast(TypeCastTree node, P p);
R visitPrimitiveType(PrimitiveTypeTree node, P p);
--- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Fri May 20 17:19:01 2011 +0100
@@ -240,10 +240,6 @@ public class SimpleTreeVisitor <R,P> imp
return defaultAction(node, p);
}
- public R visitFunctionType(FunctionTypeTree node, P p) {
- return defaultAction(node, p);
- }
-
public R visitTypeParameter(TypeParameterTree node, P p) {
return defaultAction(node, p);
}
--- a/src/share/classes/com/sun/source/util/TreeScanner.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/source/util/TreeScanner.java Fri May 20 17:19:01 2011 +0100
@@ -369,13 +369,6 @@ public class TreeScanner<R,P> implements
return scan(node.getTypeAlternatives(), p);
}
- public R visitFunctionType(FunctionTypeTree node, P p) {
- R r = scan(node.getArgumentTypes(), p);
- r = scanAndReduce(node.getResultType(), p, r);
- r = scanAndReduce(node.getThrownTypes(), p, r);
- return r;
- }
-
public R visitTypeParameter(TypeParameterTree node, P p) {
R r = scan(node.getBounds(), p);
return r;
--- a/src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java Fri May 20 17:19:01 2011 +0100
@@ -80,7 +80,7 @@ public class TypesImpl implements Types
* {@inheritDoc}
*/
public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
- return env.jctypes.isAssignableNoCheck(((TypeMirrorImpl) t1).type,
+ return env.jctypes.isAssignable(((TypeMirrorImpl) t1).type,
((TypeMirrorImpl) t2).type, Warner.noWarnings);
}
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Fri May 20 17:19:01 2011 +0100
@@ -257,32 +257,27 @@ public class Flags {
* (These occur inside java.lang.invoke.MethodHandle.)
*/
public static final long POLYMORPHIC_SIGNATURE = 1L<<43;
-
- /**
- * Flag that marks a lambda that needs a synthetic return statement
- */
- public static final long NEEDS_RETURN = 1L<<44;
-
+
/**
* Flag that marks an 'effectively final' local variable
*/
- public static final long EFFECTIVELY_FINAL = 1L<<45;
+ public static final long EFFECTIVELY_FINAL = 1L<<44;
/**
* Flag that marks a disjunction var in a multi-catch clause
*/
- public static final long DISJUNCTION = 1L<<46;
+ public static final long DISJUNCTION = 1L<<45;
/**
* Flag that marks a special kind of bridge methods (the ones that
* come from restricted supertype bounds)
*/
- public static final long OVERRIDE_BRIDGE = 1L<<47;
+ public static final long OVERRIDE_BRIDGE = 1L<<46;
/**
* Flag that marks non-override equivalent methods with the same signature
*/
- public static final long CLASH = 1L<<43;
+ public static final long CLASH = 1L<<47;
/** Modifier masks.
*/
--- a/src/share/classes/com/sun/tools/javac/code/Printer.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Printer.java Fri May 20 17:19:01 2011 +0100
@@ -162,7 +162,7 @@ public abstract class Printer implements
@Override
public String visitForAll(ForAll t, Locale locale) {
- return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale);
+ return "?" + visit(t.qtype, locale);
}
@Override
@@ -200,22 +200,6 @@ public abstract class Printer implements
@Override
public String visitMethodType(MethodType t, Locale locale) {
return "(" + printMethodArgs(t.argtypes, false, locale) + ")" + visit(t.restype, locale);
- }
-
- @Override
- public String visitFunctionType(FunctionType t, Locale locale) {
- StringBuilder buf = new StringBuilder();
- buf.append("#");
- buf.append(visit(t.restype, locale));
- buf.append("(");
- buf.append(printMethodArgs(t.argtypes, false, locale));
- buf.append(")");
- if (t.getThrownTypes().nonEmpty()) {
- buf.append("(");
- buf.append(visitTypes(t.thrown, locale));
- buf.append(")");
- }
- return buf.toString();
}
@Override
@@ -339,7 +323,7 @@ public abstract class Printer implements
? s.owner.name.toString()
: s.name.toString();
if (s.type != null) {
- if (s.type.tag == FORALL) {
+ if (s.type.isParameterized()) {
ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
}
ms += "(" + printMethodArgs(
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri May 20 17:19:01 2011 +0100
@@ -1072,8 +1072,8 @@ public abstract class Symbol implements
? owner.name.toString()
: name.toString();
if (type != null) {
- if (type.tag == FORALL)
- s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
+ if (type.isParameterized())
+ s = "<" + type.getTypeArguments() + ">" + s;
s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
}
return s;
--- a/src/share/classes/com/sun/tools/javac/code/Type.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java Fri May 20 17:19:01 2011 +0100
@@ -396,9 +396,13 @@ public class Type implements PrimitiveTy
public boolean isUnbound() { return false; }
public Type withTypeVar(Type t) { return this; }
+ /** The poly tag associated with this type (see TypeTags)
+ */
+ public int getPolyTag() { return NO_POLY; }
+
/** The underlying method type of this type.
*/
- public MethodType asMethodType(Types types) { throw new AssertionError(); }
+ public MethodType asMethodType() { throw new AssertionError(); }
/** Complete loading all classes in this type.
*/
@@ -833,152 +837,65 @@ public class Type implements PrimitiveTy
}
}
- public static class FunctionType extends ClassType {
+ /** Multiple types used in a throws type parameter */
+ public static class DisjunctiveType extends Type {
+
+ public List<Type> alternatives;
+
+ public List<Type> getTypes() {
+ return alternatives;
+ }
+
+ public DisjunctiveType(List<Type> alternatives, com.sun.tools.javac.code.Types types) {
+ super(TypeTags.DISJOINT, types.lub(alternatives).tsym);
+ this.alternatives = alternatives;
+ }
+
+ public String toString() {
+ return alternatives.toString("|");
+ }
+
+ @Override
+ public <R,S> R accept(Type.Visitor<R,S> v, S s) {
+ return v.visitDisjunctiveType(this, s);
+ }
+ }
+
+
+ public static class MethodType extends Type implements ExecutableType {
public List<Type> argtypes;
public Type restype;
public List<Type> thrown;
-
- public FunctionType(List<Type> argtypes,
- Type restype,
- List<Type> thrown,
- TypeSymbol methodHandleClass) {
- super(Type.noType, List.<Type>nil(), methodHandleClass);
- this.argtypes = argtypes;
- this.restype = restype;
- this.thrown = thrown;
- }
-
- @Override
- public <R,S> R accept(Type.Visitor<R,S> v, S s) {
- return v.visitFunctionType(this, s);
- }
-
- public String toString() {
- return "#" + restype + "(" + argtypes + ")" +
- (thrown.isEmpty() ? "" : "(" + thrown + ")");
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!(obj instanceof FunctionType))
- return false;
- FunctionType m = (FunctionType)obj;
- List<Type> args1 = argtypes;
- List<Type> args2 = m.argtypes;
- while (!args1.isEmpty() && !args2.isEmpty()) {
- if (!args1.head.equals(args2.head))
- return false;
- args1 = args1.tail;
- args2 = args2.tail;
- }
- if (!args1.isEmpty() || !args2.isEmpty())
- return false;
- return restype.equals(m.restype);
- }
-
- public int hashCode() {
- int h = CLASS;
- for (List<Type> thisargs = this.argtypes;
- thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
- thisargs = thisargs.tail)
- h = (h << 5) + thisargs.head.hashCode();
- return (h << 5) + this.restype.hashCode();
- }
-
- public List<Type> getParameterTypes() { return argtypes; }
- public Type getReturnType() { return restype; }
- public List<Type> getThrownTypes() { return thrown; }
-
- public void setThrown(List<Type> t) {
- thrown = t;
- }
-
- public boolean isErroneous() {
- return
- isErroneous(argtypes) ||
- restype != null && restype.isErroneous();
- }
-
- @Override
- public MethodType asMethodType(Types types) {
- return new MethodType(argtypes, restype, thrown, types.syms.methodClass);
- }
-
- public Type map(Mapping f) {
- List<Type> argtypes1 = map(argtypes, f);
- Type restype1 = f.apply(restype);
- List<Type> thrown1 = map(thrown, f);
- if (argtypes1 == argtypes &&
- restype1 == restype &&
- thrown1 == thrown) return this;
- else return new FunctionType(argtypes1, restype1, thrown1, tsym);
- }
-
- public boolean contains(Type elem) {
- return elem == this ||
- contains(argtypes, elem) ||
- restype.contains(elem) ||
- thrown.contains(elem);
- }
-
- public boolean isFunctionType() {
- return true;
- }
-
- public void complete() {
- //nothing to do
- }
-
- public List<TypeVar> getTypeVariables() {
- return List.nil();
- }
-
- public TypeSymbol asElement() {
- return null;
- }
- }
-
- /** Multiple types used in a throws type parameter */
- public static class DisjunctiveType extends Type {
-
- public List<Type> alternatives;
-
- public List<Type> getTypes() {
- return alternatives;
- }
-
- public DisjunctiveType(List<Type> alternatives, com.sun.tools.javac.code.Types types) {
- super(TypeTags.DISJOINT, types.lub(alternatives).tsym);
- this.alternatives = alternatives;
- }
-
- public String toString() {
- return alternatives.toString("|");
- }
-
- @Override
- public <R,S> R accept(Type.Visitor<R,S> v, S s) {
- return v.visitDisjunctiveType(this, s);
- }
- }
-
-
- public static class MethodType extends Type implements ExecutableType {
-
- public List<Type> argtypes;
- public Type restype;
- public List<Type> thrown;
+ public List<Type> typeargs;
public MethodType(List<Type> argtypes,
Type restype,
List<Type> thrown,
TypeSymbol methodClass) {
+ this(List.<Type>nil(), argtypes, restype, thrown, methodClass);
+ }
+
+ public MethodType(List<Type> typeargs,
+ List<Type> argtypes,
+ Type restype,
+ List<Type> thrown,
+ TypeSymbol methodClass) {
super(METHOD, methodClass);
+ this.typeargs = typeargs;
this.argtypes = argtypes;
this.restype = restype;
this.thrown = thrown;
+ }
+
+ @Override
+ public boolean isParameterized() {
+ return typeargs.nonEmpty();
+ }
+
+ @Override
+ public List<Type> getTypeArguments() {
+ return typeargs;
}
@Override
@@ -992,7 +909,7 @@ public class Type implements PrimitiveTy
* should be.
*/
public String toString() {
- return "(" + argtypes + ")" + restype;
+ return (isParameterized() ? "<" + typeargs + ">" : "") + "(" + argtypes + ")" + restype;
}
public boolean equals(Object obj) {
@@ -1047,9 +964,12 @@ public class Type implements PrimitiveTy
return elem == this || contains(argtypes, elem) || restype.contains(elem);
}
- public MethodType asMethodType(Types types) { return this; }
+ public MethodType asMethodType() { return this; }
public void complete() {
+ for (List<Type> l = typeargs; l.nonEmpty(); l = l.tail) {
+ ((TypeVar)l.head).bound.complete();
+ }
for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
l.head.complete();
restype.complete();
@@ -1058,7 +978,7 @@ public class Type implements PrimitiveTy
}
public List<TypeVar> getTypeVariables() {
- return List.nil();
+ return List.convert(TypeVar.class, getTypeArguments());
}
public TypeSymbol asElement() {
@@ -1212,14 +1132,58 @@ public class Type implements PrimitiveTy
public List<Type> allparams() { return qtype.allparams(); }
public Type getUpperBound() { return qtype.getUpperBound(); }
public boolean isErroneous() { return qtype.isErroneous(); }
- }
-
- public static class ForAll extends DelegatedType implements ExecutableType {
- public List<Type> tvars;
-
- public ForAll(List<Type> tvars, Type qtype) {
+ public MethodType asMethodType() {
+ Assert.check(qtype.tag == METHOD);
+ return qtype.asMethodType();
+ }
+ }
+
+ /**
+ * A ForAll type is a placeholder for an uninstantiated type - i.e. it is
+ * a polymorphic type that needs to be instantiated against a given
+ * target type. Examples of ForAll types are lambdas, method refernces,
+ * and uninstantiated generic method return types. Note that a polymorphic
+ * type might or might not have type-variables that need to be instantiated.
+ * The act of instantiating a ForAll type against a given target is accomplished
+ * by supplying the target type to the complete() method - this will call
+ * the completer of the ForAll, so that the ForAll type can be instantiated
+ * properly. When a ForAll type has been instantiated, the qtype field
+ * will store the type thos ForAll type has been instantiated to.
+ */
+ public static class ForAll extends DelegatedType {
+
+ private final int polyTag;
+ public Completer completer;
+
+ public interface Completer {
+ /**
+ * A Completer is used to instantiate a ForAll type against a
+ * target type. This interface defines a method 'complete()'
+ * that accepts a ForAll, a target type; calling this method
+ * could end up setting the 'qtype' field of the ForAll
+ *
+ * @param fa ForAll to be completed
+ * @param to target type
+ * @return instantiated type
+ */
+ Type complete(ForAll fa, Type to, boolean allowBoxing);
+ }
+
+ public ForAll(int polyTag, Type qtype) {
super(FORALL, qtype);
- this.tvars = tvars;
+ this.polyTag = polyTag;
+ }
+
+ public Type complete(Type to, boolean allowBoxing) {
+ if (completer != null) {
+ return completer.complete(this, to, allowBoxing);
+ }
+ return qtype;
+ }
+
+ @Override
+ public int getPolyTag() {
+ return polyTag;
}
@Override
@@ -1227,106 +1191,16 @@ public class Type implements PrimitiveTy
return v.visitForAll(this, s);
}
- public String toString() {
- return "<" + tvars + ">" + qtype;
- }
-
- public List<Type> getTypeArguments() { return tvars; }
-
public boolean isErroneous() {
return qtype.isErroneous();
}
- /**
- * Replaces this ForAll's typevars with a set of concrete Java types
- * and returns the instantiated generic type. Subclasses should override
- * in order to check that the list of types is a valid instantiation
- * of the ForAll's typevars. Since the same ForAll can be instantiated
- * multiple times (because of overload resolution) and extra-parameter
- * is used to indicate whether the instantiation is final or not.
- *
- * @param actuals list of actual types
- * @param types types instance
- * @return qtype where all occurrences of tvars are replaced
- * by types in actuals
- */
- public Type inst(List<Type> actuals, Type to, Types types) {
- return inst(actuals, to, types, InstantiationPhase.CHECK);
- }
- public Type inst(List<Type> actuals, Type to, Types types, InstantiationPhase phase) {
- return types.subst(qtype, tvars, actuals);
- }
- //where
- public enum InstantiationPhase {
- RESOLUTION,
- CHECK;
- }
-
- /**
- * Kind of type-constraint derived during type inference
- */
- public enum ConstraintKind {
- /**
- * upper bound constraint (a type variable must be instantiated
- * with a type T, where T is a subtype of all the types specified by
- * its EXTENDS constraints).
- */
- EXTENDS,
- /**
- * lower bound constraint (a type variable must be instantiated
- * with a type T, where T is a supertype of all the types specified by
- * its SUPER constraints).
- */
- SUPER,
- /**
- * equality constraint (a type variable must be instantiated to the type
- * specified by its EQUAL constraint.
- */
- EQUAL;
- }
-
- /**
- * Get the type-constraints of a given kind for a given type-variable of
- * this ForAll type. Subclasses should override in order to return more
- * accurate sets of constraints.
- *
- * @param tv the type-variable for which the constraint is to be retrieved
- * @param ck the constraint kind to be retrieved
- * @return the list of types specified by the selected constraint
- */
- public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
- return List.nil();
- }
-
public Type map(Mapping f) {
return f.apply(qtype);
}
public boolean contains(Type elem) {
return qtype.contains(elem);
- }
-
- public MethodType asMethodType(Types types) {
- return qtype.asMethodType(types);
- }
-
- public void complete() {
- for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
- ((TypeVar)l.head).bound.complete();
- }
- qtype.complete();
- }
-
- public List<TypeVar> getTypeVariables() {
- return List.convert(TypeVar.class, getTypeArguments());
- }
-
- public TypeKind getKind() {
- return TypeKind.EXECUTABLE;
- }
-
- public <R, P> R accept(TypeVisitor<R, P> v, P p) {
- return v.visitExecutable(this, p);
}
}
@@ -1482,7 +1356,6 @@ public class Type implements PrimitiveTy
R visitArrayType(ArrayType t, S s);
R visitMethodType(MethodType t, S s);
R visitDisjunctiveType(DisjunctiveType t, S s);
- R visitFunctionType(FunctionType t, S s);
R visitPackageType(PackageType t, S s);
R visitTypeVar(TypeVar t, S s);
R visitCapturedType(CapturedType t, S s);
--- a/src/share/classes/com/sun/tools/javac/code/TypeTags.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/TypeTags.java Fri May 20 17:19:01 2011 +0100
@@ -137,4 +137,22 @@ public class TypeTags {
/** The minimum tag of a partial type
*/
public static final int firstPartialTag = ERROR;
+
+ /*** POLY TAGS ***/
+
+ /** Poly tag for non-poly types
+ */
+ public static final int NO_POLY = 0;
+
+ /** Poly tag for lambda poly types
+ */
+ public static final int POLY_LAMBDA = NO_POLY + 1;
+
+ /** Poly tag for method references poly types
+ */
+ public static final int POLY_REFERENCE = POLY_LAMBDA + 1;
+
+ /** Poly tag for generic method return types
+ */
+ public static final int POLY_RETURN = POLY_REFERENCE + 1;
}
--- a/src/share/classes/com/sun/tools/javac/code/Types.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java Fri May 20 17:19:01 2011 +0100
@@ -38,6 +38,7 @@ import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.comp.Infer;
import com.sun.tools.javac.comp.AttrContext;
import static com.sun.tools.javac.code.Type.*;
@@ -74,16 +75,16 @@ public class Types {
new Context.Key<Types>();
final Symtab syms;
+ final Infer infer;
final JavacMessages messages;
final Names names;
- final boolean allowBoxing;
+ final boolean boxingEnabled;
final boolean allowAbstractClassInSamConversion;
final ClassReader reader;
final Source source;
final Check chk;
List<Warner> warnStack = List.nil();
final Name capturedName;
- final ConversionException conversionException;
// <editor-fold defaultstate="collapsed" desc="Instantiating">
public static Types instance(Context context) {
@@ -96,14 +97,14 @@ public class Types {
protected Types(Context context) {
context.put(typesKey, this);
syms = Symtab.instance(context);
+ infer = Infer.instance(context);
names = Names.instance(context);
- allowBoxing = Source.instance(context).allowBoxing();
+ boxingEnabled = Source.instance(context).allowBoxing();
reader = ClassReader.instance(context);
source = Source.instance(context);
chk = Check.instance(context);
capturedName = names.fromString("<captured wildcard>");
messages = JavacMessages.instance(context);
- conversionException = new ConversionException();
Options opts = Options.instance(context);
allowAbstractClassInSamConversion = opts.isSet("abstractSAM");
}
@@ -121,6 +122,14 @@ public class Types {
public Type upperBound(Type t) {
return upperBound.visit(t);
}
+
+ public List<Type> upperBounds(List<Type> ts) {
+ ListBuffer<Type> buf = lb();
+ for (Type t : ts) {
+ buf.append(upperBound(t));
+ }
+ return buf.toList();
+ }
// where
private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
@@ -150,6 +159,14 @@ public class Types {
*/
public Type lowerBound(Type t) {
return lowerBound.visit(t);
+ }
+
+ public List<Type> lowerBounds(List<Type> ts) {
+ ListBuffer<Type> buf = lb();
+ for (Type t : ts) {
+ buf.append(lowerBound(t));
+ }
+ return buf.toList();
}
// where
private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
@@ -274,84 +291,20 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="isConvertible">
/**
- * Is t a subtype of or convertiable via boxing/unboxing/lambda
+ * Is t a subtype of or convertiable via boxing/unboxing
* convertions to s?
*/
- public boolean isConvertible(Env<AttrContext> env, Type t, Type s) {
- return isConvertible(env, t, s, Warner.noWarnings);
- }
-
- public boolean isConvertibleNoCheck(Type t, Type s) {
- return isConvertibleNoCheck(t, s, Warner.noWarnings);
- }
- //where
- private boolean isConvertibleNoCheck(Type t, Type s, Warner warn) {
- return isConvertible(null, t, s, warn);
- }
-
- List<Type> boxedTypesOrTypes(List<Type> ts) {
- ListBuffer<Type> buf = lb();
- for (Type t : ts) {
- buf.append(boxedTypeOrType(t));
- }
- return buf.toList();
- }
-
- public boolean isConvertible(Env<AttrContext> env, final Type t, final Type s, final Warner warn) {
- try {
- rawIsConvertible(env, t, s, warn);
- return true;
- } catch (ConversionException ex) {
- return false;
- }
- }
-
- public void rawIsConvertible(Env<AttrContext> env, final Type t, final Type s, final Warner warn) throws ConversionException {
- if (isFunctionType(t) &&
- (s.tsym.kind == Kinds.TYP) &&
- env != null) {
- final SAMResult samRes = findSAM(s, env);
- if (samRes.isErroneous()) {
- throw conversionException.setMessage(samRes.errKey, samRes.args);
- }
- Type mtype = samRes.getTargetType();
- //the order is important here because of type-inference
- //(reference types first)
- boolean isReturnOk = t.getReturnType().tag == NONE || (t.getReturnType() == syms.voidType ?
- (isSameType(mtype.getReturnType(), boxedClass(syms.voidType).type) ||
- isSameType(mtype.getReturnType(), syms.voidType)) :
- (containsType(boxedTypeOrType(mtype.getReturnType()), boxedTypeOrType(t.getReturnType()))) ||
- covariantReturnType(boxedTypeOrType(t.getReturnType()), boxedTypeOrType(mtype.getReturnType()), Warner.noWarnings));
-
- boolean argsOk = t.getParameterTypes().size() == mtype.getParameterTypes().size() &&
- containsType(mtype.getParameterTypes(), t.getParameterTypes());
-
- boolean thrownOk = t.getThrownTypes() == Type.noTypes ||
- chk.unhandled(t.getThrownTypes(), mtype.getThrownTypes()).isEmpty();
- if (!isReturnOk || !argsOk || !thrownOk) {
- //target method is not compatible
- throw conversionException.setMessage("incompatible.target.in.lambda.conv",
- samRes.getTargetName(),
- Kinds.kindName(s.tsym),
- s.tsym);
- }
- return;
- }
- else {
- boolean tPrimitive = t.isPrimitive();
- boolean sPrimitive = s.isPrimitive();
- if (tPrimitive == sPrimitive) {
- checkUnsafeVarargsConversion(t, s, warn);
- if (!isSubtypeUnchecked(t, s, warn)) throw conversionException.setMessage(null);
- return;
- }
- if (!allowBoxing) throw conversionException.setMessage(null);
- boolean works = tPrimitive
- ? isSubtype(boxedClass(t).type, s)
- : isSubtype(unboxedType(t), s);
- if (!works)
- throw conversionException.setMessage(null);
- }
+ public boolean isConvertible(Type t, Type s, Warner warn) {
+ boolean tPrimitive = t.isPrimitive();
+ boolean sPrimitive = s.isPrimitive();
+ if (tPrimitive == sPrimitive) {
+ checkUnsafeVarargsConversion(t, s, warn);
+ return isSubtypeUnchecked(t, s, warn);
+ }
+ if (!boxingEnabled) return false;
+ return tPrimitive
+ ? isSubtype(boxedClass(t).type, s)
+ : isSubtype(unboxedType(t), s);
}
//where
private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
@@ -374,34 +327,14 @@ public class Types {
warn.warn(LintCategory.VARARGS);
}
}
-
- /**
- * This class is used to keep track of the result of a given conversion.
- * In order to retrieve a boolean value (success/failure) clients must
- * supply a type to the 'check' method. This is required as some kinds
- * of conversion (see lambda conversion) also perform an accessibility
- * check - as such their outcome depends on the current attribution environment.
- * This class also stores detailed information about why a type conversion
- * has failed; this info can be leveraged when a diagnostic message is
- * generated by javac.
- */
- public static class ConversionException extends RuntimeException {
-
- private String detailsKey;
- private Object[] detailsArgs;
-
- public ConversionException setMessage(String key, Object... args) {
- this.detailsKey = key;
- this.detailsArgs = args;
- return this;
- }
-
- public JCDiagnostic getDiagnostic(JCDiagnostic.Factory diags) {
- return detailsKey != null ?
- diags.fragment(detailsKey, detailsArgs) :
- null;
- }
- }
+ /**
+ * Is t a subtype of or convertiable via boxing/unboxing
+ * convertions to s?
+ */
+ public boolean isConvertible(Type t, Type s) {
+ return isConvertible(t, s, Warner.noWarnings);
+ }
+ // </editor-fold>
// <editor-fold defaultstate="collapsed" desc="findSam">
@@ -592,7 +525,7 @@ public class Types {
return targetType;
} else {
if (methodSyms.size() == 1) {
- if (methodSyms.head.type.tag == FORALL) {
+ if (methodSyms.head.type.isParameterized()) {
setDiagnostic("invalid.generic.target.for.lambda.conv");
return syms.errType;
} else if (!isAccessible(methodSyms.head, site)) {
@@ -605,7 +538,7 @@ public class Types {
else {
// size > 1
for (Symbol msym : methodSyms) {
- if (msym.type.tag == FORALL) {
+ if (msym.type.isParameterized()) {
setDiagnostic("invalid.generic.target.for.lambda.conv");
return syms.errType;
} else if (!isAccessible(methodSyms.head, site)) {
@@ -698,68 +631,6 @@ public class Types {
this.args = args2;
}
}
- // </editor-fold>
-
- // <editor-fold defaultstate="collapsed" desc="normalize">
-
- /**
- * Removes toplevel wildcard from a generic classtype. E.g. if T is a
- * classtype of the kind C< ... , ? super/extends A, ... > this method
- * finds a type S of the kind C<..., A, ...>. Then, the new type S
- * is returned (assuming S <: T) otherwise an error type is returned.
- *
- * @param t the type to be normalized
- * @return a type where toplevel wildcards have been removed
- */
- public Type normalize(Type t) {
-
- class Normalizer extends UnaryVisitor<Type> {
-
- boolean seenTopLevel = false;
-
- @Override
- public Type visitClassType(ClassType ct, Void s) {
- if (!seenTopLevel) {
- seenTopLevel = true;
- boolean changed = false;
- ListBuffer<Type> buf = lb();
- for (Type t : ct.getTypeArguments()) {
- Type t2 = visit(t);
- if (t != t2) changed = true;
- buf.append(t2);
- }
- if (changed)
- return new ClassType(ct.getEnclosingType(),
- buf.toList(), ct.tsym);
- }
- return ct;
- }
-
- @Override
- public Type visitWildcardType(WildcardType t, Void s) {
- return visit(t.type);
- }
-
- @Override
- public Type visitForAll(ForAll t, Void s) {
- Type qtype2 = visit(t.qtype);
- if (qtype2 != t.qtype) {
- return new ForAll(t.tvars, qtype2);
- }
- return t;
- }
-
- public Type visitType(Type t, Void s) {
- return t;
- }
-
- }
- Type t2 = new Normalizer().visit(t);
- return isSubtypeUnchecked(t2, t) ?
- t2 : createErrorType(t);
- }
-
-
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isSubtype">
@@ -923,22 +794,6 @@ public class Types {
}
@Override
- public Boolean visitFunctionType(FunctionType t, Type s) {
- if (isFunctionType(s)) {
- FunctionType that = (FunctionType)s;
- boolean isReturnOk =
- isSubtype(t.getReturnType(), that.getReturnType());
- boolean argsOk = t.getParameterTypes().size() == that.getParameterTypes().size() &&
- isSubtypes(that.getParameterTypes(), t.getParameterTypes());
- boolean thrownOk = chk.unhandled(t.getThrownTypes(), that.getThrownTypes()).isEmpty();
- return isReturnOk && argsOk && thrownOk;
- }
- else {
- return false;
- }
- }
-
- @Override
public Boolean visitDisjunctiveType(DisjunctiveType t, Type s) {
List<Type> ss = s.tag == DISJOINT ?
((DisjunctiveType)s).alternatives :
@@ -993,10 +848,7 @@ public class Types {
if (t.inst != null)
return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
- else if ((s.isPrimitive() || s.tag == VOID) &&
- (t.qtype.tsym.flags() & LAMBDA) != 0) {
- t.inst = s;
- } else {
+ else {
t.hibounds = t.hibounds.prepend(s);
}
return true;
@@ -1186,7 +1038,13 @@ public class Types {
public Boolean visitMethodType(MethodType t, Type s) {
// isSameType for methods does not take thrown
// exceptions into account!
- return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
+ if (t.isParameterized() != s.isParameterized()) return false;
+ if (t.isParameterized() &&
+ !hasSameBounds(t.getTypeArguments(), s.getTypeArguments())) {
+ return false;
+ }
+ return hasSameArgs(t, subst(s, s.getTypeArguments(), t.getTypeArguments())) &&
+ visit(t.getReturnType(), subst(s.getReturnType(), s.getTypeArguments(), t.getTypeArguments()));
}
@Override
@@ -1199,9 +1057,7 @@ public class Types {
if (s.tag != FORALL)
return false;
- ForAll forAll = (ForAll)s;
- return hasSameBounds(t, forAll)
- && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
+ return visit(t.qtype, ((ForAll)s).qtype);
}
@Override
@@ -1456,27 +1312,14 @@ public class Types {
* s is assumed to be an erased type.<br>
* (not defined for Method and ForAll types).
*/
- public boolean isCastable(Env<AttrContext> env, Type t, Type s) {
- return isCastable(env, t, s, Warner.noWarnings);
- }
-
- public boolean isCastable(Env<AttrContext> env, Type t, Type s, Warner warn) {
+ public boolean isCastable(Type t, Type s) {
+ return isCastable(t, s, Warner.noWarnings);
+ }
+
+ public boolean isCastable(Type t, Type s, Warner warn) {
if (t.isPrimitive() != s.isPrimitive())
- return allowBoxing && (isConvertible(env, t, s, warn) || isConvertible(env, s, t, warn));
- else if (isConvertible(env, t, s, warn))
- return true;
- else
- return isCastableReference(t, s, warn);
- }
-
- public boolean isCastableNoCheck(Type t, Type s) {
- return isCastableNoCheck(t, s, Warner.noWarnings);
- }
- //where
- private boolean isCastableNoCheck(Type t, Type s, Warner warn) {
- if (t.isPrimitive() != s.isPrimitive())
- return allowBoxing && (isConvertibleNoCheck(t, s, warn) || isConvertibleNoCheck(s, t, warn));
- else if (isConvertibleNoCheck(t, s, warn))
+ return boxingEnabled && (isConvertible(t, s, warn) || isConvertible(s, t, warn));
+ else if (isConvertible(t, s, warn))
return true;
else
return isCastableReference(t, s, warn);
@@ -1527,6 +1370,11 @@ public class Types {
@Override
public Boolean visitWildcardType(WildcardType t, Type s) {
return isCastableReference(upperBound(t), s, warnStack.head);
+ }
+
+ @Override
+ public Boolean visitForAll(ForAll t, Type s) {
+ return true;
}
@Override
@@ -1893,14 +1741,6 @@ public class Types {
return t.tag == ARRAY;
}
- public boolean isFunctionType(Type t) {
- switch (t.tag) {
- case CLASS: return ((ClassType)t).isFunctionType();
- case FORALL: return isFunctionType(((ForAll)t).qtype);
- default: return false;
- }
- }
-
/**
* The element type of an array.
*/
@@ -2125,19 +1965,8 @@ public class Types {
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isAssignable">
- public boolean isAssignable(Env<AttrContext> env, Type t, Type s) {
- return isAssignable(env, t, s, Warner.noWarnings);
- }
-
- //the following methods should be private, but they need to be accessed from
- //deprecated methods in JavacTypes (for backward compatibility)
-
- public boolean isAssignableNoCheck(Type t, Type s) {
- return isAssignableNoCheck(t, s, Warner.noWarnings);
- }
- //where
- public boolean isAssignableNoCheck(Type t, Type s, Warner warner) {
- return isAssignable(null, t, s, warner);
+ public boolean isAssignable(Type t, Type s) {
+ return isAssignable(t, s, Warner.noWarnings);
}
/**
@@ -2146,53 +1975,37 @@ public class Types {
* types.<br>
* (not defined for Method and ForAll types)
*/
- /**
- * Is t assignable to s?<br>
- * Equivalent to subtype except for constant values and raw
- * types.<br>
- * (not defined for Method and ForAll types)
- */
- public boolean isAssignable(Env<AttrContext> env, Type t, Type s, Warner warn) {
- try {
- rawIsAssignable(env, t, s, warn);
+ public boolean isAssignable(Type t, Type s, Warner warn) {
+ if (t.tag == ERROR)
return true;
- } catch(ConversionException ex) {
- return false;
- }
- }
-
- public void rawIsAssignable(Env<AttrContext> env, Type t, Type s, Warner warn) throws ConversionException {
- if (t.tag == ERROR)
- return;
if (t.tag <= INT && t.constValue() != null) {
int value = ((Number)t.constValue()).intValue();
switch (s.tag) {
case BYTE:
if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
- return;
+ return true;
break;
case CHAR:
if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
- return;
+ return true;
break;
case SHORT:
if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
- return;
+ return true;
break;
case INT:
- return;
+ return true;
case CLASS:
switch (unboxedType(s).tag) {
case BYTE:
case CHAR:
case SHORT:
- rawIsAssignable(env, t, unboxedType(s), warn);
- return;
+ return isAssignable(t, unboxedType(s), warn);
}
break;
}
}
- rawIsConvertible(env, t, s, warn);
+ return isConvertible(t, s, warn);
}
// </editor-fold>
@@ -2232,11 +2045,6 @@ public class Types {
erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
}
return erased;
- }
-
- @Override
- public Type visitFunctionType(FunctionType t, Boolean recurse) {
- return syms.methodHandleType;
}
@Override
@@ -2863,18 +2671,16 @@ public class Types {
@Override
public Boolean visitMethodType(MethodType t, Type s) {
- return s.tag == METHOD
- && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
- }
-
- @Override
- public Boolean visitForAll(ForAll t, Type s) {
- if (s.tag != FORALL)
- return strict ? false : visitMethodType(t.asMethodType(Types.this), s);
-
- ForAll forAll = (ForAll)s;
- return hasSameBounds(t, forAll)
- && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
+ if (s.tag != METHOD ||
+ (strict && t.isParameterized() != s.isParameterized())) return false;
+
+ if (t.isParameterized() == s.isParameterized() &&
+ !hasSameBounds(t.getTypeArguments(), s.getTypeArguments())) {
+ return false;
+ }
+
+ return s.tag == METHOD &&
+ containsTypeEquivalent(t.argtypes, subst(s.getParameterTypes(), s.getTypeArguments(), t.getTypeArguments()));
}
@Override
@@ -2882,11 +2688,10 @@ public class Types {
return false;
}
};
-
- TypeRelation hasSameArgs_strict = new HasSameArgs(true);
- TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
-
- // </editor-fold>
+ // </editor-fold>
+
+ TypeRelation hasSameArgs_strict = new HasSameArgs(true);
+ TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
// <editor-fold defaultstate="collapsed" desc="subst">
public List<Type> subst(List<Type> ts,
@@ -2950,15 +2755,32 @@ public class Types {
@Override
public Type visitMethodType(MethodType t, Void ignored) {
+ if (Type.containsAny(to, t.getTypeArguments())) {
+ //perform alpha-renaming of free-variables in 't'
+ //if 'to' types contain variables that are free in 't'
+ List<Type> freevars = newInstances(t.getTypeArguments());
+ t = new MethodType(freevars,
+ Types.this.subst(t.getParameterTypes(), t.getTypeArguments(), freevars),
+ Types.this.subst(t.getReturnType(), t.getTypeArguments(), freevars),
+ Types.this.subst(t.getThrownTypes(), t.getTypeArguments(), freevars),
+ syms.methodClass);
+ }
+ List<Type> typeargs = substBounds(t.typeargs, from, to);
List<Type> argtypes = subst(t.argtypes);
Type restype = subst(t.restype);
List<Type> thrown = subst(t.thrown);
- if (argtypes == t.argtypes &&
+ if (typeargs == t.typeargs &&
+ argtypes == t.argtypes &&
restype == t.restype &&
thrown == t.thrown)
return t;
- else
- return new MethodType(argtypes, restype, thrown, t.tsym);
+ else {
+ return new MethodType(typeargs,
+ Types.this.subst(argtypes, t.getTypeArguments(), typeargs),
+ Types.this.subst(restype, t.getTypeArguments(), typeargs),
+ Types.this.subst(thrown, t.getTypeArguments(), typeargs),
+ syms.methodClass);
+ }
}
@Override
@@ -2995,19 +2817,6 @@ public class Types {
}
@Override
- public Type visitFunctionType(FunctionType t, Void ignored) {
- List<Type> argtypes = subst(t.argtypes);
- Type restype = subst(t.restype);
- List<Type> thrown = subst(t.thrown);
- if (argtypes == t.argtypes &&
- restype == t.restype &&
- thrown == t.thrown)
- return t;
- else
- return new FunctionType(argtypes, restype, thrown, t.tsym);
- }
-
- @Override
public Type visitWildcardType(WildcardType t, Void ignored) {
Type bound = t.type;
if (t.kind != BoundKind.UNBOUND)
@@ -3028,26 +2837,6 @@ public class Types {
return t;
else
return new ArrayType(upperBound(elemtype), t.tsym);
- }
-
- @Override
- public Type visitForAll(ForAll t, Void ignored) {
- if (Type.containsAny(to, t.tvars)) {
- //perform alpha-renaming of free-variables in 't'
- //if 'to' types contain variables that are free in 't'
- List<Type> freevars = newInstances(t.tvars);
- t = new ForAll(freevars,
- Types.this.subst(t.qtype, t.tvars, freevars));
- }
- List<Type> tvars1 = substBounds(t.tvars, from, to);
- Type qtype1 = subst(t.qtype);
- if (tvars1 == t.tvars && qtype1 == t.qtype) {
- return t;
- } else if (tvars1 == t.tvars) {
- return new ForAll(tvars1, qtype1);
- } else {
- return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
- }
}
@Override
@@ -3123,14 +2912,14 @@ public class Types {
/**
* Does t have the same bounds for quantified variables as s?
*/
- boolean hasSameBounds(ForAll t, ForAll s) {
- List<Type> l1 = t.tvars;
- List<Type> l2 = s.tvars;
+ boolean hasSameBounds(List<Type> targs1, List<Type> targs2) {
+ List<Type> l1 = targs1;
+ List<Type> l2 = targs2;
while (l1.nonEmpty() && l2.nonEmpty() &&
isSameType(l1.head.getUpperBound(),
subst(l2.head.getUpperBound(),
- s.tvars,
- t.tvars))) {
+ targs2,
+ targs1))) {
l1 = l1.tail;
l2 = l2.tail;
}
@@ -3155,53 +2944,25 @@ public class Types {
};
// </editor-fold>
- public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
- return original.accept(methodWithParameters, newParams);
- }
- // where
- private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
- public Type visitType(Type t, List<Type> newParams) {
- throw new IllegalArgumentException("Not a method type: " + t);
- }
- public Type visitMethodType(MethodType t, List<Type> newParams) {
- return new MethodType(newParams, t.restype, t.thrown, t.tsym);
- }
- public Type visitForAll(ForAll t, List<Type> newParams) {
- return new ForAll(t.tvars, t.qtype.accept(this, newParams));
- }
- };
-
- public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
- return original.accept(methodWithThrown, newThrown);
- }
- // where
- private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
- public Type visitType(Type t, List<Type> newThrown) {
- throw new IllegalArgumentException("Not a method type: " + t);
- }
- public Type visitMethodType(MethodType t, List<Type> newThrown) {
- return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
- }
- public Type visitForAll(ForAll t, List<Type> newThrown) {
- return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
- }
- };
-
- public Type createMethodTypeWithReturn(Type original, Type newReturn) {
- return original.accept(methodWithReturn, newReturn);
- }
- // where
- private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() {
- public Type visitType(Type t, Type newReturn) {
- throw new IllegalArgumentException("Not a method type: " + t);
- }
- public Type visitMethodType(MethodType t, Type newReturn) {
- return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym);
- }
- public Type visitForAll(ForAll t, Type newReturn) {
- return new ForAll(t.tvars, t.qtype.accept(this, newReturn));
- }
- };
+ public MethodType createMethodTypeWithTypeArguments(Type original, List<Type> newTypeargs) {
+ Assert.check(original.tag == METHOD);
+ return new MethodType(newTypeargs, original.getParameterTypes(), original.getReturnType(), original.getThrownTypes(), original.tsym);
+ }
+
+ public MethodType createMethodTypeWithParameters(Type original, List<Type> newParams) {
+ Assert.check(original.tag == METHOD);
+ return new MethodType(original.getTypeArguments(), newParams, original.getReturnType(), original.getThrownTypes(), original.tsym);
+ }
+
+ public MethodType createMethodTypeWithThrown(Type original, List<Type> newThrown) {
+ Assert.check(original.tag == METHOD);
+ return new MethodType(original.getTypeArguments(), original.getParameterTypes(), original.getReturnType(), newThrown, original.tsym);
+ }
+
+ public MethodType createMethodTypeWithReturn(Type original, Type newReturn) {
+ Assert.check(original.tag == METHOD);
+ return new MethodType(original.getTypeArguments(), original.getParameterTypes(), newReturn, original.getThrownTypes(), original.tsym);
+ }
// <editor-fold defaultstate="collapsed" desc="createErrorType">
public Type createErrorType(Type originalType) {
@@ -3292,7 +3053,7 @@ public class Types {
public String toString(Type t) {
if (t.tag == FORALL) {
ForAll forAll = (ForAll)t;
- return typaramsString(forAll.tvars) + forAll.qtype;
+ return toString(forAll.qtype);
}
return "" + t;
}
@@ -3822,7 +3583,7 @@ public class Types {
source.allowCovariantReturns() &&
!t.isPrimitive() &&
!s.isPrimitive() &&
- isAssignableNoCheck(t, s, warner);
+ isAssignable(t, s, warner);
}
// </editor-fold>
@@ -3847,7 +3608,7 @@ public class Types {
* Return the primitive type corresponding to a boxed type.
*/
public Type unboxedType(Type t) {
- if (allowBoxing) {
+ if (boxingEnabled) {
for (int i=0; i<syms.boxedName.length; i++) {
Name box = syms.boxedName[i];
if (box != null &&
@@ -3988,16 +3749,6 @@ public class Types {
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Internal utility methods">
- private List<Type> upperBounds(List<Type> ss) {
- if (ss.isEmpty()) return ss;
- Type head = upperBound(ss.head);
- List<Type> tail = upperBounds(ss.tail);
- if (head != ss.head || tail != ss.tail)
- return tail.prepend(head);
- else
- return ss;
- }
-
private boolean sideCast(Type from, Type to, Warner warn) {
// We are casting from type $from$ to type $to$, which are
// non-final unrelated types. This method
@@ -4414,7 +4165,6 @@ public class Types {
public R visitArrayType(ArrayType t, S s) { return visitType(t, s); }
public R visitMethodType(MethodType t, S s) { return visitType(t, s); }
public R visitDisjunctiveType(DisjunctiveType t, S s) { return visitType(t, s); }
- public R visitFunctionType(FunctionType t, S s) { return visitType(t, s); }
public R visitPackageType(PackageType t, S s) { return visitType(t, s); }
public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); }
public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
@@ -4464,10 +4214,6 @@ public class Types {
return visitTypeVar(t, s);
}
@Override
- public R visitFunctionType(FunctionType t, S s) {
- return visitClassType(t, s);
- }
- @Override
public R visitForAll(ForAll t, S s) {
return visit(t.qtype, s);
}
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri May 20 17:19:01 2011 +0100
@@ -42,6 +42,7 @@ import com.sun.tools.javac.code.Attribut
import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.code.Type.ForAll.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.source.tree.IdentifierTree;
@@ -88,6 +89,13 @@ public class Attr extends JCTree.Visitor
final DeferredLintHandler deferredLintHandler;
final HashMap<JCTree, Env<AttrContext>> lambdaEnvs = new HashMap<JCTree, Env<AttrContext>>();
+ enum LambdaCheckKind {
+ RESOLUTION,
+ CHECK;
+ }
+
+ private LambdaCheckKind lambdaCheckKind = LambdaCheckKind.RESOLUTION;
+
public static Attr instance(Context context) {
Attr instance = context.get(attrKey);
if (instance == null)
@@ -121,7 +129,7 @@ public class Attr extends JCTree.Visitor
allowGenerics = source.allowGenerics();
allowVarargs = source.allowVarargs();
allowEnums = source.allowEnums();
- allowBoxing = source.allowBoxing();
+ boxingEnabled = source.allowBoxing();
allowCovariantReturns = source.allowCovariantReturns();
allowAnonOuterThis = source.allowAnonOuterThis();
allowStringsInSwitch = source.allowStringsInSwitch();
@@ -156,7 +164,7 @@ public class Attr extends JCTree.Visitor
/** Switch: support boxing and unboxing?
*/
- boolean allowBoxing;
+ boolean boxingEnabled;
/** Switch: support covariant result types?
*/
@@ -222,18 +230,25 @@ public class Attr extends JCTree.Visitor
* @param pt The expected type (or: prototype) of the tree
*/
Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
- if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
- if ((ownkind & ~pkind) == 0) {
- owntype = chk.checkType(tree.pos(), env, owntype, pt, errKey);
- } else {
- log.error(tree.pos(), "unexpected.type",
- kindNames(pkind),
- kindName(ownkind));
- owntype = types.createErrorType(owntype);
- }
- }
- tree.type = owntype;
- return owntype;
+ LambdaCheckKind prevLambdaCheckKind = lambdaCheckKind;
+ try {
+ lambdaCheckKind = LambdaCheckKind.CHECK;
+ if (owntype.tag != ERROR && pt.tag != METHOD) {
+ if ((ownkind & ~pkind) == 0) {
+ owntype = chk.checkType(tree.pos(), env, owntype, pt, errKey);
+ } else {
+ log.error(tree.pos(), "unexpected.type",
+ kindNames(pkind),
+ kindName(ownkind));
+ owntype = types.createErrorType(owntype);
+ }
+ }
+ tree.type = owntype;
+ return owntype;
+ }
+ finally {
+ lambdaCheckKind = prevLambdaCheckKind;
+ }
}
/** Is given blank final variable assignable, i.e. in a scope where it
@@ -540,7 +555,7 @@ public class Attr extends JCTree.Visitor
ListBuffer<Type> argtypes = new ListBuffer<Type>();
for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
argtypes.append(chk.checkNonVoid(
- l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly, "incompatible.types"))));
+ l.head.pos(), attribTree(l.head, env, VAL, Infer.lambdaPoly, "incompatible.types")));
return argtypes.toList();
}
@@ -1264,9 +1279,9 @@ public class Attr extends JCTree.Visitor
if (types.isSameType(thentype, elsetype))
return thentype.baseType();
- Type thenUnboxed = (!allowBoxing || thentype.isPrimitive())
+ Type thenUnboxed = (!boxingEnabled || thentype.isPrimitive())
? thentype : types.unboxedType(thentype);
- Type elseUnboxed = (!allowBoxing || elsetype.isPrimitive())
+ Type elseUnboxed = (!boxingEnabled || elsetype.isPrimitive())
? elsetype : types.unboxedType(elsetype);
// Otherwise, if both arms can be converted to a numeric
@@ -1278,10 +1293,10 @@ public class Attr extends JCTree.Visitor
// short, or char), and the other is an integer constant
// that fits into the subrange, return the subrange type.
if (thenUnboxed.tag < INT && elseUnboxed.tag == INT &&
- types.isAssignable(env, elseUnboxed, thenUnboxed))
+ types.isAssignable(elseUnboxed, thenUnboxed))
return thenUnboxed.baseType();
if (elseUnboxed.tag < INT && thenUnboxed.tag == INT &&
- types.isAssignable(env, thenUnboxed, elseUnboxed))
+ types.isAssignable(thenUnboxed, elseUnboxed))
return elseUnboxed.baseType();
for (int i = BYTE; i < VOID; i++) {
@@ -1293,7 +1308,7 @@ public class Attr extends JCTree.Visitor
}
// Those were all the cases that could result in a primitive
- if (allowBoxing) {
+ if (boxingEnabled) {
if (thentype.isPrimitive())
thentype = types.boxedClass(thentype).type;
if (elsetype.isPrimitive())
@@ -1305,7 +1320,7 @@ public class Attr extends JCTree.Visitor
if (types.isSubtype(elsetype, thentype))
return thentype.baseType();
- if (!allowBoxing || thentype.tag == VOID || elsetype.tag == VOID) {
+ if (!boxingEnabled || thentype.tag == VOID || elsetype.tag == VOID) {
log.error(pos, diagKey,
thentype, elsetype);
return thentype.baseType();
@@ -1419,37 +1434,24 @@ public class Attr extends JCTree.Visitor
// Check that there is an enclosing method which is
// nested within than the enclosing class.
if (env.enclMethod == null ||
- (env.enclMethod.sym.owner != env.enclClass.sym &&
- !env.enclMethod.sym.name.equals(names.lambda))) {
+ env.enclMethod.sym.owner != env.enclClass.sym) {
log.error(tree.pos(), "ret.outside.meth");
-
} else {
+ Type typeToCheck = env.enclMethod.sym.type.getReturnType();
+ //lambda expression does not have expected return type (at this stage)
+ if ((env.enclMethod.sym.flags() & LAMBDA) != 0) {
+ typeToCheck = Infer.anyPoly;
+ }
// Attribute return expression, if it exists, and check that
// it conforms to result type of enclosing method.
- Symbol m = env.enclMethod.sym;
- boolean isLambda = (env.enclMethod.sym.flags() & LAMBDA) != 0;
- if (m.type.getReturnType().tag == VOID) {
+ if (typeToCheck.tag == VOID) {
if (tree.expr != null)
log.error(tree.expr.pos(),
"cant.ret.val.from.meth.decl.void");
- } else if (tree.expr == null) {
- if (!isLambda) {
- log.error(tree.pos(), "missing.ret.val");
- }
- else {
- ((MethodType)m.type).restype = syms.voidType;
- }
- } else {
- attribExpr(tree.expr, env, isLambda ? Type.noType : m.type.getReturnType());
- if (isLambda) {
- if (tree.getExpression().type.tag == VOID) {
- log.error(tree.expr.pos(),
- "cant.ret.void.expr");
- }
- ((MethodType)m.type).restype = m.type.getReturnType() == Type.noType ?
- (tree.expr.type == syms.botType ? syms.objectType : tree.expr.type) :
- unionType(tree.pos(), null, m.type.getReturnType(), tree.expr.type, "incompatibles.ret.types.in.lambda");
- }
+ } else if (tree.expr == null && typeToCheck.tag != NONE) {
+ log.error(tree.pos(), "missing.ret.val");
+ } else if (tree.expr != null) {
+ attribExpr(tree.expr, env, typeToCheck);
}
}
result = null;
@@ -1659,8 +1661,7 @@ public class Attr extends JCTree.Visitor
/** Obtain a method type with given argument types.
*/
Type newMethTemplate(List<Type> argtypes, List<Type> typeargtypes) {
- MethodType mt = new MethodType(argtypes, null, null, syms.methodClass);
- return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt);
+ return new MethodType(typeargtypes != null ? typeargtypes : List.<Type>nil(), argtypes, null, null, syms.methodClass);
}
public void visitNewClass(JCNewClass tree) {
@@ -1763,7 +1764,7 @@ public class Attr extends JCTree.Visitor
if (inferred != null &&
!inferred.isErroneous() &&
inferred.tag == CLASS &&
- types.isAssignable(localEnv, inferred, pt.tag == NONE ? clazztype : pt, Warner.noWarnings)) {
+ types.isAssignable(inferred, pt.tag == NONE ? clazztype : pt, Warner.noWarnings)) {
String key = types.isSameType(clazztype, inferred) ?
"diamond.redundant.args" :
"diamond.redundant.args.1";
@@ -1902,7 +1903,7 @@ public class Attr extends JCTree.Visitor
tree.constructorType.getReturnType().tag == FORALL) {
//we need to 'close' open type-variables in the constructor type
//this can happen if the constructor is passed a lambda expression
- tree.constructorType.asMethodType(types).restype =
+ tree.constructorType.asMethodType().restype =
check(tree, tree.constructorType.getReturnType(), VAL, pkind, syms.voidType);
}
result = check(tree, owntype, VAL, pkind, pt);
@@ -1952,7 +1953,7 @@ Type attribDiamond(Env<AttrContext> env,
}
//dup attribution environment and augment the set of inference variables
- Env<AttrContext> localEnv = env.dup(tree);
+ Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
localEnv.info.tvars = clazztype.tsym.type.getTypeArguments();
//if the type of the instance creation expression is a class type
@@ -1989,9 +1990,7 @@ Type attribDiamond(Env<AttrContext> env,
//type-variables, infer them using the expected type and declared
//bounds (JLS 15.12.2.8).
try {
- clazztype = infer.instantiateExpr(localEnv, (ForAll) clazztype,
- pt.tag == NONE ? syms.objectType : pt,
- Warner.noWarnings);
+ clazztype = ((ForAll) clazztype).complete(pt.tag == NONE ? syms.objectType : pt, boxingEnabled);
} catch (Infer.InferenceException ex) {
//an error occurred while inferring uninstantiated type-variables
log.error(tree.clazz.pos(),
@@ -2095,7 +2094,7 @@ Type attribDiamond(Env<AttrContext> env,
* also be generated as they are required during lowering (in order to find
* free-variables used within a lambda expression).
*/
- Env<AttrContext> lambdaEnvironment(JCLambda tree, final Type targetType) {
+ Env<AttrContext> lambdaEnvironment(Env<AttrContext> env, JCLambda tree, final Type targetType) {
//create synthetic outer class symbol hoisting the lambda
ClassSymbol lambdaClassSym = makeLambdaClass(env.info.scope.owner,
@@ -2131,7 +2130,7 @@ Type attribDiamond(Env<AttrContext> env,
null); // missing defaultValue
lambda.type = lambdaSym.type;
- lambda.sym = lambdaSym;
+ tree.sym = lambda.sym = lambdaSym;
outerEnv.enclClass.defs = List.<JCTree>of(lambda);
Env<AttrContext> newEnv = memberEnter.methodEnv(lambda, outerEnv);
newEnv.info.scope.owner = lambda.sym;
@@ -2163,18 +2162,10 @@ Type attribDiamond(Env<AttrContext> env,
}
//where
private MethodSymbol makeLambdaSymbol(Type targetType, Symbol owner) {
- Name lambdaName = names.lambda;
- long lambdaFlags = SYNTHETIC | LAMBDA;
- Type lambdaType = null;
-
- if (!types.isFunctionType(targetType)) {
- Types.SAMResult samMethod = types.findSAM(targetType, env);
- lambdaName = samMethod.getTargetName();
- lambdaFlags = samMethod.getTargetFlags();
- lambdaType = samMethod.getTargetType();
- } else {
- lambdaType = targetType.asMethodType(types);
- }
+ Types.SAMResult samMethod = types.findSAM(targetType, env);
+ Name lambdaName = samMethod.getTargetName();
+ long lambdaFlags = samMethod.getTargetFlags() | LAMBDA;
+ Type lambdaType = samMethod.getTargetType();
return new MethodSymbol(
lambdaFlags,
@@ -2193,43 +2184,36 @@ Type attribDiamond(Env<AttrContext> env,
* attribution of the lambda expression can proceed normally.
*/
@Override
- public void visitLambda(JCLambda that) {
+ public void visitLambda(final JCLambda that) {
if (!lambdaOrReferenceAllowed(that)) {
//lambda only allowed in assignment or method invocation/cast context
log.error(that.pos(), "unexpected.lambda");
- }
-
- Type typeToCheck = lambdaOrReferenceTargetType(that);
- if (typeToCheck.tag != NONE) {
- Type samType = chk.checkSAM(that, typeToCheck, env);
- if (samType.isErroneous()) {
- result = that.type = samType;
- return;
- }
- }
-
- //if the lambda expression needs parameter inference and/or the target
- //type is unknown (e.g. the lambda position is in argument position)
- //apply an inference step where lambda return type/thrown types are
- //inferred from the body of the lambda; otherwise, just attribute the
- //lambda expression against a given target type.
- if (typeToCheck.tag == NONE ||
- that.needsParameterInference()) {
- inferLambda(that);
- } else {
- attribLambda(that, typeToCheck);
- }
-
- //if the target type is known (e.g. lambda expression is in assignment,
- //return statement, etc.) then we need to check the lambda expression type
- //against the target type --- this will cause inference of uninferred
- //lambda parameter types (if any).
- if (typeToCheck.tag != NONE) {
- chk.checkType(that.pos(), env, that.type, typeToCheck);
- result = typeToCheck;
- } else {
- result = that.type;
- }
+ result = that.type = syms.errType;
+ return;
+ }
+ final ListBuffer<Type> parameterTypes = ListBuffer.lb();
+ final boolean hasExplicitParameters = !that.needsParameterInference();
+ if (hasExplicitParameters) {
+ for (JCVariableDecl param : that.params) {
+ parameterTypes.append(attribType(param.vartype, env));
+ }
+ }
+
+ final ForAll owntype = new ForAll(POLY_LAMBDA, Type.noType) {
+ @Override
+ public List<Type> getParameterTypes() {
+ if (qtype.tag != NONE) return qtype.getParameterTypes();
+ else
+ return hasExplicitParameters ? parameterTypes.toList() : null;
+ }
+ };
+ owntype.completer = new SAMDeferredAttribution<JCLambda>(env, that) {
+ @Override
+ Type deferredAttr(Env<AttrContext> attrEnv, JCLambda treeToCheck, Type pt, boolean allowBoxing) {
+ return attribLambda(attrEnv, treeToCheck, pt, allowBoxing);
+ }
+ };
+ result = check(that, owntype, VAL, pkind, pt);
}
boolean lambdaOrReferenceAllowed(JCTree lambdaOrReference) {
@@ -2263,252 +2247,124 @@ Type attribDiamond(Env<AttrContext> env,
default: return pt;
}
}
-
+
/*
- * Prepare for lambda inference. Replicate the AST and perform a first round
- * of lambda attribution (see below) in which lambda return/thrown types
- * are inferred from the lambda body.
- */
- Type inferLambda(final JCLambda that) {
- ListBuffer<Type> argTypes = ListBuffer.lb();
- ListBuffer<Type> tvars = ListBuffer.lb();
- JCLambda tempLambda = new TreeCopier<Object>(make).copy(that);
-
- //for each empty variable type, create a 'partial' type-variable
- //this type-variable will be eventually inferred from the target-type
- for (JCVariableDecl param : tempLambda.params) {
- if (param.vartype == null) {
- TypeSymbol tvSym = new TypeSymbol(LAMBDA,
- param.name,
- null,
- env.info.scope.owner);
- TypeVar tv = new TypeVar(tvSym, Type.noType, null);
- param.vartype = make.Type(tv);
- tvSym.type = tv;
- tvars.append(tv);
- argTypes.append(tv);
+ * Attribute a lambda expression - return type/thrown types of the lambda
+ * expression are inferred from the lambda body.
+ */
+ Type attribLambda(Env<AttrContext> env, JCLambda that, Type target, boolean allowBoxing) {
+
+ //create an environment for attribution of the lambda expression
+ final Env<AttrContext> localEnv = lambdaEnvironment(env, that, target);
+
+ if (that.needsParameterInference()) {
+ //add param type info in the AST
+ List<Type> actuals = types.findSAM(target, env).getTargetType().getParameterTypes();
+ for (JCVariableDecl param : that.params) {
+ if (param.vartype == null) {
+ param.vartype = make.Type(actuals.head);
+ actuals = actuals.tail;
+ }
+ }
+ }
+
+ //attribute lambda parameters
+ attribStats(that.params, localEnv);
+
+ int prevErrors = log.nerrors;
+
+ LambdaCheckKind prevLambdaCheckKind = lambdaCheckKind;
+ try {
+ lambdaCheckKind = LambdaCheckKind.RESOLUTION;
+
+ if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
+ attribExpr(that.getBody(), localEnv, Infer.anyPoly);
}
else {
- argTypes.append(attribType(param.vartype, env));
- }
- }
-
- TypeSymbol tvSym = new TypeSymbol(LAMBDA,
- names.fromString("R"),
- null,
- env.info.scope.owner);
- TypeVar resType = new TypeVar(tvSym, Type.noType, null);
-
- Type ft;
-
- try {
- ft = attribLambda(tempLambda);
- if (ft.getReturnType() == Type.noType) {
- tvars.prepend(resType);
- ft = new FunctionType(ft.getParameterTypes(),
- resType, ft.getThrownTypes(), ft.tsym);
- }
- } catch(Throwable t) {
- tvars.prepend(resType);
- ft = new FunctionType(argTypes.toList(), resType, List.<Type>nil(), syms.methodClass);
- }
- final boolean needsReturnTypeInferred = ft.getReturnType() == resType;
-
- return that.type = new ForAll(tvars.toList(), ft) {
- @Override
- public Type inst(List<Type> actuals, Type to, Types types, ForAll.InstantiationPhase phase) {
- if (phase == ForAll.InstantiationPhase.CHECK) {
- that.type = types.subst(this, tvars, actuals);
- if (needsReturnTypeInferred) {
- actuals = actuals.tail;
- }
- //now that we have a target type 'to' and a set of instantiated types
- //for each of the unknown lambda parameter types, we can proceed
- //with the second phase of lambda attribution (see below).
- for (JCVariableDecl param : that.params) {
- if (param.vartype == null) {
- param.vartype = make.Type(actuals.head);
- actuals = actuals.tail;
- }
- }
- attribLambda(that, to);
- return that.type;
- } else {
- return super.inst(actuals, to, types, phase);
- }
- }
- };
- }
-
- /*
- * phase 1:
- * Attribute a lambda expression where the target type is unknown;
- * return type/thrown types of the lambda expression are inferred from the
- * lambda body (if possible).
- */
- Type attribLambda(JCLambda that) {
-
- //create an environment for attribution of the lambda expression
- final Env<AttrContext> localEnv = lambdaEnvironment(that,
- new FunctionType(List.<Type>nil(), Type.noType, List.<Type>nil(), syms.methodHandleType.tsym));
-
- Type resType = null;
- ListBuffer<Type> argtypes = ListBuffer.lb();
-
- boolean prevDeferDiags = log.deferDiagnostics;
- try {
- //disable the log -- we need to do this in order to avoid
- //spurious error messages from this partial attribution sweep
- log.deferDiagnostics = true;
- //attribute lambda parameters
- attribStats(that.params, localEnv);
- for (JCTree arg : that.params) {
- argtypes.append(arg.type);
- }
-
- if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
- //the return type is the type of the expression
- resType = attribExpr(that.getBody(), localEnv);
- }
- else {
- //the return type is the union of all types
- //returned by the lambda
JCBlock body = (JCBlock)that.body;
attribStats(body.stats, localEnv);
- resType = localEnv.info.scope.owner.type.getReturnType();
- if (resType == null) {
- //this happens if the body contains an expression statement
- resType = syms.voidType;
- }
}
}
finally {
- log.deferDiagnostics = prevDeferDiags;
- }
-
- //there are two causes that disable inference of lambda return type:
- //(i) either the inferred return type is erroneous (meaning that the
- // body of the lambda contained errors) or (ii) the inferred return type
- //depends on the type of 'this' (which is unkown at this stage).
- if (resType.isErroneous() ||
- resType.contains(localEnv.enclClass.type)) {
- //give up
- resType = Type.noType;
- }
- else {
- //infer return type from lambda body
- resType = resType == syms.botType ?
- syms.objectType :
- resType;
- }
+ lambdaCheckKind = prevLambdaCheckKind;
+ }
+
+ List<Type> returnTypes = attribLambdaReturnExpressions(localEnv, that, allowBoxing);
+
+ List<Type> thrownTypes = List.nil();
+
+ if (prevErrors == log.nerrors) {
+ //infer thrown types from lambda body
+ flow.analyzeLambda(that, env, make);
+ thrownTypes = that.inferredThrownTypes;
+ }
+
+ checkSAMCompatible(target, returnTypes, TreeInfo.types(that.params), thrownTypes, allowBoxing);
- List<Type> thrownTypes = null;
-
- //if one or more 'partial' types were accessed during this first attribution
- //pass, then thrown types are left uninferred (as e.g. calling an unknown
- //method on an unknown type might raise unknown exception types).
- List<JCDiagnostic> deferredErrors = log.getDeferredDiags(JCDiagnostic.Kind.ERROR);
- if (deferredErrors.nonEmpty()) {
- ListBuffer<Name> uninferredTypeNames = ListBuffer.lb();
- for (JCDiagnostic diag : deferredErrors) {
- searchUninferredTypes(diag, uninferredTypeNames);
- }
- if (uninferredTypeNames.nonEmpty() && lambdaInferenceDiags) {
- String warnKey = uninferredTypeNames.size() == 1 ?
- "cyclic.lambda.inference.throws" :
- "cyclic.lambda.inference.throws.1";
- log.warning(that.pos(), warnKey, uninferredTypeNames);
- }
- thrownTypes = Type.noTypes;
- resType = Type.noType;
- }
-
- that.type = new FunctionType(argtypes.toList(),
- resType,
- thrownTypes,
- syms.methodHandleType.tsym);
-
- if (thrownTypes == null) {
- //infer thrown types from lambda body
- flow.analyzeLambda(that, localEnv, make);
- }
- return that.type;
- }
-
- void searchUninferredTypes(JCDiagnostic suppressedDiag, ListBuffer<Name> buf) {
- for (Object o : suppressedDiag.getArgs()) {
- searchUninferredTypesInArg(o, buf);
- }
- }
-
- void searchUninferredTypesInArg(Object o, ListBuffer<Name> buf) {
- if (o instanceof Type) {
- Type t = (Type)o;
- if (t.tsym != null &&
- (t.tsym.flags() & LAMBDA) != 0 &&
- !buf.contains(t.tsym.name)) {
- buf.append(t.tsym.name);
- }
- } else if (o instanceof TypeSymbol) {
- TypeSymbol tsym = (TypeSymbol)o;
- if ((tsym.flags() & LAMBDA) != 0 && !buf.contains(tsym.name)) {
- buf.append(tsym.name);
- }
- } else if (o instanceof JCDiagnostic) {
- searchUninferredTypes((JCDiagnostic)o, buf);
- } else if (o instanceof Iterable<?>) {
- for (Object o2 : (Iterable<?>)o) {
- searchUninferredTypesInArg(o2, buf);
- }
- }
- }
-
- /**
- * phase 2:
- * Attribute a lambda expression with expected SAM type; return type/thrown
- * types of the lambda expression are inferred from the target method of the
- * lambda conversion.
- */
- Type attribLambda(JCLambda that, Type samOrFunctionType) {
-
- //'normalize' the target type (i.e. strip toplevel wildcards, where possible)
- Type superType = types.normalize(samOrFunctionType);
-
- //create an environment for attribution of the lambda expression
- final Env<AttrContext> localEnv = lambdaEnvironment(that, superType);
-
- //attribute lambda parameters
- attribStats(that.params, localEnv);
- ListBuffer<Type> argtypes = ListBuffer.lb();
- for (JCTree arg : that.params) {
- argtypes.append(arg.type);
- }
-
- Type targetType = localEnv.enclMethod.type;
-
- //attribute the lambda body
- if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
- Type exprType = attribExpr(that.getBody(), localEnv);
- Type reqType = targetType.getReturnType();
- if (!(types.isSameType(reqType, types.boxedClass(syms.voidType).type) &&
- exprType.tag == VOID)) {
- //check the expression type against the (possibly inferred) lambda return type
- chk.checkType(that.getBody(), localEnv, exprType, reqType);
- }
- }
- else {
- JCBlock body = (JCBlock)that.body;
- attribStats(body.stats, localEnv);
- }
-
- that.type = new FunctionType(argtypes.toList(),
- targetType.getReturnType(),
- targetType.getThrownTypes(),
- syms.methodHandleType.tsym);
-
- that.targetType = superType;
- that.sym = localEnv.enclMethod.sym;
- return superType;
+ return target;
+ }
+
+ List<Type> attribLambdaReturnExpressions(Env<AttrContext> env, JCLambda lambda, boolean allowBoxing) {
+ switch (lambda.getBodyKind()) {
+ case EXPRESSION:
+ Type t = lambda.getBody().type;
+ Type expected = env.enclMethod.type.getReturnType();
+ if (t.tag == FORALL && lambdaCheckKind == LambdaCheckKind.CHECK) {
+ //instantiate ForAll against expected target
+ t = lambda.getBody().type = ((ForAll)t).complete(expected, allowBoxing);
+ }
+ return List.of(t);
+ case STATEMENT:
+ JCBlock block = (JCBlock)lambda.getBody();
+ if (block.stats.isEmpty())
+ return List.<Type>of(syms.voidType);
+ else {
+ LambdaReturnExprVisitor returnExprScanner =
+ new LambdaReturnExprVisitor(env, allowBoxing);
+ returnExprScanner.scan(lambda.getBody());
+ return returnExprScanner.returnTypes;
+ }
+ default: Assert.error(); return null;
+ }
+ }
+
+ class LambdaReturnExprVisitor extends TreeScanner {
+
+ boolean allowBoxing;
+ List<Type> returnTypes = List.nil();
+ Env<AttrContext> lambdaEnv;
+
+ public LambdaReturnExprVisitor(Env<AttrContext> lambdaEnv, boolean allowBoxing) {
+ this.lambdaEnv = lambdaEnv;
+ this.allowBoxing = allowBoxing;
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ //do nothing
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //do nothing
+ }
+
+ @Override
+ public void visitReturn(JCReturn tree) {
+ if (tree.getExpression() != null &&
+ tree.getExpression().type == syms.voidType) {
+ log.error(tree.getExpression().pos(), "cant.ret.void.expr");
+ returnTypes = returnTypes.prepend(syms.errType);
+ } else {
+ Type t = tree.expr == null ? syms.voidType : tree.expr.type;
+ Type expected = lambdaEnv.enclMethod.type.getReturnType();
+ if (t.tag == FORALL && lambdaCheckKind == LambdaCheckKind.CHECK) {
+ //instantiate ForAll against expected target
+ t = tree.expr.type = ((ForAll)t).complete(expected, allowBoxing);
+ }
+ returnTypes = returnTypes.prepend(t);
+ }
+ }
}
public void visitParens(JCParens tree) {
@@ -2633,7 +2489,7 @@ Type attribDiamond(Env<AttrContext> env,
// Check that argument types of a reference ==, != are
// castable to each other, (JLS???).
if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
- if (!types.isCastable(env, left, right, new Warner(tree.pos()))) {
+ if (!types.isCastable(left, right, new Warner(tree.pos()))) {
log.error(tree.pos(), "incomparable.types", left, right);
}
}
@@ -2649,7 +2505,9 @@ Type attribDiamond(Env<AttrContext> env,
//a fresh environment is required for 292 inference to work properly ---
//see Infer.instantiatePolymorphicSignatureInstance()
Env<AttrContext> localEnv = env.dup(tree);
- Type exprtype = attribExpr(tree.expr, localEnv, Infer.anyPoly);
+ boolean isLambdaOrReference = tree.expr.getTag() == JCTree.LAMBDA ||
+ tree.expr.getTag() == JCTree.REFERENCE; //this will eventually use polyType
+ Type exprtype = attribExpr(tree.expr, localEnv, isLambdaOrReference ? clazztype : Type.noType);
Type owntype = chk.checkCastable(tree.expr.pos(), env, exprtype, clazztype);
if (exprtype.constValue() != null)
owntype = cfolder.coerce(exprtype, owntype);
@@ -2683,7 +2541,7 @@ Type attribDiamond(Env<AttrContext> env,
boolean varArgs = false;
// Find symbol
- if (pt.tag == METHOD || pt.tag == FORALL) {
+ if (pt.tag == METHOD) {
// If we are looking for a method, the prototype `pt' will be a
// method type with the type of the call's arguments as parameters.
env.info.varArgs = false;
@@ -2765,75 +2623,180 @@ Type attribDiamond(Env<AttrContext> env,
result = checkId(tree, env1.enclClass.sym.type, sym, env, pkind, pt, varArgs);
}
- public void visitReference(JCMemberReference tree) {
- if (!lambdaOrReferenceAllowed(tree)) {
- //method references only allowed in assignment or method invocation context
- log.error(tree.pos(), "unexpected.meth.reference");
- }
- Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
- JCExpression expr = tree.expr;
- Symbol sym = null;
- Type owntype = null;
- switch (tree.mode) {
- case NEW:
- case INVOKE:
- JCMethodInvocation apply = (JCMethodInvocation) expr;
- Type mtype = attribExpr(apply, localEnv);
- apply.type = mtype;
- JCTree base = TreeInfo.getSelector(apply);
- if (TreeInfo.isStaticSelector(base, names)) {
- chk.validate(base, localEnv);
- }
- sym = TreeInfo.symbol(apply.meth);
- owntype = apply.meth.type.isErroneous() ?
- apply.meth.type :
- makeMethodReferenceType(apply);
- if (owntype.getReturnType().tag == FORALL) {
- throw new AssertionError("references to generic methods are not supported yet");
- }
- if (owntype.getReturnType().tag == FORALL) {
- //experimental - turned off for now
- final ForAll rs = (ForAll)owntype.getReturnType();
- owntype = new ForAll(rs.tvars, new FunctionType(owntype.getParameterTypes(),
- rs.qtype,
- owntype.getThrownTypes(), syms.methodHandleType.tsym)) {
- @Override
- public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
- return rs.getConstraints(tv, ck);
- }
- @Override
- public Type inst(List<Type> actuals, Type to, Types types, ForAll.InstantiationPhase phase) {
- rs.inst(actuals, to, types, phase);
- return super.inst(actuals, to, types, phase);
- }
- };
- }
- break;
- default: throw new AssertionError();
- }
- // the symbol is resolved
- assert sym != null;
- tree.sym = sym;
- // FIXME: Instantiate MH<R(A...)> with type parameters from sym.
- result = check(tree, owntype, VAL, pkind, lambdaOrReferenceTargetType(tree));
- }
+ @Override
+ public void visitReference(final JCMemberReference that) {
+ if (!lambdaOrReferenceAllowed(that)) {
+ //method reference only allowed in assignment or method invocation/cast context
+ log.error(that.pos(), "unexpected.meth.reference");
+ result = that.type = syms.errType;
+ return;
+ }
+
+ final ListBuffer<Type> parameterTypes = ListBuffer.lb();
+
+ Assert.check(that.mode == JCMemberReference.ReferenceMode.INVOKE ||
+ that.mode == JCMemberReference.ReferenceMode.NEW);
+
+ JCMethodInvocation apply = (JCMethodInvocation) that.expr;
+ final boolean hasExplicitParameters = apply.args != null;
+ if (hasExplicitParameters) {
+ final Env<AttrContext> localEnv = env.dup(that);
+ boolean prevDeferDiagnostics = log.deferDiagnostics;
+ try {
+ log.deferDiagnostics = true;
+ Type ftype = attribMethodReference(localEnv, that, Type.noType, true);
+ parameterTypes.appendList(ftype.getParameterTypes());
+ } finally {
+ log.deferDiagnostics = prevDeferDiagnostics;
+ }
+ }
+
+ final ForAll owntype = new ForAll(POLY_REFERENCE, Type.noType) {
+ @Override
+ public List<Type> getParameterTypes() {
+ if (qtype.tag != NONE) return qtype.getParameterTypes();
+ else
+ return hasExplicitParameters ? parameterTypes.toList() : null;
+ }
+ };
+ owntype.completer = new SAMDeferredAttribution<JCMemberReference>(env, that) {
+ @Override
+ Type deferredAttr(Env<AttrContext> attrEnv, JCMemberReference treeToCheck, Type pt, boolean allowBoxing) {
+ return attribMethodReference(attrEnv, treeToCheck, pt, allowBoxing);
+ }
+ };
+ result = check(that, owntype, VAL, pkind, pt);
+ }
+
//where
- private Type makeMethodReferenceType(JCMethodInvocation tree) {
- JCTree base = TreeInfo.getSelector(tree);
- Symbol msym = TreeInfo.symbol(tree.meth);
- Type mtype = tree.meth.type;
+ private Type attribMethodReference(Env<AttrContext> localEnv, final JCMemberReference tree, Type to, boolean allowBoxing) {
+ Assert.check(tree.mode == JCMemberReference.ReferenceMode.INVOKE ||
+ tree.mode == JCMemberReference.ReferenceMode.NEW);
+
+ JCMethodInvocation apply = (JCMethodInvocation) tree.expr;
+ apply.type = attribExpr(apply, localEnv);
+ JCTree base = TreeInfo.getSelector(apply);
+ if (TreeInfo.isStaticSelector(base, names)) {
+ chk.validate(base, localEnv);
+ }
+ tree.sym = TreeInfo.symbol(apply.meth);
+ Type mtype = apply.meth.type;
+
+ if (apply.meth.type.isErroneous()) return apply.meth.type;
+
List<Type> args = mtype.getParameterTypes();
- if (!msym.isStatic() &&
- !msym.isConstructor() &&
+ if (!tree.sym.isStatic() &&
+ !tree.sym.isConstructor() &&
TreeInfo.isStaticSelector(base, names)) {
args = args.prepend(base.type);
}
- return new FunctionType(args,
- msym.isConstructor() ?
- base.type :
- mtype.getReturnType(),
- mtype.getThrownTypes(),
- syms.methodHandleType.tsym);
+
+ Type resType = tree.sym.isConstructor() ? base.type : mtype.getReturnType();
+
+ if (to.tag != NONE) {
+ //check mtype against sam descriptor
+ checkSAMCompatible(to, List.of(resType), args, mtype.getThrownTypes(), allowBoxing);
+ return to;
+ } else { //hack to support current inference strategy for method references
+ final List<Type> parameterTypes = args;
+ return new Type(NONE, syms.noSymbol) {
+ @Override
+ public List<Type> getParameterTypes() {
+ return parameterTypes;
+ }
+ };
+ }
+ }
+
+ /**
+ * SAM compatibility. Check that given return types, thrown types, parameter types
+ * are compatible with the expected SAM descriptor. This means that (i) parameter
+ * types must be identical to those of the target SAM descriptor; (ii) return
+ * types must be compatible with the return type of the expected SAM descriptor;
+ * thrown types must be 'included' in the thown types list of the expected
+ * SAM descriptor.
+ */
+ void checkSAMCompatible(Type sam, List<Type> resultTypes, List<Type> argtypes, List<Type> thrownTypes, boolean allowBoxing) {
+ Types.SAMResult samRes = types.findSAM(sam, env);
+ Type samDescriptor = samRes.getTargetType();
+
+ for (Type resType : resultTypes) {
+ if (!isReturnCompatible(env, resType, samDescriptor.getReturnType(), allowBoxing)) {
+ throw new Infer.InvalidInstanceException(diags).setMessage("infer.incompatible.ret.types.in.lambda", resType);
+ }
+ }
+
+ if (!types.isSameTypes(samDescriptor.getParameterTypes(), argtypes)) {
+ throw new Infer.InvalidInstanceException(diags).setMessage("infer.incompatible.arg.types.in.lambda");
+ }
+
+ if (thrownTypes != Type.noTypes &&
+ chk.unhandled(thrownTypes, samDescriptor.getThrownTypes()).nonEmpty()) {
+ throw new Infer.InvalidInstanceException(diags).setMessage("infer.incompatible.thrown.types.in.lambda", thrownTypes);
+ }
+ }
+
+ /**
+ * A return type t is compatible with an expected return type s if either
+ * (i) t indicates that the lambda body could not return normally,
+ * (ii) t is 'void' and s is void-compatible (see below), (iii) s is 'void'
+ * and t is void-compatible (see below) or (iv) it is possible to
+ * convert t to s via subtyping or assignment conversion.
+ */
+ public boolean isReturnCompatible(Env<AttrContext> env, Type t, Type s, boolean allowBoxing) {
+ t = infer.asUndetType(t);
+ return t.tag == NONE || //can't complete normally
+ t.tag == VOID && isVoidCompatible(s) ||
+ s.tag == VOID && isVoidCompatible(t) ||
+ (allowBoxing ? types.isConvertible(t, s) : types.isSubtypeUnchecked(t, s));
+ }
+
+ /**
+ * A return type in a lambda expression is said to be void-compatible
+ * if it's either 'void' or 'java.lang.Void'
+ */
+ public boolean isVoidCompatible(Type t) {
+ return t.tag == VOID ||
+ types.isSameType(t, types.boxedClass(syms.voidType).type);
+ }
+
+ abstract class SAMDeferredAttribution<T extends JCTree> implements ForAll.Completer {
+
+ Env<AttrContext> baseEnv;
+ T tree;
+
+ public SAMDeferredAttribution(Env<AttrContext> baseEnv, T tree) {
+ this.baseEnv = baseEnv;
+ this.tree = tree;
+ }
+
+ public Type complete(ForAll fa, final Type to, boolean allowBoxing) {
+ Type targetType = null;
+ try {
+ targetType = infer.inferSAM(env, to, fa.getParameterTypes());
+ }
+ catch (Infer.InferenceException ex) {
+ throw new Infer.InferenceException(diags).setMessage("no.suitable.sam.inst", to);
+ }
+ T treeToCheck = lambdaCheckKind == LambdaCheckKind.CHECK ?
+ tree :
+ new TreeCopier<Object>(make).copy(tree);
+ boolean prevDeferDiagnostics = log.deferDiagnostics;
+ try {
+ log.deferDiagnostics = lambdaCheckKind == LambdaCheckKind.RESOLUTION;
+ Type owntype = deferredAttr(baseEnv.dup(tree), treeToCheck, targetType, allowBoxing);
+ if (lambdaCheckKind == LambdaCheckKind.CHECK) {
+ fa.qtype = owntype;
+ fa.completer = null;
+ }
+ return owntype;
+ }
+ finally {
+ log.deferDiagnostics = prevDeferDiagnostics;
+ }
+ }
+
+ abstract Type deferredAttr(Env<AttrContext> attrEnv, T t, Type pt, boolean allowBoxing);
}
public void visitSelect(JCFieldAccess tree) {
@@ -2850,7 +2813,7 @@ Type attribDiamond(Env<AttrContext> env,
}
// Attribute the qualifier expression, and determine its symbol (if any).
- Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);
+ Type site = attribTree(tree.selected, env, skind, Type.noType);
if ((pkind & (PCK | TYP)) == 0)
site = capture(site); // Capture field access
@@ -2875,15 +2838,6 @@ Type attribDiamond(Env<AttrContext> env,
sitesym != null &&
sitesym.name == names._super;
- // If selected expression is polymorphic, strip
- // type parameters and remember in env.info.tvars, so that
- // they can be added later (in Attr.checkId and Infer.instantiateMethod).
- if (tree.selected.type.tag == FORALL) {
- ForAll pstype = (ForAll)tree.selected.type;
- env.info.tvars = pstype.tvars;
- site = tree.selected.type = pstype.qtype;
- }
-
// Determine the symbol represented by the selection.
env.info.varArgs = false;
Symbol sym = selectSym(tree, sitesym, site, env, pt, pkind);
@@ -2968,7 +2922,6 @@ Type attribDiamond(Env<AttrContext> env,
env.info.selectSuper = selectSuperPrev;
result = checkId(tree, site, sym, env, pkind, pt, varArgs);
- env.info.tvars = List.nil();
}
//where
/** Determine symbol referenced by a Select expression,
@@ -3001,7 +2954,7 @@ Type attribDiamond(Env<AttrContext> env,
pos, location, site, name, true);
case ARRAY:
case CLASS:
- if (pt.tag == METHOD || pt.tag == FORALL) {
+ if (pt.tag == METHOD) {
return rs.resolveQualifiedMethod(
pos, env, location, site, name, pt.getParameterTypes(), pt.getTypeArguments());
} else if (name == names._this || name == names._super) {
@@ -3170,16 +3123,6 @@ Type attribDiamond(Env<AttrContext> env,
? types.memberType(site, sym)
: sym.type;
- if (env.info.tvars.nonEmpty()) {
- Type owntype1 = new ForAll(env.info.tvars, owntype);
- for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail)
- if (!owntype.contains(l.head)) {
- log.error(tree.pos(), "undetermined.type", owntype1);
- owntype1 = types.createErrorType(owntype1);
- }
- owntype = owntype1;
- }
-
// If the variable is a constant, record constant value in
// computed type.
if (v.getConstValue() != null && isStaticReference(tree))
@@ -3364,6 +3307,7 @@ Type attribDiamond(Env<AttrContext> env,
typeargtypes,
true,
useVarargs,
+ true,
noteWarner);
boolean warned = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED);
@@ -3416,7 +3360,7 @@ Type attribDiamond(Env<AttrContext> env,
}
}
- if (warned && sym.type.tag == FORALL) {
+ if (warned && sym.type.isParameterized()) {
chk.warnUnchecked(env.tree.pos(),
"unchecked.meth.invocation.applied",
kindName(sym),
@@ -3453,7 +3397,7 @@ Type attribDiamond(Env<AttrContext> env,
}
private void assertConvertible(Env<AttrContext> env, JCTree tree, Type actual, Type formal, Warner warn) {
- if (types.isConvertible(env, actual, formal, warn))
+ if (types.isConvertible(actual, formal, warn))
return;
if (formal.isCompound()
@@ -3577,15 +3521,6 @@ Type attribDiamond(Env<AttrContext> env,
tree.type = result = owntype;
}
- @Override
- public void visitFunctionType(JCFunctionType tree) {
- //TODO: add proper checking
- Type resType = attribType(tree.resultType, env);
- List<Type> argtypes = attribAnyTypes(tree.argumentTypes, env);
- List<Type> thrown = attribTypes(tree.thrown, env);
- result = tree.type = new FunctionType(argtypes, resType, thrown, syms.methodHandleType.tsym);
- }
-
public void visitTypeParameter(JCTypeParameter tree) {
TypeVar a = (TypeVar)tree.type;
Set<Type> boundSet = new HashSet<Type>();
@@ -4038,9 +3973,6 @@ Type attribDiamond(Env<AttrContext> env,
@Override
public void visitLambda(JCLambda that) {
super.visitLambda(that);
- if (that.targetType == null) {
- that.targetType = syms.unknownType;
- }
if (that.sym == null) {
that.sym = new MethodSymbol(0, names.lambda, syms.unknownType, syms.noSymbol);
}
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri May 20 17:19:01 2011 +0100
@@ -429,18 +429,12 @@ public class Check {
Type checkType(DiagnosticPosition pos, Env<AttrContext> env, Type found, Type req, String errKey) {
if (req.tag == ERROR)
return req;
- if (found.tag == FORALL)
+ if (found.getPolyTag() != NO_POLY)
return instantiatePoly(pos, env, (ForAll)found, req, convertWarner(pos, found, req));
if (req.tag == NONE)
return found;
- JCDiagnostic details = null;
- try {
- types.rawIsAssignable(env, found, req, convertWarner(pos, found, req));
+ if (types.isAssignable(found, req, convertWarner(pos, found, req)))
return found;
- }
- catch (Types.ConversionException ex) {
- details = ex.getDiagnostic(diags);
- }
if (found.tag <= DOUBLE && req.tag <= DOUBLE)
return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req);
if (found.isSuperBound()) {
@@ -451,19 +445,7 @@ public class Check {
log.error(pos, "assignment.to.extends-bound", req);
return types.createErrorType(found);
}
- JCDiagnostic subDiag = details != null ?
- diags.fragment(errKey + ".1", details) :
- diags.fragment(errKey);
- return typeError(pos, subDiag, found, req);
- }
-
- boolean checkArgument(Env<AttrContext> env, Type actual, Type formal, boolean allowBoxing, Warner warn) {
- if (allowBoxing) {
- types.rawIsConvertible(env, actual, formal, warn);
- return true;
- } else {
- return types.isSubtypeUnchecked(actual, formal, warn);
- }
+ return typeError(pos, diags.fragment(errKey), found, req);
}
/** Instantiate polymorphic type to some prototype, unless
@@ -471,38 +453,57 @@ public class Check {
* is returned unchanged.
*/
Type instantiatePoly(DiagnosticPosition pos, Env<AttrContext> env, ForAll t, Type pt, Warner warn) throws Infer.NoInstanceException {
- if (pt == Infer.anyPoly && complexInference) {
+ if (pt == Infer.anyPoly) {
return t;
- } else if (pt == Infer.anyPoly || pt.tag == NONE) {
- //if type is primitive or function type, the expected type is untouched;
+ }
+ else if (pt == Infer.lambdaPoly &&
+ (t.getPolyTag() == POLY_LAMBDA ||
+ t.getPolyTag() == POLY_REFERENCE)) {
+ return t;
+ } else if (pt.tag == NONE) {
+ //if type is primitive, the expected type is untouched;
//otherwise changed to java.lang.Object
- Type newpt = t.qtype.tag <= VOID ||
- types.isFunctionType(t) ?
+ Type newpt = t.qtype.tag <= VOID ?
t.qtype :
syms.objectType;
return instantiatePoly(pos, env, t, newpt, warn);
} else if (pt.tag == ERROR) {
return pt;
} else {
- try {
- return infer.instantiateExpr(env, t, pt, warn, ForAll.InstantiationPhase.CHECK);
- } catch (Infer.NoInstanceException ex) {
- if (ex.isAmbiguous) {
- JCDiagnostic d = ex.getDiagnostic();
- log.error(pos,
- "undetermined.type" + (d!=null ? ".1" : ""),
- t, d);
- return types.createErrorType(pt);
- } else {
- JCDiagnostic d = ex.getDiagnostic();
- return typeError(pos,
- diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
- t, pt);
- }
- } catch (Infer.InvalidInstanceException ex) {
- JCDiagnostic d = ex.getDiagnostic();
- log.error(pos, "invalid.inferred.types", d);
- return types.createErrorType(pt);
+ switch (t.getPolyTag()) {
+ case POLY_REFERENCE:
+ case POLY_LAMBDA:
+ Types.SAMResult samRes = types.findSAM(pt, env);
+ if (samRes.isErroneous()) {
+ return typeError(pos,
+ diags.fragment("incompatible.types.1", samRes.getDiagnostic(diags)),
+ t, pt);
+ }
+ try {
+ t.complete(pt, true);
+ return t;
+ }
+ catch (Infer.InferenceException ex) {
+ return typeError(pos,
+ diags.fragment("incompatible.types.1", ex.diagnostic),
+ t, pt);
+ }
+ case POLY_RETURN:
+ try {
+ Type typeToCheck = t.complete(pt, true);
+ return checkType(warn.pos(), env, typeToCheck, pt);
+ } catch (Infer.NoInstanceException ex) {
+ JCDiagnostic d = ex.getDiagnostic();
+ return typeError(pos,
+ diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
+ t.qtype, pt);
+ } catch (Infer.InvalidInstanceException ex) {
+ JCDiagnostic d = ex.getDiagnostic();
+ log.error(pos, "invalid.inferred.types", d);
+ return types.createErrorType(pt);
+ }
+
+ default: Assert.error("unexpected poly type" + t.getPolyTag()); return null;
}
}
}
@@ -517,7 +518,7 @@ public class Check {
if (found.tag == FORALL) {
instantiatePoly(pos, env, (ForAll) found, req, castWarner(pos, found, req));
return req;
- } else if (types.isCastable(env, found, req, castWarner(pos, found, req))) {
+ } else if (types.isCastable(found, req, castWarner(pos, found, req))) {
return req;
} else {
return typeError(pos,
@@ -801,8 +802,7 @@ public class Check {
}
Type checkSAM(DiagnosticPosition pos, Type t, Env<AttrContext> env) {
- if (t.tag == CLASS &&
- types.findSAM(t, env).isErroneous()) {
+ if (types.findSAM(t, env).isErroneous()) {
//if the target type is neither a SAM type nor a function type, reports an error
Types.SAMResult res = types.findSAM(t, env);
String key = "invalid.target.type.for.lambda.conv";
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri May 20 17:19:01 2011 +0100
@@ -365,7 +365,8 @@ public class Flow extends TreeScanner {
* I.e. is symbol either a local or a blank final variable?
*/
boolean trackable(VarSymbol sym) {
- return (sym.owner.kind == MTH ||
+ return !daEnabled ? false :
+ (sym.owner.kind == MTH ||
((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL &&
classDef.sym.isEnclosedBy((ClassSymbol)sym.owner)));
}
@@ -613,7 +614,7 @@ public class Flow extends TreeScanner {
/* ------------ Visitor methods for various sorts of trees -------------*/
public void visitClassDef(JCClassDecl tree) {
- if (tree.sym == null) return;
+ if (!daEnabled || tree.sym == null) return;
JCClassDecl classDefPrev = classDef;
List<Type> thrownPrev = thrown;
@@ -1336,20 +1337,55 @@ public class Flow extends TreeScanner {
scanExprs(tree.dims);
scanExprs(tree.elems);
}
-
+
+ /**
+ * It could make sense to create two separate visitors, one for DA/DU and
+ * one for exception checking, as suggested in BGGA - this would make it
+ * easier to check thrown types of a lambda
+ */
public void analyzeLambda(JCLambda tree, Env<AttrContext> env, TreeMaker make) {
+ JCClassDecl prevClassDef = classDef;
+ Bits prevInits = inits;
+ Bits prevUninits = uninits;
boolean prevDaEnabled = daEnabled;
+ boolean prevAlive = alive;
+ List<Type> prevThrown = thrown;
+ List<Type> prevCaught = caught;
+ ListBuffer<PendingExit> prevPending = pendingExits;
+ HashMap<Symbol, List<Type>> prevPreciseRethrowTypes = preciseRethrowTypes;
+ Scope prevUnrefdResources = unrefdResources;
try {
+ classDef = env.enclClass;
+ inits = Bits.emptyBits;
+ uninits = Bits.emptyBits;
daEnabled = false;
- analyzeTree(tree, env, make);
+ alive = true;
+ caught = List.of(syms.throwableType); //inhibit exception checking
+ thrown = List.nil();
+ pendingExits = new ListBuffer<PendingExit>();
+ preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
+ unrefdResources = new Scope(classDef.sym);
+ scanStat(tree.body);
+ tree.canCompleteNormally = alive;
+ tree.inferredThrownTypes = thrown;
}
finally {
+ classDef = prevClassDef;
+ inits = prevInits;
+ uninits = prevUninits;
daEnabled = prevDaEnabled;
+ alive = prevAlive;
+ thrown = prevThrown;
+ caught = prevCaught;
+ pendingExits = prevPending;
+ preciseRethrowTypes = prevPreciseRethrowTypes;
+ unrefdResources = prevUnrefdResources;
}
}
@Override
public void visitLambda(JCLambda tree) {
+ if (!daEnabled) return;
List<Type> prevCaught = caught;
List<Type> prevThrown = thrown;
Bits prevUninits = uninits;
@@ -1371,25 +1407,6 @@ public class Flow extends TreeScanner {
}
alive = true;
scanStat(tree.body);
-
- if (alive && types.isSameType(tree.type.getReturnType(), types.boxedClass(syms.voidType).type)) {
- //there's no return statement and the lambda (possibly inferred)
- //return type is java.lang.Void; sets the NEEDS_RETURN flag in
- //order to tell code generation to emit a synthetic return statement
- tree.sym.flags_field |= NEEDS_RETURN;
- alive = false;
- }
-
- if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && alive &&
- tree.type.getReturnType().tag != VOID &&
- tree.type.getReturnType().tag != NONE) {
- log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
- }
- if (tree.type.getThrownTypes() == null) {
- ((FunctionType)tree.type).thrown = thrown;
- if (alive && tree.type.getReturnType() == Type.noType)
- ((FunctionType)tree.type).restype = syms.voidType;
- }
}
finally {
caught = prevCaught;
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri May 20 17:19:01 2011 +0100
@@ -32,10 +32,8 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.JCDiagnostic;
-import java.util.EnumSet;
import static com.sun.tools.javac.code.TypeTags.*;
@@ -51,7 +49,9 @@ public class Infer {
new Context.Key<Infer>();
/** A value for prototypes that admit any type, including polymorphic ones. */
+
public static final Type anyPoly = new Type(NONE, null);
+ public static final Type lambdaPoly = new Type(NONE, null);
Symtab syms;
Types types;
@@ -134,6 +134,76 @@ public class Infer {
*/
Mapping getInstFun = new Mapping("getInstFun") {
+ public Type apply(Type t) {
+ switch (t.tag) {
+ case UNKNOWN:
+ throw ambiguousNoInstanceException
+ .setMessage("undetermined.type");
+ case UNDETVAR:
+ UndetVar that = (UndetVar) t;
+ if (that.inst == null)
+ throw ambiguousNoInstanceException
+ .setMessage("type.variable.has.undetermined.type",
+ that.qtype);
+ return isConstraintCyclic(that) ?
+ that.qtype :
+ apply(that.inst);
+ default:
+ return t.map(this);
+ }
+ }
+
+ private boolean isConstraintCyclic(UndetVar uv) {
+ Types.UnaryVisitor<Boolean> constraintScanner =
+ new Types.UnaryVisitor<Boolean>() {
+
+ List<Type> seen = List.nil();
+
+ Boolean visit(List<Type> ts) {
+ for (Type t : ts) {
+ if (visit(t)) return true;
+ }
+ return false;
+ }
+
+ public Boolean visitType(Type t, Void ignored) {
+ return false;
+ }
+
+ @Override
+ public Boolean visitClassType(ClassType t, Void ignored) {
+ if (t.isCompound()) {
+ return visit(types.supertype(t)) ||
+ visit(types.interfaces(t));
+ } else {
+ return visit(t.getTypeArguments());
+ }
+ }
+ @Override
+ public Boolean visitWildcardType(WildcardType t, Void ignored) {
+ return visit(t.type);
+ }
+
+ @Override
+ public Boolean visitUndetVar(UndetVar t, Void ignored) {
+ if (seen.contains(t)) {
+ return true;
+ } else {
+ seen = seen.prepend(t);
+ return visit(t.inst);
+ }
+ }
+ };
+ return constraintScanner.visit(uv);
+ }
+ };
+
+ /** A mapping that returns its type argument with every UndetVar replaced
+ * by its `inst' field. If 'inst' is 'null', the mapping returns the
+ * type-variable 'hidden' behind the UndetVar (what about loops?)
+ */
+
+ Mapping partialInstFun = new Mapping("partialInstFun") {
public Type apply(Type t) {
switch (t.tag) {
case UNKNOWN:
@@ -141,62 +211,13 @@ public class Infer {
.setMessage("undetermined.type");
case UNDETVAR:
UndetVar that = (UndetVar) t;
- if (that.inst == null)
- throw ambiguousNoInstanceException
- .setMessage("type.variable.has.undetermined.type",
- that.qtype);
- return isConstraintCyclic(that) ?
- that.qtype :
- apply(that.inst);
- default:
- return t.map(this);
- }
- }
-
- private boolean isConstraintCyclic(UndetVar uv) {
- Types.UnaryVisitor<Boolean> constraintScanner =
- new Types.UnaryVisitor<Boolean>() {
-
- List<Type> seen = List.nil();
-
- Boolean visit(List<Type> ts) {
- for (Type t : ts) {
- if (visit(t)) return true;
- }
- return false;
- }
-
- public Boolean visitType(Type t, Void ignored) {
- return false;
- }
-
- @Override
- public Boolean visitClassType(ClassType t, Void ignored) {
- if (t.isCompound()) {
- return visit(types.supertype(t)) ||
- visit(types.interfaces(t));
- } else {
- return visit(t.getTypeArguments());
- }
- }
- @Override
- public Boolean visitWildcardType(WildcardType t, Void ignored) {
- return visit(t.type);
- }
-
- @Override
- public Boolean visitUndetVar(UndetVar t, Void ignored) {
- if (seen.contains(t)) {
- return true;
- } else {
- seen = seen.prepend(t);
- return visit(t.inst);
- }
- }
- };
- return constraintScanner.visit(uv);
- }
- };
+ return (that.inst == null || that.inst.tag == BOT)
+ ? that.qtype : that.inst.map(this);
+ default:
+ return t.map(this);
+ }
+ }
+ };
/***************************************************************************
* Mini/Maximization of UndetVars
@@ -289,437 +310,6 @@ public class Infer {
}
}
-/***************************************************************************
- * Exported Methods
- ***************************************************************************/
-
- /** Try to instantiate expression type `that' to given type `to'.
- * If a maximal instantiation exists which makes this type
- * a subtype of type `to', return the instantiated type.
- * If no instantiation exists, or if several incomparable
- * best instantiations exist throw a NoInstanceException.
- */
- public Type instantiateExpr(Env<AttrContext> env, ForAll that,
- Type to,
- Warner warn) throws InferenceException {
- return instantiateExpr(env, that, to, warn, ForAll.InstantiationPhase.CHECK);
- }
- public Type instantiateExpr(Env<AttrContext> env, ForAll that,
- Type to,
- Warner warn, ForAll.InstantiationPhase phase) throws InferenceException {
- List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
- for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
- UndetVar uv = (UndetVar) l.head;
- TypeVar tv = (TypeVar)uv.qtype;
- ListBuffer<Type> hibounds = new ListBuffer<Type>();
- for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS)) {
- hibounds.append(types.subst(t, that.tvars, undetvars));
- }
- List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL);
- if (inst.nonEmpty() && inst.head.tag != BOT) {
- uv.inst = types.subst(inst.head, that.tvars, undetvars);
- }
- uv.hibounds = hibounds.toList();
- }
- Type to2 = to.isPrimitive() && !that.qtype.isPrimitive() ?
- types.boxedClass(to).type :
- to; //this is a hack
- Type qtype1 = types.subst(that.qtype, that.tvars, undetvars);
- boolean works = false;
- if (types.isFunctionType(qtype1) && to2.tag == CLASS) {
- //we need conversion - not subtyping (function type needs SAM conversion)
- works = types.isConvertible(env, qtype1, to2, warn);
- //inference of function types should take into account lower bounds
- //(because of contravarance of function type argument types)
- for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
- UndetVar uv = (UndetVar) l.head;
- minimizeInst(uv, warn);
- if (uv.inst.tag == BOT) {
- uv.inst = null;
- }
- }
- } else {
- works = types.isSubtype(qtype1,
- qtype1.tag == UNDETVAR ? types.boxedTypeOrType(to2) : to2);
- }
- if (!works) {
- throw unambiguousNoInstanceException
- .setMessage("infer.no.conforming.instance.exists",
- that.tvars, that.qtype, to);
- }
- for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail)
- maximizeInst((UndetVar) l.head, warn);
- // System.out.println(" = " + qtype1.map(getInstFun));//DEBUG
-
- // check bounds
- List<Type> targs = Type.map(undetvars, getInstFun);
- if (Type.containsAny(targs, that.tvars)) {
- //replace uninferred type-vars
- targs = types.subst(targs,
- that.tvars,
- instaniateAsUninferredVars(undetvars, that.tvars));
- }
- return chk.checkType(warn.pos(), env, that.inst(targs, to, types, phase), to);
- }
- //where
- private List<Type> instaniateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
- ListBuffer<Type> new_targs = ListBuffer.lb();
- //step 1 - create syntethic captured vars
- for (Type t : undetvars) {
- UndetVar uv = (UndetVar)t;
- Type newArg = new CapturedType(t.tsym.name, t.tsym, uv.inst, syms.botType, null);
- new_targs = new_targs.append(newArg);
- }
- //step 2 - replace synthetic vars in their bounds
- for (Type t : new_targs.toList()) {
- CapturedType ct = (CapturedType)t;
- ct.bound = types.subst(ct.bound, tvars, new_targs.toList());
- WildcardType wt = new WildcardType(ct.bound, BoundKind.EXTENDS, syms.boundClass);
- ct.wildcard = wt;
- }
- return new_targs.toList();
- }
-
- /** Instantiate method type `mt' by finding instantiations of
- * `tvars' so that method can be applied to `argtypes'.
- */
- public Type instantiateMethod(final Env<AttrContext> env,
- List<Type> tvars,
- MethodType mt,
- final Symbol msym,
- final List<Type> argtypes,
- final boolean allowBoxing,
- final boolean useVarargs,
- final Warner warn) throws InferenceException {
- //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
- final ListBuffer<Type> argUndetvars = ListBuffer.lb();
- List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
- List<Type> formals = mt.argtypes;
- boolean forcePostCheck = false;
- //need to capture exactly once - otherwise subsequent
- //applicability checks might fail
- final ListBuffer<Type> capturedArgs = ListBuffer.lb();
- List<Type> actuals = argtypes;
- List<Type> actualsNoCapture = argtypes;
- // instantiate all polymorphic argument types and
- // set up lower bounds constraints for undetvars
- Type varargsFormal = useVarargs ? formals.last() : null;
- if (argtypes != Type.noTypes) {
- if (varargsFormal == null &&
- actuals.size() != formals.size()) {
- throw unambiguousNoInstanceException
- .setMessage("infer.arg.length.mismatch");
- }
- while (actuals.nonEmpty() && formals.head != varargsFormal) {
- Type formal = formals.head;
- Type actual = actuals.head.baseType();
- Type actualNoCapture = actualsNoCapture.head.baseType();
- Type undetFormal = types.subst(formal, tvars, undetvars);
- if (actual.tag == FORALL) {
- forcePostCheck = true;
- //improvement - go ahead with method conversion check but create
- //a 'fake' actual arg, where tvars are replaced with undet var
- final ForAll fa = (ForAll)actual;
- final List<Type> arg_fvs = Type.map(fa.tvars, fromTypeVarFun);
- argUndetvars.appendList(arg_fvs);
- actual = types.subst(fa, fa.tvars, arg_fvs);
- capturedArgs.append(makeUnknownArgumentForAll(fa, arg_fvs));
- }
- else {
- capturedArgs.append(actual = types.capture(actual));
- }
- boolean works = false;
- JCDiagnostic problem = null;
- try {
- works = chk.checkArgument(env, actual, undetFormal, allowBoxing, warn);
- }
- catch (Types.ConversionException ex) {
- problem = ex.getDiagnostic(diags);
- }
- if (!works) {
- argumentMismatch(tvars, actualNoCapture, formal, problem);
- }
- formals = formals.tail;
- actuals = actuals.tail;
- actualsNoCapture = actualsNoCapture.tail;
- }
- if (formals.head != varargsFormal) // not enough args
- throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch");
-
- // for varargs arguments as well
- if (useVarargs) {
- //note: if applicability check is triggered by most specific test,
- //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
- Type elemType = types.elemtypeOrType(varargsFormal);
- Type elemUndet = types.subst(elemType, tvars, undetvars);
- while (actuals.nonEmpty()) {
- Type actual = actuals.head.baseType();
- Type actualNoCapture = actualsNoCapture.head.baseType();
-
-
- if (actual.tag == FORALL) {
- forcePostCheck = true;
- //improvement - go ahead with method conversion check but create
- //a 'fake' actual arg, where tvars are replaced with undet var
- final ForAll fa = (ForAll)actual;
- final List<Type> arg_fvs = Type.map(fa.tvars, fromTypeVarFun);
- argUndetvars.appendList(arg_fvs);
- actual = types.subst(fa, fa.tvars, arg_fvs);
- capturedArgs.append(makeUnknownArgumentForAll(fa, arg_fvs));
- } else {
- capturedArgs.append(actual = types.capture(actual));
- }
- boolean works = false;
- JCDiagnostic problem = null;
- try {
- works = chk.checkArgument(env, actual, elemUndet, allowBoxing, warn);
- }
- catch (Types.ConversionException ex) {
- problem = ex.getDiagnostic(diags);
- }
- if (!works) {
- argumentMismatch(tvars, actualNoCapture, elemType, problem);
- }
- actuals = actuals.tail;
- actualsNoCapture = actualsNoCapture.tail;
- }
- }
- }
-
- // minimize as yet undetermined type variables
- for (Type t : undetvars.appendList(argUndetvars))
- minimizeInst((UndetVar) t, warn);
-
- /** Type variables instantiated to bottom */
- ListBuffer<Type> restvars = new ListBuffer<Type>();
-
- /** Undet vars instantiated to bottom */
- final ListBuffer<Type> restundet = new ListBuffer<Type>();
-
- /** Instantiated types or TypeVars if under-constrained */
- ListBuffer<Type> insttypes = new ListBuffer<Type>();
-
- /** Instantiated types or UndetVars if under-constrained */
- ListBuffer<Type> undettypes = new ListBuffer<Type>();
-
- for (Type t : undetvars) {
- UndetVar uv = (UndetVar)t;
- while (uv.inst != null && uv.inst.tag == UNDETVAR) {
- uv = (UndetVar)uv.inst;
- }
- if (uv.inst == null) {
- uv = (UndetVar)t;
- }
- if (uv.inst.tag == UNDETVAR || uv.inst.tag == BOT) {
- restvars.append(uv.qtype);
- restundet.append(uv);
- insttypes.append(uv.qtype);
- undettypes.append(uv);
- if (uv.inst.tag == BOT)
- uv.inst = null;
- } else {
- insttypes.append(uv.inst);
- undettypes.append(uv.inst);
- }
- }
- checkWithinBounds(tvars, undettypes.toList(), warn);
-
- mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
-
- if (!restvars.isEmpty() || forcePostCheck) {
- // if there are uninstantiated variables,
- // quantify result type with them
- final List<Type> inferredTypes = insttypes.toList();
- final List<Type> all_tvars = tvars; //this is the wrong tvars
- return new UninferredMethodType(mt, restvars.toList()) {
- @Override
- public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
- return Infer.this.getConstraints(restundet.toList(), tv, EnumSet.of(ck), all_tvars, inferredTypes);
- }
-
- @Override
- public void check(List<Type> inferred, Types types, Type to, ForAll.InstantiationPhase phase) throws NoInstanceException {
- List<Type> inferred2 = inferred;
- for (Type t : restundet.toList()) {
- //this has the side-effect of instantiating any
- //undetvar in the actual types whose instantiation
- //was an uninferred undetvar
- UndetVar uv = (UndetVar)t;
- uv.inst = inferred2.head;
- inferred2 = inferred2.tail;
- }
- // check that actuals conform to inferred formals
- checkArgumentsAcceptable(env, capturedArgs.toList(), getParameterTypes(), allowBoxing, useVarargs, warn, phase);
- // check that inferred bounds conform to their bounds
- checkWithinBounds(all_tvars,
- types.subst(inferredTypes, tvars, inferred), warn);
- if (useVarargs) {
- chk.checkVararg(env.tree.pos(), getParameterTypes(), msym);
- }
- }};
- }
- else {
- // check that actuals conform to inferred formals
- checkArgumentsAcceptable(env, capturedArgs.toList(), mt.getParameterTypes(), allowBoxing, useVarargs, warn, ForAll.InstantiationPhase.RESOLUTION);
- // return instantiated version of method type
- return mt;
- }
- }
- //where
-
- /**
- * A delegated type representing a partially uninferred method type.
- * The return type of a partially uninferred method type is a ForAll
- * type - when the return type is instantiated (see Infer.instantiateExpr)
- * the underlying method type is also updated.
- */
- abstract class UninferredMethodType extends DelegatedType {
-
- final List<Type> tvars;
-
- public UninferredMethodType(MethodType mtype, List<Type> tvars) {
- super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym));
- this.tvars = tvars;
- asMethodType(types).restype = new UninferredReturnType(tvars, mtype.restype);
- }
-
- @Override
- public MethodType asMethodType(Types types) {
- return qtype.asMethodType(types);
- }
-
- @Override
- public Type map(Mapping f) {
- return qtype.map(f);
- }
-
- void instantiateReturnType(Type restype, List<Type> inferred, Type to, Types types, ForAll.InstantiationPhase phase) throws NoInstanceException {
- //update method type with newly inferred type-arguments
- qtype = new MethodType(types.subst(getParameterTypes(), tvars, inferred),
- restype,
- types.subst(UninferredMethodType.this.getThrownTypes(), tvars, inferred),
- UninferredMethodType.this.qtype.tsym);
- check(inferred, types, to, phase);
- }
-
- abstract void check(List<Type> inferred, Types types, Type to, ForAll.InstantiationPhase phase) throws NoInstanceException;
-
- abstract List<Type> getConstraints(TypeVar tv, ConstraintKind ck);
-
- class UninferredReturnType extends ForAll {
- public UninferredReturnType(List<Type> tvars, Type restype) {
- super(tvars, restype);
- }
- @Override
- public Type inst(List<Type> actuals, Type to, Types types, ForAll.InstantiationPhase phase) {
- Type newRestype = super.inst(actuals, to, types, phase);
- instantiateReturnType(newRestype, actuals, to, types, phase);
- return newRestype;
- }
- @Override
- public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
- return UninferredMethodType.this.getConstraints(tv, ck);
- }
- }
- }
-
- private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals,
- boolean allowBoxing, boolean useVarargs, Warner warn, ForAll.InstantiationPhase phase) {
- try {
- rs.checkRawArgumentsAcceptable(env, actuals, formals,
- allowBoxing, useVarargs, warn, phase);
- }
- catch (Resolve.InapplicableMethodException ex) {
- // inferred method is not applicable
- throw invalidInstanceException.setMessage(ex.getDiagnostic());
- }
- }
- private ForAll makeUnknownArgumentForAll(final ForAll fa, final List<Type> undetvars) {
- return new ForAll(fa.tvars, fa.qtype) {
- @Override
- public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
- return Infer.this.getConstraints(undetvars, tv, EnumSet.of(ck), fa.tvars, undetvars);
- }
- @Override
- public Type inst(List<Type> actuals, Type to, Types types, ForAll.InstantiationPhase phase) {
- return fa.inst(actuals, to, types, phase);
- }
- };
- }
- //where
- private void argumentMismatch(List<Type> tvars, Type actual, Type formal, JCDiagnostic problem) throws InferenceException {
- if (tvars.nonEmpty()) {
- String errKey = problem == null ?
- "infer.no.conforming.assignment.exists" :
- "infer.no.conforming.assignment.exists.1";
- throw unambiguousNoInstanceException
- .setMessage(errKey,
- tvars, actual, formal, problem);
- }
- else {
- String errKey = problem == null ?
- "no.conforming.assignment.exists" :
- "no.conforming.assignment.exists.1";
- throw unambiguousNoInstanceException
- .setMessage(errKey,
- actual, formal, problem);
- }
- }
-
- private List<Type> getConstraints(List<Type> undetvars, TypeVar tv, EnumSet<ConstraintKind> constraints, List<Type> tvars, List<Type> inferred) {
- for (Type t : undetvars) {
- UndetVar uv = (UndetVar)t;
- if (uv.qtype == tv) {
- for (ConstraintKind ck : constraints) {
- switch (ck) {
- case EXTENDS:
- ListBuffer<Type> hibounds = ListBuffer.lb();
- for (Type t2 : uv.hibounds) {
- hibounds.appendList(t2.tag == UNDETVAR ?
- getConstraints(List.of(t2), tv, EnumSet.of(ck, ConstraintKind.EQUAL), tvars, inferred) :
- uv.hibounds);
- }
- return types.subst(hibounds.appendList(types.getBounds(tv)).toList(), tvars, inferred);
- case SUPER:
- ListBuffer<Type> lobounds = ListBuffer.lb();
- for (Type t2 : uv.lobounds) {
- lobounds.appendList(t2.tag == UNDETVAR ?
- getConstraints(List.of(t2), tv, EnumSet.of(ck, ConstraintKind.EQUAL), tvars, inferred) :
- uv.lobounds);
- }
- return types.subst(lobounds.toList(), tvars, inferred);
- case EQUAL: {
- if (uv.inst == null) return List.nil();
- else
- return uv.inst.tag == UNDETVAR ?
- getConstraints(List.of(uv.inst), tv, EnumSet.of(ck), tvars, inferred) :
- List.of(types.subst(uv.inst, tvars, inferred));
- }
- }
- }
- }
- }
- return List.nil();
- }
-
- /** Try to instantiate argument type `that' to given type `to'.
- * If this fails, try to insantiate `that' to `to' where
- * every occurrence of a type variable in `tvars' is replaced
- * by an unknown type.
- */
- public Type instantiateArg(Env<AttrContext> env, ForAll that,
- Type to,
- Warner warn, ForAll.InstantiationPhase phase) throws InferenceException {
- Type inferredArg = null;
- try {
- inferredArg = instantiateExpr(env, that, to, warn, phase);
- }
- catch (Infer.InferenceException e) {
- inferredArg = syms.errType;
- }
- return inferredArg;
- }
-
/** check that type parameters are within their bounds.
*/
void checkWithinBounds(List<Type> tvars,
@@ -738,7 +328,372 @@ public class Infer {
args.head, bounds);
}
}
-
+
+/***************************************************************************
+ * Exported Methods
+ ***************************************************************************/
+
+ // <editor-fold desc="uninferred inference vars instantiation">
+ /**
+ * Try to instantiate any uninferred inference variable in the current
+ * inference context, so that the poly type `that' conforms to given type `to'.
+ * If a maximal instantiation exists the instantiate type-arguments are
+ * returned.
+ */
+ public List<Type> instantiateExpr(Env<AttrContext> env, ForAll that,
+ Type to,
+ Warner warn) throws InferenceException {
+ try {
+ Assert.check(that.getPolyTag() == POLY_RETURN);
+ Type qtype1 = asUndetType(that.qtype);
+ if (!types.isAssignable(qtype1,
+ qtype1.tag == UNDETVAR ? types.boxedTypeOrType(to) : to)) {
+ throw unambiguousNoInstanceException
+ .setMessage("infer.no.conforming.instance.exists",
+ inferenceVars(), that.qtype, to);
+ }
+ for (List<Type> l = undetVars(); l.nonEmpty(); l = l.tail)
+ maximizeInst((UndetVar) l.head, warn);
+ // check bounds
+ List<Type> targs = Type.map(undetVars(), getInstFun);
+ if (Type.containsAny(targs, inferenceVars())) {
+ //replace uninferred type-vars
+ targs = types.subst(targs,
+ inferenceVars(),
+ instaniateAsUninferredVars(undetVars(), inferenceVars()));
+ }
+ return targs;
+ }
+ finally {
+ inferenceContexts.head.clear();
+ }
+ }
+ //where
+ private List<Type> instaniateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
+ ListBuffer<Type> new_targs = ListBuffer.lb();
+ //step 1 - create syntethic captured vars
+ for (Type t : undetvars) {
+ UndetVar uv = (UndetVar)t;
+ Type newArg = new CapturedType(t.tsym.name, t.tsym, uv.inst, syms.botType, null);
+ new_targs = new_targs.append(newArg);
+ }
+ //step 2 - replace synthetic vars in their bounds
+ for (Type t : new_targs.toList()) {
+ CapturedType ct = (CapturedType)t;
+ ct.bound = types.subst(ct.bound, tvars, new_targs.toList());
+ WildcardType wt = new WildcardType(ct.bound, BoundKind.EXTENDS, syms.boundClass);
+ ct.wildcard = wt;
+ }
+ return new_targs.toList();
+ }
+ // </editor-fold>
+
+ // <editor-fold desc="method instantiation routines">
+ /**
+ * Instantiate a method type. There are two cases in which a method type
+ * should require instantiation: (i) if the method is generic (i.e. it
+ * has type-parameters) or (ii) if any of the actual types supplied to the
+ * method is a poly type (see Type.ForAll).
+ *
+ * The inference process repeatedly checks actual arguments types against
+ * formal argument types in order to derive constraints on the current
+ * inference variables. Note that checking arguments might trigger completion
+ * of poly types (and, possibly, this can cause deferred attribution).
+ *
+ * The loop terminates when either (i) all arguments have been checked or,
+ * (ii) not all arguments have been checked, but no further progress can be
+ * made. In the latter case an error is issued (cyclic inference).
+ *
+ * It is possible that one or more inference variables are left uninferred
+ * at the end of the checking loop. If this happens, the method return type
+ * is replaced with a poly type, indicating that the method return type
+ * requires additional instantiation - this additional step will be carried
+ * out when i.e. the method return value is assigned to a variable, in which
+ * case, the expected type (of the variable) is used to influence the result
+ * of this second inference pass (see Infer.instantiateExpr).
+ */
+ public Type instantiateMethod(final Env<AttrContext> env,
+ List<Type> tvars,
+ MethodType mt,
+ final Symbol msym,
+ final List<Type> argtypes,
+ final boolean allowBoxing,
+ final boolean useVarargs,
+ boolean polyArgs,
+ final Warner warn) throws InferenceException {
+
+ //init
+ List<Type> uncheckedArgs = List.nil();
+ List<Type> prevUncheckedArgs;
+
+ do {
+ prevUncheckedArgs = uncheckedArgs;
+ uncheckedArgs = rs.checkRawArgumentsAcceptable(env, mt, argtypes,
+ allowBoxing, useVarargs, warn,
+ inferenceVars().isEmpty() ? rs.resolveHandler : inferenceHandler);
+
+ // minimize as yet undetermined type variables
+ for (Type t : undetVars())
+ minimizeInst((UndetVar) t, warn);
+
+ /** Type variables instantiated to bottom */
+ ListBuffer<Type> restvars = new ListBuffer<Type>();
+
+ /** Undet vars instantiated to bottom */
+ final ListBuffer<Type> restundet = new ListBuffer<Type>();
+
+ /** Instantiated types or TypeVars if under-constrained */
+ List<Type> insttypes = List.nil();
+
+ /** Instantiated types or UndetVars if under-constrained */
+ List<Type> undettypes = List.nil();
+
+ for (Type t : undetVars()) {
+ UndetVar uv = (UndetVar)t;
+ Type inst = uv.inst == null ? null : partialInstFun.apply(uv.inst);
+ if (uv.inst == null || uv.inst.tag == BOT) {
+ restvars.append(uv.qtype);
+ restundet.append(uv);
+ insttypes = insttypes.append(uv.qtype);
+ undettypes = undettypes.append(uv);
+ uv.inst = null;
+ } else {
+ insttypes = insttypes.append(inst);
+ undettypes = undettypes.append(inst);
+ }
+ }
+
+ checkWithinBounds(inferenceVars(), undettypes, warn);
+
+ mt = (MethodType)types.subst(mt, inferenceVars(), insttypes);
+
+ //if no progress has been made, terminate the loop
+ if (prevUncheckedArgs.size() == uncheckedArgs.size() &&
+ uncheckedArgs.size() > 0) {
+ throw invalidInstanceException.setMessage("cyclic.lambda.inference");
+ }
+ tvars = restvars.toList();
+ }
+ while (uncheckedArgs.size() > 0 && tvars.nonEmpty());
+
+ if (tvars.nonEmpty() || polyArgs) {
+ // if there are uninstantiated variables,
+ // quantify result type with them
+ return new UninferredMethodType(env, mt, types) {
+ @Override
+ void check(List<Type> inferred) throws NoInstanceException {
+ // check that actuals conform to inferred formals
+ try {
+ rs.checkRawArgumentsAcceptable(env, qtype, argtypes, allowBoxing, useVarargs, warn);
+ }
+ catch (Resolve.InapplicableMethodException ex) {
+ // inferred method is not applicable
+ throw invalidInstanceException.setMessage(ex.getDiagnostic());
+ }
+ // check that inferred bounds conform to their bounds
+ checkWithinBounds(tvars, inferred, warn);
+ if (useVarargs) {
+ chk.checkVararg(env.tree.pos(), getParameterTypes(), msym);
+ }
+ }};
+ }
+ else {
+ //no rest vars - clear inference context
+ inferenceContexts.head.clear();
+ try {
+ // check that actuals conform to inferred formals
+ rs.checkRawArgumentsAcceptable(env, mt, argtypes, allowBoxing, useVarargs, warn);
+ }
+ catch (Resolve.InapplicableMethodException ex) {
+ // inferred method is not applicable
+ throw invalidInstanceException.setMessage(ex.getDiagnostic());
+ }
+ // return instantiated version of method type
+ return mt;
+ }
+ }
+ //where
+
+ /** inference check handler **/
+ Resolve.MethodCheckHandler inferenceHandler = new Resolve.MethodCheckHandler() {
+ public void arityMismatch() {
+ throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch");
+ }
+ public void argumentMismatch(boolean varargs, Type found, Type expected, JCDiagnostic cause) {
+ String key = null;
+ if (varargs) {
+ key = cause == null ?
+ "infer.varargs.argument.mismatch" :
+ "infer.varargs.argument.mismatch.1";
+ } else {
+ key = cause == null ?
+ "infer.no.conforming.assignment.exists" :
+ "infer.no.conforming.assignment.exists.1";
+ }
+ throw unambiguousNoInstanceException.setMessage(key,
+ inferenceVars(), found, expected, cause);
+ }
+ public void inaccessibleVarargs(Symbol location, Type expected) {
+ //this kind of error should not be acted upon at this stage
+ }
+ };
+
+ /**
+ * A delegated type representing a partially uninferred method type.
+ * The return type of a partially uninferred method type is a ForAll
+ * type - when the return type is instantiated (see Infer.instantiateExpr)
+ * the underlying method type is also updated.
+ */
+ abstract class UninferredMethodType extends DelegatedType {
+
+ final List<Type> tvars;
+ Env<AttrContext> env;
+
+ public UninferredMethodType(Env<AttrContext> env, Type mt, Types types) {
+ super(METHOD, new MethodType(mt.getParameterTypes(), null, mt.getThrownTypes(), mt.tsym));
+ this.tvars = inferenceVars();
+ this.env = env;
+ asMethodType().restype = new UninferredReturnType(env, mt.getReturnType(), types);
+ }
+
+ @Override
+ public MethodType asMethodType() {
+ return qtype.asMethodType();
+ }
+
+ @Override
+ public Type map(Mapping f) {
+ return qtype.map(f);
+ }
+
+ void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
+ //update method type with newly inferred type-arguments
+ qtype = new MethodType(types.subst(getParameterTypes(), tvars, inferred),
+ restype,
+ types.subst(UninferredMethodType.this.getThrownTypes(), tvars, inferred),
+ UninferredMethodType.this.qtype.tsym);
+ check(inferred);
+ }
+
+ abstract void check(List<Type> inferred) throws NoInstanceException;
+
+ class UninferredReturnType extends ForAll {
+ public UninferredReturnType(final Env<AttrContext> env, Type restype, final Types types) {
+ super(POLY_RETURN, restype);
+ completer = new Completer() {
+ public Type complete(ForAll fa, Type to, boolean allowBoxing) {
+ List<Type> actuals = instantiateExpr(env, fa, to, Warner.noWarnings);
+ fa.qtype = types.subst(fa.qtype, tvars, actuals);
+ instantiateReturnType(fa.qtype, actuals, types);
+ return fa.qtype;
+ }
+ };
+ //include upper bounds
+ for (Type t : undetVars()) {
+ UndetVar uv = (UndetVar)t;
+ uv.hibounds = uv.hibounds.appendList(asUndetTypes(types.getBounds((TypeVar)uv.qtype)));
+ }
+ }
+ }
+ }
+ // </editor-fold>
+
+ // <editor-fold desc="SAM type instantiation">
+ /**
+ * This method is used to infer a suitable target SAM in case the original
+ * SAM type contains one or more wildcards. An inference process is applied
+ * so that wildcard bounds, as well as explicit lambda/method ref parameters
+ * (where applicable) are used to constraint the solution.
+ */
+ public Type inferSAM(Env<AttrContext> env, Type samType, List<Type> paramTypes) {
+ if (types.capture(samType) == samType) {
+ //if capture doesn't change the type then return the target unchanged
+ //(this means the target contains no wilddcards!)
+ return samType;
+ } else {
+ List<Type> tvars = samType.tsym.type.getTypeArguments();
+ Type formalSam = samType.tsym.type;
+ if (paramTypes != null) {
+ pushContext(formalSam.getTypeArguments());
+ //get constraints from explicit params (this is done by
+ //checking that explicit param types are equal to the ones
+ //in the SAM descriptors)
+ Type undetSAM = asUndetType(formalSam);
+ Type target = types.findSAM(undetSAM, env).getTargetType();
+ if (!types.isSameTypes(target.getParameterTypes(), paramTypes)) {
+ throw invalidInstanceException;
+ }
+ for (List<Type> l = undetVars(); l.nonEmpty(); l = l.tail) {
+ UndetVar uv = (UndetVar) l.head;
+ if (uv.lobounds.nonEmpty())
+ minimizeInst(uv, Warner.noWarnings);
+ else if (uv.hibounds.nonEmpty())
+ maximizeInst(uv, Warner.noWarnings);
+ if (uv.inst == null || uv.inst.tag == BOT) {
+ uv.inst = uv.qtype;
+ }
+ }
+ List<Type> targs = Type.map(undetVars(), getInstFun);
+ formalSam = types.subst(formalSam, inferenceVars(), targs);
+ //discard current context;
+ popContext(false);
+ }
+ ListBuffer<Type> typeargs = ListBuffer.lb();
+ List<Type> actualTypeargs = samType.getTypeArguments();
+ //for remaining uninferred type-vars in the SAM type,
+ //simply replace the wildcards with its bound
+ for (Type t : formalSam.getTypeArguments()) {
+ if (tvars.contains(t) && actualTypeargs.head.tag == WILDCARD) {
+ WildcardType wt = (WildcardType)actualTypeargs.head;
+ typeargs.append(wt.type);
+ } else {
+ typeargs.append(t);
+ }
+ actualTypeargs = actualTypeargs.tail;
+ }
+ Type owntype = types.subst(formalSam, tvars, typeargs.toList());
+ if (!chk.checkValidGenericType(owntype) || !types.isSubtypeUnchecked(owntype, samType)) {
+ //if the inferred SAM type is not well-formed, or if it's not
+ //a subtype of the original target, issue an error
+ throw invalidInstanceException;
+ }
+ return owntype;
+ }
+ }
+ // </editor-fold>
+
+ // <editor-fold desc="actual argument instantiation">
+ /**
+ * Instantiate an actual argument type (whose kind is a poly type) using
+ * the corresponding formal as target type. This could trigger poly type
+ * completion (and, as a consequence, deferred attribution).
+ */
+ public Type instantiateArg(Env<AttrContext> env, Type mtype, ForAll that,
+ Type to, Warner warn, boolean allowBoxing) throws InferenceException {
+ switch (that.getPolyTag()) {
+ case POLY_LAMBDA:
+ case POLY_REFERENCE:
+ //is the target a valid SAM?
+ Types.SAMResult samRes = types.findSAM(to, env);
+ if (samRes.isErroneous()) {
+ throw invalidInstanceException.setMessage(samRes.getDiagnostic(diags));
+ }
+ //complete the poly type iff either (i) the lambda/mref has
+ //explicit params, or (ii) the formals in the expected SAM desc
+ //do not contain any inference var
+ List<Type> expectedFormals = samRes.getTargetType().getParameterTypes();
+ if (that.getParameterTypes() != null ||
+ !Type.containsAny(expectedFormals, inferenceVars())) {
+ return that.complete(asUndetType(to), allowBoxing);
+ } else {
+ throw unambiguousNoInstanceException;
+ }
+ default: Assert.error(); return Type.noType;
+ }
+ }
+ // </editor-fold>
+
+ // <editor-fold desc="Polymorphic signature instantiation">
/**
* Compute a synthetic method type corresponding to the requested polymorphic
* method signature. The target return type is computed from the immediately
@@ -798,4 +753,79 @@ public class Infer {
return t;
}
};
- }
+ // </editor-fold>
+
+ // <editor-fold desc="Inference context handling">
+ /**
+ * An inference context contains a set of type-variables and corresponding
+ * undet variables, used to keep track of constraints. In the typical scenario,
+ * an inference context is pushed onto the stack when a new method signature
+ * needs to be instantiated. Such context is then popped off the stack when
+ * overload resolution is completed. It is possible that, when popping an
+ * inference context, its variables/undetvars are copied over to the
+ * outer context (this behavior is required in order to propagate inference
+ * variables in the right way).
+ */
+ class InferenceContext {
+ List<Type> tvars;
+ List<Type> undetvars;
+
+ public InferenceContext() {
+ this(List.<Type>nil());
+ }
+
+ public InferenceContext(List<Type> tvars) {
+ this.tvars = tvars;
+ this.undetvars = Type.map(tvars, fromTypeVarFun);
+ }
+
+ void clear() {
+ tvars = List.nil();
+ undetvars = List.nil();
+ }
+ }
+
+ /** starts off with global context - for Check.instantiatePoly **/
+ List<InferenceContext> inferenceContexts = List.of(new InferenceContext());
+
+ void pushContext(List<Type> tvars) {
+ inferenceContexts = inferenceContexts.prepend(new InferenceContext(tvars));
+ }
+
+ void popContext(boolean merge) {
+ InferenceContext oldCtx = inferenceContexts.head;
+ inferenceContexts = inferenceContexts.tail;
+ if (merge) {
+ inferenceContexts.head.tvars = inferenceContexts.head.tvars.appendList(oldCtx.tvars);
+ inferenceContexts.head.undetvars = inferenceContexts.head.undetvars.appendList(oldCtx.undetvars);
+ }
+ }
+
+ /**
+ * Return an uninstantiated version of this type, where the inference
+ * type-variables are replaced with undetvars. This is useful in order
+ * to perform subtyping tests, conversions, etc.
+ */
+ Type asUndetType(Type t) {
+ return types.subst(t,
+ inferenceContexts.head.tvars,
+ inferenceContexts.head.undetvars);
+ }
+
+ List<Type> asUndetTypes(List<Type> ts) {
+ ListBuffer<Type> buf = ListBuffer.lb();
+ for (Type t : ts) {
+ buf.append(asUndetType(t));
+ }
+ return buf.toList();
+ }
+
+ List<Type> inferenceVars() {
+ return inferenceContexts.head.tvars;
+ }
+
+ List<Type> undetVars() {
+ return inferenceContexts.head.undetvars;
+ }
+ // </editor-fold>
+}
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri May 20 17:19:01 2011 +0100
@@ -3140,7 +3140,7 @@ public class Lower extends TreeTranslato
@SuppressWarnings("unchecked") // XXX unchecked
<T extends JCTree> T unlambdaIfNeeded(T tree, Type type) {
- if (types.isSameType(tree.type, syms.methodHandleType) &&
+ if ((tree.getTag() == LAMBDA || tree.getTag() == JCTree.REFERENCE) &&
!types.findSAM(type, attrEnv).isErroneous()) {
return (T)(type.isInterface() ?
lambdaToInterface((JCExpression)tree, type) :
@@ -4019,7 +4019,8 @@ public class Lower extends TreeTranslato
JCBlock makeLambdaBody(JCLambda tree) {
JCReturn defaultRet = null;
- if ((tree.sym.flags() & Flags.NEEDS_RETURN) != 0) {
+ if (tree.canCompleteNormally &&
+ types.isSameType(tree.type.getReturnType(), types.boxedClass(syms.voidType).type)) {
defaultRet = make.Return(make.Literal(TypeTags.BOT, null).setType(syms.botType));
}
JCBlock body = null;
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri May 20 17:19:01 2011 +0100
@@ -375,11 +375,10 @@ public class MemberEnter extends JCTree.
exc = chk.checkClassType(l.head.pos(), exc);
thrownbuf.append(exc);
}
- Type mtype = new MethodType(argbuf.toList(),
+ return new MethodType(tvars, argbuf.toList(),
restype,
thrownbuf.toList(),
syms.methodClass);
- return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
}
/* ********************************************************************
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 20 17:19:01 2011 +0100
@@ -90,12 +90,10 @@ public class Resolve {
varNotFound = new
SymbolNotFoundError(ABSENT_VAR);
- wrongMethod = new
- InapplicableSymbolError(syms.errSymbol);
- wrongMethods = new
- InapplicableSymbolsError(syms.errSymbol);
- methodNotFound = new
- SymbolNotFoundError(ABSENT_MTH);
+
+ methodNotFound =
+ new SymbolNotFoundError(ABSENT_MTH);
+
typeNotFound = new
SymbolNotFoundError(ABSENT_TYP);
@@ -123,8 +121,6 @@ public class Resolve {
/** error symbols, which are returned when resolution fails
*/
final SymbolNotFoundError varNotFound;
- final InapplicableSymbolError wrongMethod;
- final InapplicableSymbolsError wrongMethods;
final SymbolNotFoundError methodNotFound;
final SymbolNotFoundError typeNotFound;
@@ -331,6 +327,7 @@ public class Resolve {
List<Type> typeargtypes,
boolean allowBoxing,
boolean useVarargs,
+ boolean check,
Warner warn)
throws Infer.InferenceException {
boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
@@ -346,59 +343,76 @@ public class Resolve {
mt = types.subst(mt, env.info.tvars, tvars);
}
if (typeargtypes == null) typeargtypes = List.nil();
- if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
+ if (!mt.isParameterized() && typeargtypes.nonEmpty()) {
// This is not a polymorphic method, but typeargs are supplied
// which is fine, see JLS3 15.12.2.1
- } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
- ForAll pmt = (ForAll) mt;
- if (typeargtypes.length() != pmt.tvars.length())
+ } else if (mt.isParameterized() && typeargtypes.nonEmpty()) {
+ if (typeargtypes.length() != mt.getTypeArguments().length())
throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
// Check type arguments are within bounds
- List<Type> formals = pmt.tvars;
+ List<Type> formals = mt.getTypeArguments();
List<Type> actuals = typeargtypes;
ListBuffer<Type> actuals2 = ListBuffer.lb();
while (formals.nonEmpty() && actuals.nonEmpty()) {
Type actual = chk.checkParameterType(actuals.head, formals.head);
actuals2.append(actual);
List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
- pmt.tvars, typeargtypes);
+ mt.getTypeArguments(), typeargtypes);
for (; bounds.nonEmpty(); bounds = bounds.tail)
if (!types.isSubtypeUnchecked(actual, bounds.head, warn))
throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
formals = formals.tail;
actuals = actuals.tail;
}
- mt = types.subst(pmt.qtype, pmt.tvars, actuals2.toList());
- } else if (mt.tag == FORALL) {
- ForAll pmt = (ForAll) mt;
- List<Type> tvars1 = types.newInstances(pmt.tvars);
+ Type mt2 = types.createMethodTypeWithTypeArguments((MethodType)mt, List.<Type>nil());
+ mt = types.subst(mt2, mt.getTypeArguments(), actuals2.toList());
+ } else if (mt.isParameterized()) {
+ List<Type> tvars1 = types.newInstances(mt.getTypeArguments());
tvars = tvars.appendList(tvars1);
- mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
+ mt = types.subst(mt, mt.getTypeArguments(), tvars1);
}
// find out whether we need to go the slow route via infer
+
+ boolean hasPolyArgs = false;
+ for (Type t : argtypes) {
+ if (t.getPolyTag() != NO_POLY) {
+ hasPolyArgs = true;
+ break;
+ }
+ }
+
boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
- polymorphicSignature;
- for (List<Type> l = argtypes;
- l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
- l = l.tail) {
- if (l.head.tag == FORALL) instNeeded = true;
- }
-
- if (instNeeded)
- return polymorphicSignature ?
- infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
- infer.instantiateMethod(env,
- tvars,
- (MethodType)mt,
- m,
- argtypes,
- allowBoxing,
- useVarargs,
- warn);
-
- checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
- allowBoxing, useVarargs, warn, ForAll.InstantiationPhase.RESOLUTION);
+ polymorphicSignature ||
+ hasPolyArgs;
+
+ List<Type> argsToCheck = argtypes == Type.noTypes ?
+ Type.noTypes :
+ types.capture(types.upperBounds(argtypes));
+
+ if (instNeeded) {
+ try {
+ infer.pushContext(tvars);
+ return polymorphicSignature ?
+ infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argsToCheck) :
+ infer.instantiateMethod(env,
+ tvars,
+ (MethodType)mt,
+ m,
+ argsToCheck,
+ allowBoxing,
+ useVarargs,
+ hasPolyArgs,
+ warn);
+ }
+ finally {
+ //if we are checking the method, and if the call is not unchecked
+ //copy current inference vars to outer inference context
+ infer.popContext(check && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED));
+ }
+ }
+
+ checkRawArgumentsAcceptable(env, mt, argsToCheck, allowBoxing, useVarargs, warn);
return mt;
}
@@ -411,116 +425,189 @@ public class Resolve {
List<Type> typeargtypes,
boolean allowBoxing,
boolean useVarargs,
+ boolean check,
Warner warn) {
try {
return rawInstantiate(env, site, m, argtypes, typeargtypes,
- allowBoxing, useVarargs, warn);
+ allowBoxing, useVarargs, check, warn);
} catch (InapplicableMethodException ex) {
return null;
}
}
+ // <editor-fold desc="method applicability check">
+
/** Check if a parameter list accepts a list of args.
*/
boolean argumentsAcceptable(Env<AttrContext> env,
+ Type mtype,
+ List<Type> argtypes,
+ boolean allowBoxing,
+ boolean useVarargs,
+ Warner warn) {
+ try {
+ checkRawArgumentsAcceptable(env, mtype, argtypes, allowBoxing, useVarargs, warn);
+ return true;
+ } catch (InapplicableMethodException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * A check handler is used by the main method applicability routine in order
+ * to handle specific method applicability failures. It is assumed that a class
+ * implementing this interface should throw exceptions that are a subtype of
+ * InapplicableMethodException (see below). Such exception will terminate the
+ * method applicability check and propagate important info outwards (for the
+ * purpose of generating better diagnostics).
+ */
+ interface MethodCheckHandler {
+ /* The number of actuals and formals differ */
+ void arityMismatch();
+ /* An actual argument type does not conform to the corresponding formal type */
+ void argumentMismatch(boolean varargs, Type found, Type expected, JCDiagnostic cause);
+ /* The element type of a varargs is not accessible in the current context */
+ void inaccessibleVarargs(Symbol location, Type expected);
+ }
+
+ /**
+ * Basic method check handler used within Resolve - all methods end up
+ * throwing InapplicableMethodException; a diagnostic fragment that describes
+ * the cause as to why the method is not applicable is set on the exception
+ * before it is thrown.
+ */
+ MethodCheckHandler resolveHandler = new MethodCheckHandler() {
+ public void arityMismatch() {
+ throw inapplicableMethodException.setMessage("arg.length.mismatch");
+ }
+ public void argumentMismatch(boolean varargs, Type found, Type expected, JCDiagnostic cause) {
+ String key = null;
+ if (varargs) {
+ key = cause == null ?
+ "varargs.argument.mismatch" :
+ "varargs.argument.mismatch.1";
+ } else {
+ key = cause == null ?
+ "no.conforming.assignment.exists" :
+ "no.conforming.assignment.exists.1";
+ }
+ throw inapplicableMethodException.setMessage(key,
+ found, expected, cause);
+ }
+ public void inaccessibleVarargs(Symbol location, Type expected) {
+ throw inapplicableMethodException.setMessage("inaccessible.varargs.type",
+ expected, Kinds.kindName(location), location);
+ }
+ };
+
+ List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env,
+ Type mtype,
List<Type> argtypes,
- List<Type> formals,
boolean allowBoxing,
boolean useVarargs,
Warner warn) {
- return argumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn, ForAll.InstantiationPhase.CHECK);
- }
- boolean argumentsAcceptable(Env<AttrContext> env,
+ return checkRawArgumentsAcceptable(env, mtype, argtypes,
+ allowBoxing, useVarargs, warn, resolveHandler);
+ }
+
+ /**
+ * Main method applicability routine. Given a list of actual types A,
+ * a list of formal types F, determines whether the types in A are
+ * compatible (by method invocation conversion) with the types in F.
+ *
+ * Since this routine is shared between overload resolution and method
+ * type-inference, it is crucial that actual types are converted to the
+ * corresponding 'undet' form (i.e. where inference variables are replaced
+ * with undetvars) so that constraints can be propagated and collected.
+ *
+ * Moreover, if one or more types in A is a poly type, this routine calls
+ * Infer.instantiateArg in order to complete the poly type (this might involve
+ * deferred attribution).
+ *
+ * A method check handler (see above) is used in order to report errors.
+ */
+ List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env,
+ Type mtype,
List<Type> argtypes,
- List<Type> formals,
boolean allowBoxing,
boolean useVarargs,
Warner warn,
- ForAll.InstantiationPhase phase) {
- try {
- checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn, phase);
- return true;
- } catch (InapplicableMethodException ex) {
- return false;
- }
- }
- void checkRawArgumentsAcceptable(Env<AttrContext> env, List<Type> argtypes,
- List<Type> formals,
- boolean allowBoxing,
- boolean useVarargs,
- Warner warn,
- ForAll.InstantiationPhase phase) {
- if (argtypes == Type.noTypes) return;
+ MethodCheckHandler handler) {
+ if (argtypes == Type.noTypes) return List.nil();
+
+ List<Type> formals = mtype.getParameterTypes();
Type varargsFormal = useVarargs ? formals.last() : null;
+ List<Type> uncheckedArgs = List.nil();
+
if (varargsFormal == null &&
argtypes.size() != formals.size()) {
- throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
+ handler.arityMismatch(); // not enough args
+ return uncheckedArgs;
}
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
- Type actual = argtypes.head.tag == FORALL ?
- infer.instantiateArg(env, (ForAll)argtypes.head, formals.head, warn, phase) :
- argtypes.head;
- boolean works = false;
- JCDiagnostic problem = null;
- try {
- works = chk.checkArgument(env, actual, formals.head, allowBoxing, warn);
- }
- catch (Types.ConversionException ex) {
- problem = ex.getDiagnostic(diags);
- }
- if (!works) {
- String errKey = problem == null ?
- "no.conforming.assignment.exists" :
- "no.conforming.assignment.exists.1";
- throw inapplicableMethodException.setMessage(errKey,
- actual,
- formals.head, problem);
+ Type actual = argtypes.head;
+ if (actual.tag == FORALL) {
+ try {
+ infer.instantiateArg(env, mtype, (ForAll)actual, formals.head, warn, allowBoxing);
+ } catch (Infer.NoInstanceException ex) {
+ uncheckedArgs = uncheckedArgs.append(actual);
+ } catch (Infer.InvalidInstanceException ex) {
+ handler.argumentMismatch(useVarargs, actual, formals.head, ex.diagnostic);
+ }
+ } else {
+ Type undetFormal = infer.asUndetType(formals.head);
+ boolean works = allowBoxing ?
+ types.isConvertible(argtypes.head, undetFormal, warn) :
+ types.isSubtypeUnchecked(argtypes.head, undetFormal, warn);
+ if (!works) {
+ handler.argumentMismatch(false, argtypes.head, formals.head, null);
+ return null;
+ }
}
argtypes = argtypes.tail;
formals = formals.tail;
}
- if (formals.head != varargsFormal)
- throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
+ if (formals.head != varargsFormal) {
+ handler.arityMismatch(); // not enough args
+ return uncheckedArgs;
+ }
if (useVarargs) {
//note: if applicability check is triggered by most specific test,
//the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
Type elt = types.elemtypeOrType(varargsFormal);
while (argtypes.nonEmpty()) {
- Type actual = argtypes.head.tag == FORALL ?
- infer.instantiateArg(env, (ForAll)argtypes.head, elt, warn, phase) :
- argtypes.head;
- boolean works = false;
- JCDiagnostic problem = null;
- try {
- works = chk.checkArgument(env, actual, elt, allowBoxing, warn);
- }
- catch (Types.ConversionException ex) {
- problem = ex.getDiagnostic(diags);
- }
- if (!works) {
- String errKey = problem == null ?
- "varargs.argument.mismatch" :
- "varargs.argument.mismatch.1";
- throw inapplicableMethodException.setMessage(errKey,
- actual,
- elt,
- problem);
+ Type actual = argtypes.head;
+ if (actual.tag == FORALL) {
+ try {
+ infer.instantiateArg(env, mtype, (ForAll)actual, elt, warn, allowBoxing);
+ } catch (Infer.NoInstanceException ex) {
+ uncheckedArgs = uncheckedArgs.append(actual);
+ } catch (InapplicableMethodException ex) {
+ handler.argumentMismatch(true, actual, elt, ex.diagnostic);
+ }
+ } else {
+ Type eltUndet = infer.asUndetType(elt);
+ if (!types.isConvertible(actual, eltUndet, warn)) {
+ handler.argumentMismatch(true,
+ argtypes.head,
+ elt, null);
+ return uncheckedArgs;
+ }
}
argtypes = argtypes.tail;
}
//check varargs element type accessibility
if (!isAccessible(env, elt)) {
Symbol location = env.enclClass.sym;
- throw inapplicableMethodException.setMessage("inaccessible.varargs.type",
- elt,
- Kinds.kindName(location),
- location);
- }
- }
- }
+ handler.inaccessibleVarargs(location, elt);
+ }
+ }
+ return uncheckedArgs;
+ }
+
// where
public static class InapplicableMethodException extends RuntimeException {
private static final long serialVersionUID = 0;
@@ -554,6 +641,7 @@ public class Resolve {
}
}
private final InapplicableMethodException inapplicableMethodException;
+ // </editor-fold>
/* ***************************************************************************
* Symbol lookup
@@ -729,15 +817,15 @@ public class Resolve {
Assert.check(sym.kind < AMBIGUOUS);
try {
rawInstantiate(env, site, sym, argtypes, typeargtypes,
- allowBoxing, useVarargs, Warner.noWarnings);
+ allowBoxing, useVarargs, false, Warner.noWarnings);
} catch (InapplicableMethodException ex) {
switch (bestSoFar.kind) {
case ABSENT_MTH:
- return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
+ return currentResolutionContext.wrongMethod.setWrongSym(sym, ex.getDiagnostic());
case WRONG_MTH:
- wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation);
+ currentResolutionContext.wrongMethods.addInitialCandidate();
case WRONG_MTHS:
- return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic());
+ return currentResolutionContext.wrongMethods.addCandidate(sym, ex.getDiagnostic());
default:
return bestSoFar;
}
@@ -813,8 +901,8 @@ public class Resolve {
// both abstract, neither overridden; merge throws clause and result type
Symbol mostSpecific;
Type result2 = mt2.getReturnType();
- if (mt2.tag == FORALL)
- result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
+ if (mt2.isParameterized())
+ result2 = types.subst(result2, mt2.getTypeArguments(), mt1.getTypeArguments());
if (types.isSubtype(mt1.getReturnType(), result2))
mostSpecific = m1;
else if (types.isSubtype(result2, mt1.getReturnType()))
@@ -865,9 +953,9 @@ public class Resolve {
noteWarner.clear();
Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
- allowBoxing, false, noteWarner) != null ||
+ allowBoxing, false, false, noteWarner) != null ||
useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
- allowBoxing, true, noteWarner) != null) &&
+ allowBoxing, true, false, noteWarner) != null) &&
!noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
}
//where
@@ -1481,32 +1569,33 @@ public class Resolve {
Name name,
List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = startResolution();
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentStep = steps.head;
- sym = findFun(env, name, argtypes, typeargtypes,
- steps.head.isBoxingRequired,
- env.info.varArgs = steps.head.isVarargsRequired);
- methodResolutionCache.put(steps.head, sym);
- steps = steps.tail;
- }
- if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
- MethodResolutionPhase errPhase =
- firstErroneousResolutionPhase();
- sym = access(methodResolutionCache.get(errPhase),
- pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
- env.info.varArgs = errPhase.isVarargsRequired;
- }
- return sym;
- }
-
- private Symbol startResolution() {
- wrongMethod.clear();
- wrongMethods.clear();
- return methodNotFound;
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ currentResolutionContext = new MethodResolutionContext();
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ currentResolutionContext.step = steps.head;
+ sym = findFun(env, name, argtypes, typeargtypes,
+ steps.head.isBoxingRequired,
+ env.info.varArgs = steps.head.isVarargsRequired);
+ currentResolutionContext.resolutionCache.put(steps.head, sym);
+ steps = steps.tail;
+ }
+ if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+ MethodResolutionPhase errPhase =
+ currentResolutionContext.firstErroneousResolutionPhase();
+ sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+ pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired;
+ }
+ return sym;
+ }
+ finally {
+ currentResolutionContext = prevResolutionContext;
+ }
}
/** Resolve a qualified method identifier
@@ -1526,40 +1615,47 @@ public class Resolve {
Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
Symbol location, Type site, Name name, List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = startResolution();
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentStep = steps.head;
- sym = findMethod(env, site, name, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- env.info.varArgs = steps.head.isVarargsRequired(), false);
- methodResolutionCache.put(steps.head, sym);
- steps = steps.tail;
- }
- if (sym.kind >= AMBIGUOUS) {
- if (site.tsym.isPolymorphicSignatureGeneric()) {
- //polymorphic receiver - synthesize new method symbol
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ currentResolutionContext = new MethodResolutionContext();
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ currentResolutionContext.step = steps.head;
+ sym = findMethod(env, site, name, argtypes, typeargtypes,
+ steps.head.isBoxingRequired(),
+ env.info.varArgs = steps.head.isVarargsRequired(), false);
+ currentResolutionContext.resolutionCache.put(steps.head, sym);
+ steps = steps.tail;
+ }
+ if (sym.kind >= AMBIGUOUS) {
+ if (site.tsym.isPolymorphicSignatureGeneric()) {
+ //polymorphic receiver - synthesize new method symbol
+ env.info.varArgs = false;
+ sym = findPolymorphicSignatureInstance(env,
+ site, name, null, argtypes);
+ }
+ else {
+ //if nothing is found return the 'first' error
+ MethodResolutionPhase errPhase =
+ currentResolutionContext.firstErroneousResolutionPhase();
+ sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+ pos, location, site, name, true, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired;
+ }
+ } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
+ //non-instantiated polymorphic signature - synthesize new method symbol
env.info.varArgs = false;
sym = findPolymorphicSignatureInstance(env,
- site, name, null, argtypes);
- }
- else {
- //if nothing is found return the 'first' error
- MethodResolutionPhase errPhase =
- firstErroneousResolutionPhase();
- sym = access(methodResolutionCache.get(errPhase),
- pos, location, site, name, true, argtypes, typeargtypes);
- env.info.varArgs = errPhase.isVarargsRequired;
- }
- } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
- //non-instantiated polymorphic signature - synthesize new method symbol
- env.info.varArgs = false;
- sym = findPolymorphicSignatureInstance(env,
- site, name, (MethodSymbol)sym, argtypes);
- }
- return sym;
+ site, name, (MethodSymbol)sym, argtypes);
+ }
+ return sym;
+ }
+ finally {
+ currentResolutionContext = prevResolutionContext;
+ }
}
/** Find or create an implicit method of exactly the given type (after erasure).
@@ -1638,25 +1734,32 @@ public class Resolve {
Type site,
List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = startResolution();
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentStep = steps.head;
- sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- env.info.varArgs = steps.head.isVarargsRequired());
- methodResolutionCache.put(steps.head, sym);
- steps = steps.tail;
- }
- if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
- MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
- sym = access(methodResolutionCache.get(errPhase),
- pos, site, names.init, true, argtypes, typeargtypes);
- env.info.varArgs = errPhase.isVarargsRequired();
- }
- return sym;
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ currentResolutionContext = new MethodResolutionContext();
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ currentResolutionContext.step = steps.head;
+ sym = findConstructor(pos, env, site, argtypes, typeargtypes,
+ steps.head.isBoxingRequired(),
+ env.info.varArgs = steps.head.isVarargsRequired());
+ currentResolutionContext.resolutionCache.put(steps.head, sym);
+ steps = steps.tail;
+ }
+ if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+ MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
+ sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+ pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired();
+ }
+ return sym;
+ }
+ finally {
+ currentResolutionContext = prevResolutionContext;
+ }
}
/** Resolve constructor using diamond inference.
@@ -1674,38 +1777,45 @@ public class Resolve {
Type site,
List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = startResolution();
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentStep = steps.head;
- sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- env.info.varArgs = steps.head.isVarargsRequired());
- methodResolutionCache.put(steps.head, sym);
- steps = steps.tail;
- }
- if (sym.kind >= AMBIGUOUS) {
- final JCDiagnostic details = sym.kind == WRONG_MTH ?
- ((InapplicableSymbolError)sym).explanation :
- null;
- Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
- Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
- String key = details == null ?
- "cant.apply.diamond" :
- "cant.apply.diamond.1";
- return diags.create(dkind, log.currentSource(), pos, key,
- diags.fragment("diamond", site.tsym), details);
- }
- };
- MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
- sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
- env.info.varArgs = errPhase.isVarargsRequired();
- }
- return sym;
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ currentResolutionContext = new MethodResolutionContext();
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ currentResolutionContext.step = steps.head;
+ sym = findConstructor(pos, env, site, argtypes, typeargtypes,
+ steps.head.isBoxingRequired(),
+ env.info.varArgs = steps.head.isVarargsRequired());
+ currentResolutionContext.resolutionCache.put(steps.head, sym);
+ steps = steps.tail;
+ }
+ if (sym.kind >= AMBIGUOUS) {
+ final JCDiagnostic details = sym.kind == WRONG_MTH ?
+ ((InapplicableSymbolError)sym).explanation :
+ null;
+ Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
+ Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ String key = details == null ?
+ "cant.apply.diamond" :
+ "cant.apply.diamond.1";
+ return diags.create(dkind, log.currentSource(), pos, key,
+ diags.fragment("diamond", site.tsym), details);
+ }
+ };
+ MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
+ sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired();
+ }
+ return sym;
+ }
+ finally {
+ currentResolutionContext = prevResolutionContext;
+ }
}
/** Resolve constructor.
@@ -1724,6 +1834,25 @@ public class Resolve {
List<Type> typeargtypes,
boolean allowBoxing,
boolean useVarargs) {
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ currentResolutionContext = new MethodResolutionContext();
+ Symbol sym = findConstructor(pos, env, site,
+ argtypes,
+ typeargtypes, allowBoxing,
+ useVarargs);
+ return sym;
+ }
+ finally {
+ currentResolutionContext = prevResolutionContext;
+ }
+ }
+
+ Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
+ Type site, List<Type> argtypes,
+ List<Type> typeargtypes,
+ boolean allowBoxing,
+ boolean useVarargs) {
Symbol sym = findMethod(env, site,
names.init, argtypes,
typeargtypes, allowBoxing,
@@ -1758,14 +1887,21 @@ public class Resolve {
*/
Symbol resolveOperator(DiagnosticPosition pos, int optag,
Env<AttrContext> env, List<Type> argtypes) {
- Name name = treeinfo.operatorName(optag);
- Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
- null, false, false, true);
- if (boxingEnabled && sym.kind >= WRONG_MTHS)
- sym = findMethod(env, syms.predefClass.type, name, argtypes,
- null, true, false, true);
- return access(sym, pos, env.enclClass.sym.type, name,
- false, argtypes, null);
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ currentResolutionContext = new MethodResolutionContext();
+ Name name = treeinfo.operatorName(optag);
+ Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
+ null, false, false, true);
+ if (boxingEnabled && sym.kind >= WRONG_MTHS)
+ sym = findMethod(env, syms.predefClass.type, name, argtypes,
+ null, true, false, true);
+ return access(sym, pos, env.enclClass.sym.type, name,
+ false, argtypes, null);
+ }
+ finally {
+ currentResolutionContext = prevResolutionContext;
+ }
}
/** Resolve operator.
@@ -2045,12 +2181,6 @@ public class Resolve {
if (name == names.error)
return null;
- if (name == names.empty &&
- !types.isFunctionType(site)) {
- return diags.create(dkind, log.currentSource(), pos,
- "lambda.call.non.func.type", site);
- }
-
if (isOperator(name)) {
boolean isUnaryOp = argtypes.size() == 1;
String key = argtypes.size() == 1 ?
@@ -2173,13 +2303,6 @@ public class Resolve {
Type second = !isUnaryOp ? argtypes.tail.head : null;
return diags.create(dkind, log.currentSource(), pos,
key, name, first, second);
- }
- else if (types.isFunctionType(site) &&
- name == names.empty) {
- return diags.create(dkind, log.currentSource(), pos,
- "cant.apply.lambda",
- methodArguments(site.getParameterTypes()),
- methodArguments(argtypes));
}
else {
Symbol ws = sym.asMemberOf(site, types);
@@ -2249,11 +2372,16 @@ public class Resolve {
return details.reverse();
}
- Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) {
- Candidate c = new Candidate(currentStep, sym, details);
+ Symbol addCandidate(Symbol sym, JCDiagnostic details) {
+ Candidate c = new Candidate(currentResolutionContext.step, sym, details);
if (c.isValid() && !candidates.contains(c))
candidates = candidates.append(c);
return this;
+ }
+
+ Symbol addInitialCandidate() {
+ return addCandidate(currentResolutionContext.wrongMethod.sym,
+ currentResolutionContext.wrongMethod.explanation);
}
void clear() {
@@ -2467,24 +2595,41 @@ public class Resolve {
}
}
- private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
- new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
-
final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
- private MethodResolutionPhase currentStep = null;
-
- private MethodResolutionPhase firstErroneousResolutionPhase() {
- MethodResolutionPhase bestSoFar = BASIC;
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= WRONG_MTHS) {
- sym = methodResolutionCache.get(steps.head);
- bestSoFar = steps.head;
- steps = steps.tail;
- }
- return bestSoFar;
- }
+ /**
+ * A resolution context is used to keep track of intermediate results of
+ * overload resolution, such as list of method that are not applicable
+ * (used to generate more precise diagnostics) and so on. Resolution contexts
+ * can be nested, in case overload resolution trigers deferred attribution
+ * (i.e. of the body of a lambda expression). This means that when overload
+ * resolution begins, a new context should be created and prepended to the
+ * list of pending resolution contexts.
+ */
+ class MethodResolutionContext {
+
+ final InapplicableSymbolError wrongMethod = new InapplicableSymbolError(syms.errSymbol);
+ final InapplicableSymbolsError wrongMethods = new InapplicableSymbolsError(syms.errSymbol);
+
+ private Map<MethodResolutionPhase, Symbol> resolutionCache =
+ new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
+
+ private MethodResolutionPhase step = null;
+
+ private MethodResolutionPhase firstErroneousResolutionPhase() {
+ MethodResolutionPhase bestSoFar = BASIC;
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= WRONG_MTHS) {
+ sym = resolutionCache.get(steps.head);
+ bestSoFar = steps.head;
+ steps = steps.tail;
+ }
+ return bestSoFar;
+ }
+ }
+
+ MethodResolutionContext currentResolutionContext = null;
}
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri May 20 17:19:01 2011 +0100
@@ -123,7 +123,7 @@ public class TransTypes extends TreeTran
JCExpression coerce(JCExpression tree, Type target) {
Type btarget = target.baseType();
if (tree.type.isPrimitive() == target.isPrimitive()) {
- return types.isAssignableNoCheck(tree.type, btarget, Warner.noWarnings)
+ return types.isAssignable(tree.type, btarget, Warner.noWarnings)
? tree
: cast(tree, btarget);
}
@@ -529,6 +529,7 @@ public class TransTypes extends TreeTran
try {
currentMethod = tree.sym;
pt = null;
+ tree.type = erasure(tree.type);
super.visitLambda(tree);
}
finally {
@@ -764,7 +765,7 @@ public class TransTypes extends TreeTran
public void visitReference(JCMemberReference tree) {
tree.expr = translate(tree.expr, null);
- tree.type = types.erasure(tree.type);
+ tree.type = syms.methodHandleType;
result = tree;
}
@@ -779,11 +780,6 @@ public class TransTypes extends TreeTran
public void visitTypeApply(JCTypeApply tree) {
JCTree clazz = translate(tree.clazz, null);
result = clazz;
- }
-
- @Override
- public void visitFunctionType(JCFunctionType that) {
- result = make.QualIdent(syms.methodHandleType.tsym).setType(syms.methodHandleType).setPos(that.pos);
}
/**************************************************************************
--- a/src/share/classes/com/sun/tools/javac/comp/Unlambda.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Unlambda.java Fri May 20 17:19:01 2011 +0100
@@ -93,30 +93,13 @@ public class Unlambda extends TreeTransl
@Override
public void visitLambda(JCLambda tree) {
- if (types.isFunctionType(tree.targetType)) {
- //lambda expression whose target is a function type are still
- //translated in Lower
- result = tree;
- return;
- }
-
- Type type = tree.targetType;
-
//create new anon class definition implementing SAM method
// class <anon> extends SAMClass { ... }
ClassSymbol samClassSym = (ClassSymbol)tree.sym.owner;
-
- //add this
-// VarSymbol thisSym = new VarSymbol(Flags.FINAL | Flags.HASINIT,
-// names._this,
-// samClassSym.type,
-// samClassSym);
-// samClassSym.members().enter(thisSym);
-
- Type superType = types.isFunctionType(tree.targetType) ?
- syms.methodHandleType :
- tree.targetType;
+ Type targetType = ((ForAll)tree.type).qtype;
+
+ Type superType = targetType;
if (superType.isInterface()) {
((ClassType)samClassSym.type).supertype_field = syms.objectType;
@@ -130,8 +113,8 @@ public class Unlambda extends TreeTransl
make.Modifiers(samClassSym.flags_field),
names.empty,
List.<JCTypeParameter>nil(),
- type.isInterface() ? make.QualIdent(syms.objectType.tsym).setType(syms.objectType) : make.QualIdent(type.tsym).setType(type),
- type.isInterface() ? List.of(make.QualIdent(type.tsym).setType(type)) : List.<JCExpression>nil(),
+ targetType.isInterface() ? make.QualIdent(syms.objectType.tsym).setType(syms.objectType) : make.QualIdent(targetType.tsym).setType(targetType),
+ targetType.isInterface() ? List.of(make.QualIdent(targetType.tsym).setType(targetType)) : List.<JCExpression>nil(),
null);
samClassDecl.sym = samClassSym;
@@ -157,7 +140,7 @@ public class Unlambda extends TreeTransl
JCNewClass newClass = make.NewClass(null,
List.<JCExpression>nil(),
- make.QualIdent(type.tsym),
+ make.QualIdent(targetType.tsym),
List.<JCExpression>nil(),
samClassDecl);
newClass.constructor = samConstrDecl.sym;
@@ -204,7 +187,11 @@ public class Unlambda extends TreeTransl
JCBlock makeLambdaBody(JCLambda tree) {
JCReturn defaultRet = null;
- if ((tree.sym.flags() & Flags.NEEDS_RETURN) != 0) {
+ if (tree.canCompleteNormally &&
+ types.isSameType(tree.sym.type.getReturnType(), types.boxedClass(syms.voidType).type)) {
+ //there's no return statement and the lambda (possibly inferred)
+ //return type is java.lang.Void; sets the NEEDS_RETURN flag in
+ //order to tell code generation to emit a synthetic return statement
defaultRet = make.Return(make.Literal(TypeTags.BOT, null).setType(syms.botType));
}
JCBlock body = null;
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri May 20 17:19:01 2011 +0100
@@ -686,9 +686,12 @@ public class ClassReader implements Comp
syms.methodClass);
case '<':
typevars = typevars.dup(currentOwner);
- Type poly = new ForAll(sigToTypeParams(), sigToType());
+ List<Type> tvars = sigToTypeParams();
+ Type mt = sigToType();
+ Assert.check(mt.tag == METHOD);
+ ((MethodType)mt).typeargs = tvars;
typevars = typevars.leave();
- return poly;
+ return mt;
default:
throw badClassFile("bad.signature",
Convert.utf2string(signature, sigp, 10));
@@ -982,7 +985,7 @@ public class ClassReader implements Comp
for (int j = 0; j < nexceptions; j++)
thrown = thrown.prepend(readClassSymbol(nextChar()).type);
if (sym.type.getThrownTypes().isEmpty())
- sym.type.asMethodType(types).thrown = thrown.reverse();
+ sym.type.asMethodType().thrown = thrown.reverse();
}
},
@@ -1081,7 +1084,7 @@ public class ClassReader implements Comp
sym.type = readType(nextChar());
//- System.err.println(" # " + sym.type);
if (sym.kind == MTH && sym.type.getThrownTypes().isEmpty())
- sym.type.asMethodType(types).thrown = thrown;
+ sym.type.asMethodType().thrown = thrown;
}
}
@@ -1242,10 +1245,10 @@ public class ClassReader implements Comp
if (nt == null)
return null;
- MethodType type = nt.type.asMethodType(types);
+ MethodType type = nt.type.asMethodType();
for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next())
- if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(types), type))
+ if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type))
return (MethodSymbol)e.sym;
if (nt.name != names.init)
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri May 20 17:19:01 2011 +0100
@@ -307,6 +307,9 @@ public class ClassWriter extends ClassFi
break;
case METHOD:
MethodType mt = (MethodType)type;
+ if (mt.isParameterized()) {
+ assembleParamsSig(mt.getTypeArguments());
+ }
sigbuf.appendByte('(');
assembleSig(mt.argtypes);
sigbuf.appendByte(')');
@@ -341,11 +344,6 @@ public class ClassWriter extends ClassFi
sigbuf.appendByte('T');
sigbuf.appendName(type.tsym.name);
sigbuf.appendByte(';');
- break;
- case FORALL:
- ForAll ft = (ForAll)type;
- assembleParamsSig(ft.tvars);
- assembleSig(ft.qtype);
break;
case DISJOINT:
DisjunctiveType dt = (DisjunctiveType)type;
--- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Fri May 20 17:19:01 2011 +0100
@@ -97,7 +97,7 @@ public class JavacTypes implements javax
public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
validateTypeNotIn(t1, EXEC_OR_PKG);
validateTypeNotIn(t2, EXEC_OR_PKG);
- return types.isAssignableNoCheck((Type) t1, (Type) t2, Warner.noWarnings);
+ return types.isAssignable((Type) t1, (Type) t2, Warner.noWarnings);
}
public boolean contains(TypeMirror t1, TypeMirror t2) {
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri May 20 17:19:01 2011 +0100
@@ -104,8 +104,6 @@ public class JavacParser implements Pars
this.allowDefenderMethods = source.allowDefenderMethods();
this.allowThrowTypeParameters = source.allowThrowTypeParameters();
this.allowLambda = source.allowLambda();
- this.allowFunctionTypes = source.allowLambda() && false && //disabled!!!
- fac.options.get("allowFunctionTypes") != null;
this.keepDocComments = keepDocComments;
if (keepDocComments)
docComments = new HashMap<JCTree,String>();
@@ -161,10 +159,6 @@ public class JavacParser implements Pars
/** Switch: should we recognize lambda expressions?
*/
boolean allowLambda;
-
- /** Switch: should we recognize function types?
- */
- boolean allowFunctionTypes;
/** Switch: should we recognize throw type-parameters?
*/
@@ -1347,26 +1341,6 @@ public class JavacParser implements Pars
return toP(F.at(pos).Lambda(args, expr));
}
- JCExpression functionType() {
- mode = TYPE;
- checkFunctionTypes();
- JCExpression retType = parseType();
- accept(LPAREN);
- List<JCExpression> args = (S.token() == RPAREN) ?
- List.<JCExpression>nil() :
- typeList();
- accept(RPAREN);
- List<JCExpression> thrown = List.nil();
- if (S.token() == LPAREN &&
- S.peekToken() == THROWS) {
- S.nextToken();
- accept(THROWS);
- thrown = qualidentList();
- accept(RPAREN);
- }
- return toP(F.at(S.pos()).FunctionType(args, retType, thrown));
- }
-
/** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
* | MemberReferenceSuffix
*/
@@ -3430,12 +3404,6 @@ public class JavacParser implements Pars
allowLambda = true;
}
}
- void checkFunctionTypes() {
- if (!allowFunctionTypes) {
- log.error(S.pos(), "func.types.not.supported.in.source", source.name);
- allowFunctionTypes = true;
- }
- }
void checkThrowTypeParameters() {
if (!allowThrowTypeParameters) {
log.error(S.pos(), "throw.typarams.not.supported.in.source", source.name);
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri May 20 17:19:01 2011 +0100
@@ -162,18 +162,8 @@ compiler.err.cant.apply.symbols=\
compiler.err.cant.apply.symbols=\
no suitable {0} found for {1}({2})
-compiler.err.cant.apply.lambda=\
- lambda expression cannot be applied to given types\n\
- required: {0}\n\
- found: {1}
-
-compiler.warn.cyclic.lambda.inference.throws=\
- thrown types cannot be inferred from lambda body because of cyclic inference\n\
- explicit type required for the following parameter: {0}
-
-compiler.warn.cyclic.lambda.inference.throws.1=\
- thrown types cannot be inferred from lambda body because of cyclic inference\n\
- explicit types required for the following parameters: {0}
+compiler.misc.cyclic.lambda.inference=\
+ cyclic inference - try specifying lambda parameter types
compiler.err.invalid.target.type.for.lambda.conv=\
invalid target type {0} for lambda conversion
@@ -185,9 +175,6 @@ compiler.misc.no.target.method.for.lambd
compiler.misc.no.target.method.for.lambda.conv=\
no target method for lambda conversion found in {1} {2}
-compiler.misc.incompatible.target.in.lambda.conv=\
- target method {0} in {1} {2} is not suitable for lambda conversion
-
compiler.misc.incompatible.targets.in.lambda.conv=\
no suitable target method for lambda conversion found in {1} {2}
@@ -211,6 +198,9 @@ compiler.misc.target.not.accessible=\
compiler.misc.multiple.targets.for.lambda.conv=\
the target type of a lambda conversion has multiple non-overriding abstract methods
+
+compiler.misc.no.suitable.sam.inst=\
+ no instance of type {0} exists so that lambda expression can be type-checked
# 0: symbol
compiler.err.cant.assign.val.to.final.var=\
@@ -620,10 +610,14 @@ compiler.err.neither.conditional.subtype
second operand: {0}\n\
third operand : {1}
-compiler.err.incompatibles.ret.types.in.lambda=\
-incompatible return types in lambda expression: neither is a subtype of the other\n\
-expected type: {0}\n\
-found : {1}
+compiler.misc.infer.incompatible.ret.types.in.lambda=\
+ incompatible return type {0} in lambda expression
+
+compiler.misc.infer.incompatible.thrown.types.in.lambda=\
+ incompatible thrown types {0} in lambda expression
+
+compiler.misc.infer.incompatible.arg.types.in.lambda=\
+ incompatible parameter types in lambda expression
compiler.err.new.not.allowed.in.annotation=\
''new'' not allowed in an annotation
@@ -1719,6 +1713,13 @@ compiler.misc.infer.no.conforming.assign
no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to formal parameter type {2}\n\
({3})
+compiler.misc.infer.varargs.argument.mismatch=\
+ no instance(s) of type variable(s) {0} exists so that argument type {1} does not conform to vararg element type {2}
+
+compiler.misc.infer.varargs.argument.mismatch.1=\
+ no instance(s) of type variable(s) {0} exists so that argument type {1} does not conform to vararg element type {2}\n\
+ ({3})
+
compiler.misc.infer.arg.length.mismatch=\
cannot instantiate from arguments because actual and formal argument lists differ in length
@@ -1822,10 +1823,6 @@ compiler.err.cant.resolve.location.args.
symbol: {0} <{2}>{1}({3})\n\
location: {4}
-
-compiler.err.lambda.call.non.func.type=\
- lambda invocation syntax cannot be used on non-lambda type {0}
-
##a location subdiagnostic is composed as follows:
## The first argument {0} is the location "kindname" (e.g. 'constructor', 'field', etc.)
## The second argument {1} is the location name
@@ -2060,10 +2057,6 @@ compiler.err.lambda.not.supported.in.sou
lambda expressions are not supported in -source {0}\n\
(use -source 8 or higher to enable lambda expressions)
-compiler.err.func.types.not.supported.in.source=\
- function types are not supported in -source {0}\n\
- (use -source 8 or higher and -XDallowFunctionTypes to enable function types)
-
compiler.err.defender.methods.not.supported.in.source=\
defender methods are not supported in -source {0}\n\
(use -source 8 or higher to enable defender methods)
@@ -2086,6 +2079,9 @@ compiler.misc.type.null=\
compiler.misc.type.lambda=\
<lambda>
+
+compiler.misc.type.mref=\
+ <method-ref>
# X#n (where n is an int id) is disambiguated tvar name
# 0: name, 1: number
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java Fri May 20 17:19:01 2011 +0100
@@ -249,13 +249,9 @@ public abstract class JCTree implements
*/
public static final int TYPEDISJUNCTION = TYPEAPPLY + 1;
- /** Function types, of type FunctionType.
- */
- public static final int TYPEFUNCTION = TYPEDISJUNCTION + 1;
-
/** Formal type parameters, of type TypeParameter.
*/
- public static final int TYPEPARAMETER = TYPEFUNCTION + 1;
+ public static final int TYPEPARAMETER = TYPEDISJUNCTION + 1;
/** Type argument.
*/
@@ -1466,7 +1462,8 @@ public abstract class JCTree implements
public List<JCVariableDecl> params;
public JCTree body;
public Symbol sym;
- public Type targetType;
+ public boolean canCompleteNormally = true;
+ public List<Type> inferredThrownTypes;
private boolean needsParameterInference = false;
@@ -2029,49 +2026,6 @@ public abstract class JCTree implements
@Override
public int getTag() {
return TYPEDISJUNCTION;
- }
- }
-
- /** A function type.
- * @param argumentTypes the types of the function arguments.
- * @param resultType the type of the result of the function.
- * @param thrown the list of checked excpetions thrown by the function.
- */
- public static class JCFunctionType extends JCExpression implements FunctionTypeTree {
- public List<JCExpression> argumentTypes;
- public JCExpression resultType;
- public List<JCExpression> thrown;
-
- public JCFunctionType(List<JCExpression> argumentTypes,
- JCExpression resultType,
- List<JCExpression> thrown) {
- this.argumentTypes = argumentTypes;
- this.resultType = resultType;
- this.thrown = thrown;
- }
- @Override
- public int getTag() {
- return TYPEFUNCTION;
- }
- @Override
- public void accept(Visitor v) {
- v.visitFunctionType(this);
- }
- @Override
- public <R, D> R accept(TreeVisitor<R, D> v, D d) {
- return v.visitFunctionType(this, d);
- }
- public java.util.List<? extends Tree> getArgumentTypes() {
- return argumentTypes;
- }
- public Tree getResultType() {
- return resultType;
- }
- public java.util.List<? extends ExpressionTree> getThrownTypes() {
- return thrown;
- }
- public Kind getKind() {
- return Kind.FUNCTION_TYPE;
}
}
@@ -2400,7 +2354,6 @@ public abstract class JCTree implements
public void visitTypeArray(JCArrayTypeTree that) { visitTree(that); }
public void visitTypeApply(JCTypeApply that) { visitTree(that); }
public void visitTypeDisjunction(JCTypeDisjunction that) { visitTree(that); }
- public void visitFunctionType(JCFunctionType that) { visitTree(that); }
public void visitTypeParameter(JCTypeParameter that) { visitTree(that); }
public void visitWildcard(JCWildcard that) { visitTree(that); }
public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); }
--- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java Fri May 20 17:19:01 2011 +0100
@@ -1239,22 +1239,6 @@ public class Pretty extends JCTree.Visit
}
}
- public void visitFunctionType(JCFunctionType tree) {
- try {
- print("#");
- print("(");
- printExprs(tree.argumentTypes);
- print(")");
- if (tree.thrown.nonEmpty()) {
- print("(");
- printExprs(tree.thrown);
- print(")");
- }
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
public void visitTypeParameter(JCTypeParameter tree) {
try {
print(tree.name);
--- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Fri May 20 17:19:01 2011 +0100
@@ -355,14 +355,6 @@ public class TreeCopier<P> implements Tr
JCTypeDisjunction t = (JCTypeDisjunction) node;
List<JCExpression> components = copy(t.alternatives, p);
return M.at(t.pos).TypeDisjunction(components);
- }
-
- public JCTree visitFunctionType(FunctionTypeTree node, P p) {
- JCFunctionType t = (JCFunctionType) node;
- List<JCExpression> argtypes = copy(t.argumentTypes, p);
- JCExpression restype = copy(t.resultType, p);
- List<JCExpression> thrown = copy(t.thrown, p);
- return M.at(t.pos).FunctionType(argtypes, restype, thrown);
}
public JCTree visitArrayType(ArrayTypeTree node, P p) {
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri May 20 17:19:01 2011 +0100
@@ -451,12 +451,6 @@ public class TreeMaker implements JCTree
public JCTypeDisjunction TypeDisjunction(List<JCExpression> components) {
JCTypeDisjunction tree = new JCTypeDisjunction(components);
- tree.pos = pos;
- return tree;
- }
-
- public JCFunctionType FunctionType(List<JCExpression> argtypes, JCExpression restype, List<JCExpression> thrown) {
- JCFunctionType tree = new JCFunctionType(argtypes, restype, thrown);
tree.pos = pos;
return tree;
}
--- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Fri May 20 17:19:01 2011 +0100
@@ -276,12 +276,6 @@ public class TreeScanner extends Visitor
scan(tree.elemtype);
}
- public void visitFunctionType(JCFunctionType tree) {
- scan(tree.argumentTypes);
- scan(tree.resultType);
- scan(tree.thrown);
- }
-
public void visitTypeApply(JCTypeApply tree) {
scan(tree.clazz);
scan(tree.arguments);
--- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Fri May 20 17:19:01 2011 +0100
@@ -379,13 +379,6 @@ public class TreeTranslator extends JCTr
result = tree;
}
- public void visitFunctionType(JCFunctionType tree) {
- tree.argumentTypes = translate(tree.argumentTypes);
- tree.resultType = translate(tree.resultType);
- tree.thrown = translate(tree.thrown);
- result = tree;
- }
-
public void visitTypeParameter(JCTypeParameter tree) {
tree.bounds = translate(tree.bounds);
result = tree;
--- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Thu May 05 15:47:56 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Fri May 20 17:19:01 2011 +0100
@@ -347,23 +347,21 @@ public class RichDiagnosticFormatter ext
return s;
}
+ @SuppressWarnings("fallthrough")
@Override
public String visitForAll(ForAll t, Locale locale) {
- if (types.isFunctionType(t)) {
- return t.qtype.containsAny(t.tvars) ?
- localize(locale, "compiler.misc.type.lambda") :
- visit(t.qtype, locale);
- }
- else {
- return super.visitForAll(t, locale);
- }
- }
-
- @Override
- public String visitFunctionType(FunctionType t, Locale locale) {
- return (t.getReturnType().isErroneous()) ?
- localize(locale, "compiler.misc.type.lambda") :
- super.visitFunctionType(t, locale);
+ switch (t.getPolyTag()) {
+ case POLY_LAMBDA:
+ case POLY_REFERENCE:
+ String key = t.getPolyTag() == POLY_LAMBDA ?
+ "compiler.misc.type.lambda" :
+ "compiler.misc.type.mref";
+ return t.qtype.tag == NONE ?
+ localize(locale, key) :
+ visit(t.qtype, locale);
+ default:
+ return super.visitForAll(t, locale);
+ }
}
@Override
@@ -415,10 +413,7 @@ public class RichDiagnosticFormatter ext
@Override
public String visitTypeVar(TypeVar t, Locale locale) {
- if ((t.tsym.flags() & LAMBDA) != 0) {
- return "?";
- }
- else if (unique(t) ||
+ if (unique(t) ||
!getConfiguration().isEnabled(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES)) {
return t.toString();
}
@@ -456,7 +451,7 @@ public class RichDiagnosticFormatter ext
? ownerName
: s.name.toString();
if (s.type != null) {
- if (s.type.tag == FORALL) {
+ if (s.type.isParameterized()) {
ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
}
ms += "(" + printMethodArgs(
@@ -489,24 +484,16 @@ public class RichDiagnosticFormatter ext
}
@Override
- public Void visitForAll(ForAll t, Void ignored) {
- visit(t.tvars);
+ public Void visitForAll(ForAll t, Void ignored) {
visit(t.qtype);
return null;
}
@Override
public Void visitMethodType(MethodType t, Void ignored) {
+ visit(t.typeargs);
visit(t.argtypes);
visit(t.restype);
- return null;
- }
-
- @Override
- public Void visitFunctionType(FunctionType t, Void ignored) {
- visit(t.argtypes);
- visit(t.restype);
- visit(t.thrown);
return null;
}
@@ -581,8 +568,7 @@ public class RichDiagnosticFormatter ext
@Override
public Void visitTypeVar(TypeVar t, Void ignored) {
- if ((t.tsym.flags() & LAMBDA) == 0 &&
- indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
+ if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
//access the bound type and skip error types
Type bound = t.bound;
while ((bound instanceof ErrorType))
--- a/test/tools/javac/Diagnostics/6862608/T6862608a.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/Diagnostics/6862608/T6862608a.out Fri May 20 17:19:01 2011 +0100
@@ -1,3 +1,3 @@ T6862608a.java:19:41: compiler.err.prob.
-T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), <T>java.util.Comparator<T>, java.util.Comparator<java.lang.String>
+T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), java.util.Comparator<T>, java.util.Comparator<java.lang.String>
- compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, <T>compound(java.lang.Iterable<? extends java.util.Comparator<? super T>>))}
1 error
--- a/test/tools/javac/diags/examples.not-yet.txt Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/diags/examples.not-yet.txt Fri May 20 17:19:01 2011 +0100
@@ -40,6 +40,7 @@ compiler.err.type.var.more.than.once
compiler.err.type.var.more.than.once # UNUSED
compiler.err.type.var.more.than.once.in.result # UNUSED
compiler.err.undetermined.type
+compiler.err.undetermined.type.1
compiler.err.unexpected.type
compiler.err.unknown.enum.constant # in bad class file
compiler.err.unsupported.cross.fp.lit # Scanner: host system dependent
@@ -73,6 +74,7 @@ compiler.misc.kindname.type.variable.bou
compiler.misc.kindname.type.variable.bound
compiler.misc.kindname.value
compiler.misc.no.unique.minimal.instance.exists
+compiler.misc.no.unique.maximal.instance.exists
compiler.misc.resume.abort # prompt for a response
compiler.misc.source.unavailable # DiagnosticSource
compiler.misc.token.bad-symbol
@@ -113,18 +115,15 @@ compiler.warn.unchecked.cast.to.type
compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type
compiler.warn.unexpected.archive.file # Paths: zip file with unknown extn
compiler.err.bad.defender.method.body #LAMBDA
+compiler.err.bad.lambda.token #LAMBDA
compiler.err.break.inside.lambda #LAMBDA
-compiler.err.cant.apply.lambda #LAMBDA
compiler.err.cant.ref.non.effectively.final.var #LAMBDA
compiler.err.cant.ret.void.expr #LAMBDA
compiler.err.cont.inside.lambda #LAMBDA
compiler.err.defender.methods.not.supported.in.source #LAMBDA
compiler.err.disjoint.type.not.allowed.here #LAMBDA
-compiler.err.func.types.not.supported.in.source #LAMBDA
-compiler.err.incompatibles.ret.types.in.lambda #LAMBDA
compiler.err.invalid.target.type.for.lambda.conv #LAMBDA
compiler.err.invalid.target.type.for.lambda.conv.1 #LAMBDA
-compiler.err.lambda.call.non.func.type #LAMBDA
compiler.err.lambda.not.supported.in.source #LAMBDA
compiler.err.method.references.not.supported.in.source #LAMBDA
compiler.err.throw.typarams.not.supported.in.source #LAMBDA
@@ -135,13 +134,16 @@ compiler.err.unexpected.lambda
compiler.err.unexpected.lambda #LAMBDA
compiler.err.unexpected.meth.reference #LAMBDA
compiler.misc.bad.defender.method #LAMBDA
+compiler.misc.cyclic.lambda.inference #LAMBDA
compiler.misc.disjunctive.type #LAMBDA
compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope #LAMBDA
-compiler.misc.incompatible.target.in.lambda.conv #LAMBDA
compiler.misc.incompatible.targets.in.lambda.conv #LAMBDA
+compiler.misc.infer.varargs.argument.mismatch #LAMBDA
+compiler.misc.infer.varargs.argument.mismatch.1 #LAMBDA
compiler.misc.invalid.generic.target.for.lambda.conv #LAMBDA
compiler.misc.lambda #LAMBDA
compiler.misc.multiple.targets.for.lambda.conv #LAMBDA
+compiler.misc.no.suitable.sam.inst #LAMBDA
compiler.misc.no.target.method.for.lambda.conv #LAMBDA
compiler.misc.target.for.lambda.conv.must.be.abstract #LAMBDA
compiler.misc.target.for.lambda.conv.must.be.interface #LAMBDA
@@ -157,9 +159,10 @@ compiler.misc.no.conforming.assignment.e
compiler.misc.no.conforming.assignment.exists.1 #LAMBDA
compiler.misc.varargs.argument.mismatch.1 #LAMBDA
compiler.misc.type.lambda #LAMBDA
+compiler.misc.type.mref #LAMBDA
compiler.misc.bad.enclosing.method #LAMBDA
+compiler.misc.infer.incompatible.ret.types.in.lambda #LAMBDA
+compiler.misc.infer.incompatible.arg.types.in.lambda #LAMBDA
+compiler.misc.infer.incompatible.thrown.types.in.lambda #LAMBDA
compiler.note.potential.lambda.found #LAMBDA
-compiler.warn.cyclic.lambda.inference.throws #LAMBDA
-compiler.warn.cyclic.lambda.inference.throws.1 #LAMBDA
-compiler.err.bad.lambda.token #LAMBDA
compiler.warn.redundant.extension.keyword #LAMBDA
--- a/test/tools/javac/generics/inference/6315770/T6315770.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/generics/inference/6315770/T6315770.out Fri May 20 17:19:01 2011 +0100
@@ -1,3 +1,3 @@ T6315770.java:16:42: compiler.err.undete
-T6315770.java:16:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
+T6315770.java:16:42: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)), T6315770<T>, T6315770<? extends java.lang.String>
+T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), T6315770<T>, T6315770<? super java.lang.String>
2 errors
--- a/test/tools/javac/generics/inference/6638712/T6638712a.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/generics/inference/6638712/T6638712a.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ T6638712a.java:16:41: compiler.err.prob.
-T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), <T>java.util.Comparator<T>, java.util.Comparator<java.lang.String>
+T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), java.util.Comparator<T>, java.util.Comparator<java.lang.String>
1 error
--- a/test/tools/javac/generics/inference/6638712/T6638712b.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/generics/inference/6638712/T6638712b.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ T6638712b.java:14:21: compiler.err.prob.
-T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)), <T>T, java.lang.String
+T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: I,T, T, java.lang.String)), T, java.lang.String
1 error
--- a/test/tools/javac/generics/inference/6638712/T6638712e.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/generics/inference/6638712/T6638712e.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ T6638712e.java:17:27: compiler.err.prob.
-T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)), <X>T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>
+T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)), T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>
1 error
--- a/test/tools/javac/lambda/BadConv03.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/BadConv03.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ BadConv03.java:40:11: compiler.err.inval
-BadConv03.java:40:11: compiler.err.invalid.target.type.for.lambda.conv.1: BadConv03.B, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, BadConv03.B)
+BadConv03.java:40:11: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, BadConv03.B)), compiler.misc.type.lambda, BadConv03.B
1 error
--- a/test/tools/javac/lambda/BadLambdaPos.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/BadLambdaPos.out Fri May 20 17:19:01 2011 +0100
@@ -1,11 +1,9 @@ BadLambdaPos.java:39:14: compiler.err.un
BadLambdaPos.java:39:14: compiler.err.unexpected.lambda
BadLambdaPos.java:39:30: compiler.err.unexpected.lambda
-BadLambdaPos.java:39:28: compiler.err.operator.cant.be.applied.1: +, #void(int), #void(int)
BadLambdaPos.java:40:14: compiler.err.unexpected.lambda
BadLambdaPos.java:44:18: compiler.err.unexpected.lambda
BadLambdaPos.java:44:34: compiler.err.unexpected.lambda
-BadLambdaPos.java:44:32: compiler.err.operator.cant.be.applied.1: +, #void(int), #void(int)
BadLambdaPos.java:45:21: compiler.err.unexpected.lambda
-BadLambdaPos.java:49:22: compiler.err.invalid.target.type.for.lambda.conv.1: java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)
-BadLambdaPos.java:50:28: compiler.err.invalid.target.type.for.lambda.conv.1: java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)
-10 errors
+BadLambdaPos.java:49:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+BadLambdaPos.java:50:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+8 errors
--- a/test/tools/javac/lambda/BadReturn.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/BadReturn.out Fri May 20 17:19:01 2011 +0100
@@ -1,3 +1,3 @@ BadReturn.java:42:42: compiler.err.prob.
-BadReturn.java:42:42: compiler.err.prob.found.req: (compiler.misc.incompatible.types), void, java.lang.Comparable<?>
-BadReturn.java:47:45: compiler.err.prob.found.req: (compiler.misc.incompatible.types), void, java.lang.Comparable<?>
+BadReturn.java:42:42: compiler.err.cant.ret.void.expr
+BadReturn.java:47:45: compiler.err.cant.ret.void.expr
2 errors
--- a/test/tools/javac/lambda/BadTargetType.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/BadTargetType.out Fri May 20 17:19:01 2011 +0100
@@ -1,5 +1,5 @@ BadTargetType.java:37:24: compiler.err.i
-BadTargetType.java:37:24: compiler.err.invalid.target.type.for.lambda.conv.1: java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)
-BadTargetType.java:38:17: compiler.err.invalid.target.type.for.lambda.conv.1: java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)
-BadTargetType.java:41:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, java.lang.Object, #void(int), kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: #void(int), java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object))
-BadTargetType.java:42:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, java.lang.Object, #void(int), kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: #void(int), java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object))
+BadTargetType.java:37:24: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+BadTargetType.java:38:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+BadTargetType.java:41:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, java.lang.Object, compiler.misc.type.lambda, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object))
+BadTargetType.java:42:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, java.lang.Object, compiler.misc.type.lambda, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object))
4 errors
--- a/test/tools/javac/lambda/LambdaCapture04.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaCapture04.java Fri May 20 17:19:01 2011 +0100
@@ -23,6 +23,7 @@
/*
* @test
+ * @ignore
* @summary test for capture of non-mutable locals/outer fields in multiple scopes
* @author Maurizio Cimadamore
* @run main LambdaCapture04
--- a/test/tools/javac/lambda/LambdaCapture05.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaCapture05.java Fri May 20 17:19:01 2011 +0100
@@ -23,6 +23,7 @@
/*
* @test
+ * @ignore
* @summary test for capture in nested lambda expressions
* @author Maurizio Cimadamore
* @run main LambdaCapture05
--- a/test/tools/javac/lambda/LambdaConv02.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaConv02.out Fri May 20 17:19:01 2011 +0100
@@ -1,3 +1,3 @@ LambdaConv02.java:42:18: compiler.err.in
-LambdaConv02.java:42:18: compiler.err.invalid.target.type.for.lambda.conv.1: LambdaConv02.SAM, (compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope: null, kindname.class, LambdaConv02.SAM, LambdaConv02)
-LambdaConv02.java:43:9: compiler.err.cant.apply.symbol.1: kindname.method, test1, LambdaConv02.SAM, #void(), kindname.class, LambdaConv02, (compiler.misc.no.conforming.assignment.exists.1: #void(), LambdaConv02.SAM, (compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope: null, kindname.class, LambdaConv02.SAM, LambdaConv02))
+LambdaConv02.java:42:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope: null, kindname.class, LambdaConv02.SAM, LambdaConv02)), compiler.misc.type.lambda, LambdaConv02.SAM
+LambdaConv02.java:43:9: compiler.err.cant.apply.symbol.1: kindname.method, test1, LambdaConv02.SAM, compiler.misc.type.lambda, kindname.class, LambdaConv02, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, LambdaConv02.SAM, (compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope: null, kindname.class, LambdaConv02.SAM, LambdaConv02))
2 errors
--- a/test/tools/javac/lambda/LambdaConv03.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaConv03.java Fri May 20 17:19:01 2011 +0100
@@ -23,6 +23,7 @@
/*
* @test
+ * @ignore
* @summary SAM types and method type inference
* @author Brian Goetz
* @author Maurizio Cimadamore
--- a/test/tools/javac/lambda/LambdaConv09.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaConv09.out Fri May 20 17:19:01 2011 +0100
@@ -1,6 +1,6 @@ LambdaConv09.java:67:19: compiler.err.in
-LambdaConv09.java:67:19: compiler.err.invalid.target.type.for.lambda.conv.1: LambdaConv09.Foo1, (compiler.misc.no.target.method.for.lambda.conv: null, kindname.class, LambdaConv09.Foo1)
-LambdaConv09.java:68:19: compiler.err.invalid.target.type.for.lambda.conv.1: LambdaConv09.Foo2, (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo2)
-LambdaConv09.java:70:19: compiler.err.invalid.target.type.for.lambda.conv.1: LambdaConv09.Bar3, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.class, LambdaConv09.Bar3)
-LambdaConv09.java:71:18: compiler.err.invalid.target.type.for.lambda.conv.1: LambdaConv09.Quux, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.class, LambdaConv09.Quux)
-LambdaConv09.java:72:19: compiler.err.invalid.target.type.for.lambda.conv.1: LambdaConv09.Foo4, (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo4)
+LambdaConv09.java:67:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.class, LambdaConv09.Foo1)), compiler.misc.type.lambda, LambdaConv09.Foo1
+LambdaConv09.java:68:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo2)), compiler.misc.type.lambda, LambdaConv09.Foo2
+LambdaConv09.java:70:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.class, LambdaConv09.Bar3)), compiler.misc.type.lambda, LambdaConv09.Bar3
+LambdaConv09.java:71:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.class, LambdaConv09.Quux)), compiler.misc.type.lambda, LambdaConv09.Quux
+LambdaConv09.java:72:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo4)), compiler.misc.type.lambda, LambdaConv09.Foo4
5 errors
--- a/test/tools/javac/lambda/LambdaConv10.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaConv10.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ LambdaConv10.java:36:44: compiler.err.pr
-LambdaConv10.java:36:44: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.target.in.lambda.conv: call, kindname.interface, LambdaConv10.Method1)), #java.lang.Integer(int)(), LambdaConv10.Method1<java.lang.Integer,java.lang.Integer,>
+LambdaConv10.java:36:44: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.arg.types.in.lambda)), compiler.misc.type.lambda, LambdaConv10.Method1<java.lang.Integer,java.lang.Integer,>
1 error
--- a/test/tools/javac/lambda/LambdaExprNotVoid.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/LambdaExprNotVoid.out Fri May 20 17:19:01 2011 +0100
@@ -1,3 +1,3 @@ LambdaExprNotVoid.java:35:24: compiler.e
-LambdaExprNotVoid.java:35:24: compiler.err.prob.found.req: (compiler.misc.incompatible.types), int, void
-LambdaExprNotVoid.java:36:24: compiler.err.prob.found.req: (compiler.misc.incompatible.types), int, void
+LambdaExprNotVoid.java:35:14: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: int)), compiler.misc.type.lambda, LambdaExpr05.SAM
+LambdaExprNotVoid.java:36:14: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: int)), compiler.misc.type.lambda, LambdaExpr05.SAM
2 errors
--- a/test/tools/javac/lambda/MethodReference04.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/MethodReference04.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ MethodReference04.java:34:16: compiler.e
-MethodReference04.java:34:16: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)), #void(java.lang.Integer), java.lang.Object
+MethodReference04.java:34:16: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.abstract: null, kindname.class, java.lang.Object)), compiler.misc.type.mref, java.lang.Object
1 error
--- a/test/tools/javac/lambda/MethodReference09.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/MethodReference09.out Fri May 20 17:19:01 2011 +0100
@@ -1,4 +1,4 @@ MethodReference09.java:42:23: compiler.e
MethodReference09.java:42:23: compiler.err.non-static.cant.be.ref: kindname.method, getThis()
-MethodReference09.java:42:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.target.in.lambda.conv: m, kindname.interface, MethodReference09.SAM)), #java.lang.String(), MethodReference09.SAM
+MethodReference09.java:42:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.arg.types.in.lambda)), compiler.misc.type.mref, MethodReference09.SAM
MethodReference09.java:43:20: compiler.err.non-static.cant.be.ref: kindname.variable, this
3 errors
--- a/test/tools/javac/lambda/MethodReference20.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/MethodReference20.out Fri May 20 17:19:01 2011 +0100
@@ -1,5 +1,5 @@ MethodReference20.java:42:27: compiler.e
-MethodReference20.java:42:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.target.in.lambda.conv: m, kindname.interface, MethodReference20.SAM)), #MethodReference20<java.lang.String>(java.lang.String), MethodReference20.SAM<java.lang.Integer>
+MethodReference20.java:42:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: MethodReference20<java.lang.String>)), compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>
MethodReference20.java:43:53: compiler.err.cant.apply.symbol.1: kindname.constructor, MethodReference20, java.lang.String, java.lang.Integer, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: java.lang.Integer, java.lang.String, null)
-MethodReference20.java:44:9: compiler.err.cant.apply.symbol.1: kindname.method, test, MethodReference20.SAM<java.lang.Integer>, #MethodReference20<java.lang.String>(java.lang.String), kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists.1: #MethodReference20<java.lang.String>(java.lang.String), MethodReference20.SAM<java.lang.Integer>, (compiler.misc.incompatible.target.in.lambda.conv: m, kindname.interface, MethodReference20.SAM))
+MethodReference20.java:44:9: compiler.err.cant.apply.symbol.1: kindname.method, test, MethodReference20.SAM<java.lang.Integer>, compiler.misc.type.mref, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>, (compiler.misc.infer.incompatible.ret.types.in.lambda: MethodReference20<java.lang.String>))
MethodReference20.java:45:40: compiler.err.cant.apply.symbol.1: kindname.constructor, MethodReference20, java.lang.String, java.lang.Integer, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: java.lang.Integer, java.lang.String, null)
4 errors
--- a/test/tools/javac/lambda/TargetType01.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/TargetType01.java Fri May 20 17:19:01 2011 +0100
@@ -23,9 +23,9 @@
/*
* @test
- * @summary show that method resolution is not NP hard
+ * @summary check nested case of overload resolution and lambda parameter inference
* @author Maurizio Cimadamore
- * @compile/fail/ref=TargetType01.out -XDlambdaInferenceDiags=false -XDrawDiagnostics TargetType01.java
+ * @compile TargetType01.java
*/
class TargetType01 {
--- a/test/tools/javac/lambda/TargetType04.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/TargetType04.out Fri May 20 17:19:01 2011 +0100
@@ -1,3 +1,3 @@ TargetType04.java:37:29: compiler.err.pr
-TargetType04.java:37:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: ?, #?(?), TargetType04.S<java.lang.Double,java.lang.Integer>)), compiler.misc.type.lambda, TargetType04.S<java.lang.Double,java.lang.Integer>
-TargetType04.java:38:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: ?, #?(?), TargetType04.S<java.lang.Integer,java.lang.Double>)), compiler.misc.type.lambda, TargetType04.S<java.lang.Integer,java.lang.Double>
+TargetType04.java:37:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: java.lang.Double)), compiler.misc.type.lambda, TargetType04.S<java.lang.Double,java.lang.Integer>
+TargetType04.java:38:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: java.lang.Integer)), compiler.misc.type.lambda, TargetType04.S<java.lang.Integer,java.lang.Double>
2 errors
--- a/test/tools/javac/lambda/TargetType06.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/TargetType06.java Fri May 20 17:19:01 2011 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @summary check complex case of target typing
* @author Maurizio Cimadamore
- * @compile TargetType06.java
+ * @compile/fail/ref=TargetType06.out -XDrawDiagnostics TargetType06.java
*/
import java.util.List;
--- a/test/tools/javac/lambda/TargetType10.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/TargetType10.java Fri May 20 17:19:01 2011 +0100
@@ -25,7 +25,7 @@
* @test
* @summary check that wildcards in the target method of a lambda conversion is handled correctly
* @author Maurizio Cimadamore
- * @compile TargetType10.java
+ * @compile/fail/ref=TargetType10.out -XDrawDiagnostics TargetType10.java
*/
class TargetType10 {
--- a/test/tools/javac/lambda/TargetType11.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/TargetType11.java Fri May 20 17:19:01 2011 +0100
@@ -25,7 +25,7 @@
* @test
* @summary check that wildcards in the target method of a lambda conversion is handled correctly
* @author Maurizio Cimadamore
- * @compile TargetType11.java
+ * @compile/fail/ref=TargetType11.out -Xlint:unchecked -XDrawDiagnostics TargetType11.java
*/
class TargetType11 {
--- a/test/tools/javac/lambda/TargetType14.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/TargetType14.out Fri May 20 17:19:01 2011 +0100
@@ -1,7 +1,2 @@ TargetType14.java:38:27: compiler.warn.c
-TargetType14.java:38:27: compiler.warn.cyclic.lambda.inference.throws.1: i,j
-TargetType14.java:39:11: compiler.warn.cyclic.lambda.inference.throws.1: i,j
-TargetType14.java:40:30: compiler.warn.cyclic.lambda.inference.throws.1: i,j
-TargetType14.java:41:30: compiler.warn.cyclic.lambda.inference.throws.1: i,j
-TargetType14.java:41:48: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.String, java.lang.Integer
+TargetType14.java:41:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, TargetType14.SAM<java.lang.String>, TargetType14.SAM<java.lang.Integer>)), TargetType14.SAM<java.lang.String>, TargetType14.SAM<java.lang.Integer>
1 error
-4 warnings
--- a/test/tools/javac/lambda/badMemberRefBytecode/Main.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/badMemberRefBytecode/Main.java Fri May 20 17:19:01 2011 +0100
@@ -1,5 +1,4 @@ import java.util.Collections;
import java.util.Collections;
-import java.util.Locale;
public class Main {
--- a/test/tools/javac/lambda/sqe/SAM_types/NonSAM1.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/sqe/SAM_types/NonSAM1.out Fri May 20 17:19:01 2011 +0100
@@ -1,2 +1,2 @@ NonSAM1.java:9:20: compiler.err.invalid.
-NonSAM1.java:9:20: compiler.err.invalid.target.type.for.lambda.conv.1: Planet, (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, Planet)
+NonSAM1.java:9:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, Planet)), compiler.misc.type.lambda, Planet
1 error
--- a/test/tools/javac/lambda/sqe/SAM_types/NonSAM3.out Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/lambda/sqe/SAM_types/NonSAM3.out Fri May 20 17:19:01 2011 +0100
@@ -1,9 +1,9 @@ NonSAM3.java:13:21: compiler.err.invalid
-NonSAM3.java:13:21: compiler.err.invalid.target.type.for.lambda.conv.1: FooBar, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, FooBar)
-NonSAM3.java:14:22: compiler.err.invalid.target.type.for.lambda.conv.1: FooBar, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, FooBar)
-NonSAM3.java:15:17: compiler.err.invalid.target.type.for.lambda.conv.1: DE, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)
-NonSAM3.java:16:18: compiler.err.invalid.target.type.for.lambda.conv.1: DE, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)
-NonSAM3.java:17:18: compiler.err.invalid.target.type.for.lambda.conv.1: DE, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)
-NonSAM3.java:18:18: compiler.err.invalid.target.type.for.lambda.conv.1: DE, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)
-NonSAM3.java:19:18: compiler.err.invalid.target.type.for.lambda.conv.1: DE, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)
-NonSAM3.java:20:18: compiler.err.invalid.target.type.for.lambda.conv.1: DE, (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)
+NonSAM3.java:13:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, FooBar)), compiler.misc.type.lambda, FooBar
+NonSAM3.java:14:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, FooBar)), compiler.misc.type.lambda, FooBar
+NonSAM3.java:15:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:16:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:17:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
8 errors
--- a/test/tools/javac/types/TypeHarness.java Thu May 05 15:47:56 2011 -0700
+++ b/test/tools/javac/types/TypeHarness.java Fri May 20 17:19:01 2011 +0100
@@ -123,7 +123,7 @@ public class TypeHarness {
/** assert that 's' is/is not castable to 't' */
public void assertCastable(Type s, Type t, boolean expected) {
- if (types.isCastableNoCheck(s, t) != expected) {
+ if (types.isCastable(s, t) != expected) {
String msg = expected ?
" is not castable to " :
" is castable to ";
@@ -138,7 +138,7 @@ public class TypeHarness {
/** assert that 's' is/is not convertible (method invocation conversion) to 't' */
public void assertConvertible(Type s, Type t, boolean expected) {
- if (types.isConvertibleNoCheck(s, t) != expected) {
+ if (types.isConvertible(s, t) != expected) {
String msg = expected ?
" is not convertible to " :
" is convertible to ";
@@ -153,7 +153,7 @@ public class TypeHarness {
/** assert that 's' is/is not assignable to 't' */
public void assertAssignable(Type s, Type t, boolean expected) {
- if (types.isAssignableNoCheck(s, t) != expected) {
+ if (types.isAssignable(s, t) != expected) {
String msg = expected ?
" is not assignable to " :
" is assignable to ";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType06.out Fri May 20 17:19:01 2011 +0100
@@ -0,0 +1,2 @@
+TargetType06.java:46:23: compiler.err.cant.apply.symbol.1: kindname.method, map, TargetType06.Function<B,B>, compiler.misc.type.lambda, kindname.class, TargetType06, (compiler.misc.cyclic.lambda.inference)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType10.out Fri May 20 17:19:01 2011 +0100
@@ -0,0 +1,2 @@
+TargetType10.java:38:11: compiler.err.cant.apply.symbol.1: kindname.method, compose, TargetType10.Function<B,C>,TargetType10.Function<A,? extends B>, compiler.misc.type.lambda,compiler.misc.type.lambda, kindname.class, TargetType10.Test, (compiler.misc.cyclic.lambda.inference)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType11.out Fri May 20 17:19:01 2011 +0100
@@ -0,0 +1,4 @@
+TargetType11.java:37:61: compiler.warn.unchecked.varargs.non.reifiable.type: TargetType11.Predicate<? super T>
+TargetType11.java:41:32: compiler.err.cant.apply.symbol.1: kindname.method, and, TargetType11.Predicate<? super T>[], compiler.misc.type.lambda,compiler.misc.type.lambda, kindname.class, TargetType11.Test, (compiler.misc.cyclic.lambda.inference)
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType19.java Fri May 20 17:19:01 2011 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary complex case of generic method call with lambda argument where target
+ * is a wildcard SAM
+ * @compile TargetType19.java
+ */
+import java.util.List;
+
+class TargetType19 {
+
+ interface SAM<X> {
+ void f(List<? extends X> i);
+ }
+
+ <Z> void call(SAM<? extends Z> s, Z z) { }
+
+ { call(#{ List<? extends String> p -> }, 1); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType19.out Fri May 20 17:19:01 2011 +0100
@@ -0,0 +1,2 @@
+TargetType19.java:40:10: compiler.err.invalid.inferred.types: (compiler.misc.no.conforming.assignment.exists: TargetType19.SAM<java.lang.String>, TargetType19.SAM<? extends java.lang.Integer>)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType20.java Fri May 20 17:19:01 2011 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary complex case of lambda return type that depends on generic method
+ * inference variable
+ * @compile TargetType20.java
+ */
+import java.util.*;
+
+class TargetType20 {
+
+ interface SAM2<X> {
+ List<X> f();
+ }
+
+ class Test {
+ <Z> void call(SAM2<Z> x, SAM2<Z> y) { }
+ { call(#{ -> Collections.emptyList() }, #{ -> new ArrayList<String>() }); }
+ }
+}
--- a/src/share/classes/com/sun/source/tree/FunctionTypeTree.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.source.tree;
-
-import java.util.List;
-
-/**
- * A tree node for a function type.
- *
- * @author mcimadamore
- */
-public interface FunctionTypeTree extends Tree {
- List<? extends Tree> getArgumentTypes();
- List<? extends Tree> getThrownTypes();
- Tree getResultType();
-}
--- a/test/tools/javac/diags/examples/UndeterminedType1.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.undetermined.type.1
-// key: compiler.misc.no.unique.maximal.instance.exists
-
-class UndeterminedType1<V> {
- <T extends Integer & Runnable> UndeterminedType1<T> m() {
- return null;
- }
-
-
- UndeterminedType1<? extends String> c2 = m();
-}
--- a/test/tools/javac/lambda/BadConv01.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @ignore
- * @summary check that target of SAM conversion can't be a generic method
- * @author Alex Buckley
- * @compile/fail/ref=BadConv01.out -XDallowFunctionTypes -XDrawDiagnostics BadConv01.java
- */
-
-class BadConv01<T> {
- #int(T) p = #(T x) { 10 };
- interface Bar { <X> int m(X x); }
-
- Bar b = p; // Illegal. Bar has an infinite number of members called m.
-}
--- a/test/tools/javac/lambda/BadConv02.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @ignore
- * @summary check that target of SAM conversion can't be an abstract class with non-default constructor
- * @author Alex Buckley
- * @compile/fail/ref=BadConv02.out -XDallowFunctionTypes -XDrawDiagnostics BadConv02.java
- */
-
-class BadConv02 {
-
- static abstract class Foo {
- Foo(int x) {}
- int m() { return 0; }
- }
-
- static class FooImpl extends Foo {
- FooImpl(int x) { super(x); }
- int m() { return 1; }
- }
-
- #int() x = #{ 42 };
- Foo f_1 = new FooImpl(); // Illegal, of course.
- Foo f_2 = x; // x has no argument for Foo's constructor, so must be illegal like the FooImpl() line.
-}
--- a/test/tools/javac/lambda/FuncType01.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @ignore
- * @summary test function type with no arguments
- * @author Maurizio Cimadamore
- * @compile -XDallowFunctionTypes FuncType01.java
- * @run main FuncType01
- */
-
-public class FuncType01 {
-
- static void assertTrue(boolean cond) {
- if (!cond)
- throw new AssertionError();
- }
-
- public static void main(String[] args) {
- #boolean() cond = #{ true };
- assertTrue(cond.());
- }
-}
--- a/test/tools/javac/lambda/LambdaConv04.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @ignore
- * @summary function type and method type inference
- * @author Brian Goetz
- * @author Maurizio Cimadamore
- * @compile -XDallowFunctionTypes LambdaConv04.java
- * @run main LambdaConv04
- */
-
-public class LambdaConv04 {
-
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
- public static <T, U> T exec(#T(U) lambda, U x) {
- return lambda.(x);
- }
-
- static {
- //void
- exec(#(Integer x){ assertTrue(x == 3); }, 3);
- //Covariant returns:
- int i = exec(#(Integer x){ x }, 3);
- assertTrue(3 == i);
- //Method resolution with boxing:
- int x = exec(#(Integer x) { x }, 3);
- assertTrue(3 == x);
- //Runtime exception transparency:
- try {
- exec(#(Object x) { x.hashCode() }, null);
- }
- catch (RuntimeException e) {
- assertTrue(true);
- }
- }
-
- {
- //void
- exec(#(Integer x){ assertTrue(x == 3); }, 3);
- //Covariant returns:
- int i = exec(#(Integer x) { x }, 3);
- assertTrue(3 == i);
- //Method resolution with boxing:
- int x = exec(#(Integer x) { x }, 3);
- assertTrue(3 == x);
- //Runtime exception transparency:
- try {
- exec(#(Object x) { x.hashCode() }, null);
- }
- catch (RuntimeException e) {
- assertTrue(true);
- }
- }
-
- public static void test1() {
- //void
- exec(#(Integer x){ assertTrue(x == 3); }, 3);
- //Covariant returns:
- int i = exec(#(Integer x) { x }, 3);
- assertTrue(3 == i);
- //Method resolution with boxing:
- int x = exec(#(Integer x) { x }, 3);
- assertTrue(3 == x);
- //Runtime exception transparency:
- try {
- exec(#(Object x) { x.hashCode() }, null);
- }
- catch (RuntimeException e) {
- assertTrue(true);
- }
- }
-
- public void test2() {
- //void
- exec(#(Integer x){ assertTrue(x == 3); }, 3);
- //Covariant returns:
- int i = exec(#(Integer x) { x }, 3);
- assertTrue(3 == i);
- //Method resolution with boxing:
- int x = exec(#(Integer x) { x }, 3);
- assertTrue(3 == x);
- //Runtime exception transparency:
- try {
- exec(#(Object x) { x.hashCode() }, null);
- }
- catch (RuntimeException e) {
- assertTrue(true);
- }
- }
-
- public static void main(String[] args) {
- test1();
- new LambdaConv04().test2();
- assertTrue(assertionCount == 16);
- }
-}
--- a/test/tools/javac/lambda/TargetType01.out Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-TargetType01.java:45:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
-TargetType01.java:45:33: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
-2 errors
--- a/test/tools/javac/lambda/TargetType09.java Thu May 05 15:47:56 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @ignore
- * @summary check that explicit non-generic target type parses w/o problems
- * @author Peter Levart
- * @author Maurizio Cimadamore
- * @compile -XDallowFunctionTypes TargetType09.java
- */
-
-class TargetType09 {
- public static #int() twice(final int value) { return null; }
- public static #int() twice(final #int() func) { return null; }
-
- public static void main(String[] args) {
- System.out.println(twice(#{22}).());
- }
-}