mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-16 10:53:31 +00:00
8073842: Invalid method reference when referencing a method on a wildcard type
Method rteference lookup logic doesn't skip type-variables as required by javac. Reviewed-by: jlahoda
This commit is contained in:
parent
ee906c96d7
commit
7b2bf7805a
@ -168,6 +168,18 @@ public class Types {
|
||||
}
|
||||
else return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively skip type-variables until a class/array type is found; capture conversion is then
|
||||
* (optionally) applied to the resulting type. This is useful for i.e. computing a site that is
|
||||
* suitable for a method lookup.
|
||||
*/
|
||||
public Type skipTypeVars(Type site, boolean capture) {
|
||||
while (site.hasTag(TYPEVAR)) {
|
||||
site = site.getUpperBound();
|
||||
}
|
||||
return capture ? capture(site) : site;
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="isUnbounded">
|
||||
@ -1787,12 +1799,9 @@ public class Types {
|
||||
}
|
||||
|
||||
private Type relaxBound(Type t) {
|
||||
if (t.hasTag(TYPEVAR)) {
|
||||
while (t.hasTag(TYPEVAR))
|
||||
t = t.getUpperBound();
|
||||
t = rewriteQuantifiers(t, true, true);
|
||||
}
|
||||
return t;
|
||||
return (t.hasTag(TYPEVAR)) ?
|
||||
rewriteQuantifiers(skipTypeVars(t, false), true, true) :
|
||||
t;
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
@ -1872,10 +1881,7 @@ public class Types {
|
||||
*/
|
||||
private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
|
||||
public Type apply(Type t) {
|
||||
while (t.hasTag(TYPEVAR)) {
|
||||
t = t.getUpperBound();
|
||||
}
|
||||
return elemtype(t);
|
||||
return elemtype(skipTypeVars(t, false));
|
||||
}
|
||||
};
|
||||
|
||||
@ -2662,8 +2668,7 @@ public class Types {
|
||||
|
||||
private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
|
||||
for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) {
|
||||
while (t.hasTag(TYPEVAR))
|
||||
t = t.getUpperBound();
|
||||
t = skipTypeVars(t, false);
|
||||
TypeSymbol c = t.tsym;
|
||||
Symbol bestSoFar = null;
|
||||
for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) {
|
||||
|
||||
@ -3176,8 +3176,7 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.sym = sym;
|
||||
|
||||
if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
|
||||
while (site.hasTag(TYPEVAR)) site = site.getUpperBound();
|
||||
site = capture(site);
|
||||
site = types.skipTypeVars(site, true);
|
||||
}
|
||||
|
||||
// If that symbol is a variable, ...
|
||||
|
||||
@ -28,7 +28,6 @@ package com.sun.tools.javac.comp;
|
||||
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.comp.Resolve.ResolveError;
|
||||
import com.sun.tools.javac.resources.CompilerProperties;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
@ -1372,11 +1371,7 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
site = env.enclClass.sym.type;
|
||||
}
|
||||
|
||||
while (site.hasTag(TYPEVAR)) {
|
||||
site = site.getUpperBound();
|
||||
}
|
||||
|
||||
site = types.capture(site);
|
||||
site = types.skipTypeVars(site, true);
|
||||
|
||||
List<Type> args = rs.dummyArgs(tree.args.length());
|
||||
Name name = TreeInfo.name(tree.meth);
|
||||
|
||||
@ -3446,10 +3446,7 @@ public class Lower extends TreeTranslator {
|
||||
syms.iterableType.tsym);
|
||||
if (iterableType.getTypeArguments().nonEmpty())
|
||||
iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
|
||||
Type eType = tree.expr.type;
|
||||
while (eType.hasTag(TYPEVAR)) {
|
||||
eType = eType.getUpperBound();
|
||||
}
|
||||
Type eType = types.skipTypeVars(tree.expr.type, false);
|
||||
tree.expr.type = types.erasure(eType);
|
||||
if (eType.isCompound())
|
||||
tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
|
||||
|
||||
@ -1791,8 +1791,7 @@ public class Resolve {
|
||||
!t.hasTag(TYPEVAR)) {
|
||||
return null;
|
||||
}
|
||||
while (t.hasTag(TYPEVAR))
|
||||
t = t.getUpperBound();
|
||||
t = types.skipTypeVars(t, false);
|
||||
if (seen.contains(t.tsym)) {
|
||||
//degenerate case in which we have a circular
|
||||
//class hierarchy - because of ill-formed classfiles
|
||||
@ -2656,11 +2655,9 @@ public class Resolve {
|
||||
InferenceContext inferenceContext,
|
||||
ReferenceChooser referenceChooser) {
|
||||
|
||||
site = types.capture(site);
|
||||
//step 1 - bound lookup
|
||||
ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
|
||||
referenceTree, site, name, argtypes, typeargtypes, VARARITY);
|
||||
|
||||
//step 1 - bound lookup
|
||||
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
|
||||
MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
|
||||
boundSearchResolveContext.methodCheck = methodCheck;
|
||||
@ -3044,9 +3041,13 @@ public class Resolve {
|
||||
*/
|
||||
class MethodReferenceLookupHelper extends ReferenceLookupHelper {
|
||||
|
||||
/** The original method reference lookup site. */
|
||||
Type originalSite;
|
||||
|
||||
MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
|
||||
List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
|
||||
super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
|
||||
super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
|
||||
this.originalSite = site;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -3062,7 +3063,7 @@ public class Resolve {
|
||||
(argtypes.head.hasTag(NONE) ||
|
||||
types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
|
||||
return new UnboundMethodReferenceLookupHelper(referenceTree, name,
|
||||
site, argtypes, typeargtypes, maxPhase);
|
||||
originalSite, argtypes, typeargtypes, maxPhase);
|
||||
} else {
|
||||
return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
|
||||
@Override
|
||||
@ -3114,7 +3115,7 @@ public class Resolve {
|
||||
super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
|
||||
if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
|
||||
Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
|
||||
this.site = types.capture(asSuperSite);
|
||||
this.site = types.skipTypeVars(asSuperSite, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -818,9 +818,7 @@ public class TransTypes extends TreeTranslator {
|
||||
}
|
||||
|
||||
public void visitSelect(JCFieldAccess tree) {
|
||||
Type t = tree.selected.type;
|
||||
while (t.hasTag(TYPEVAR))
|
||||
t = t.getUpperBound();
|
||||
Type t = types.skipTypeVars(tree.selected.type, false);
|
||||
if (t.isCompound()) {
|
||||
if ((tree.sym.flags() & IPROXY) != 0) {
|
||||
tree.sym = ((MethodSymbol)tree.sym).
|
||||
|
||||
44
langtools/test/tools/javac/lambda/8073842/T8073842.java
Normal file
44
langtools/test/tools/javac/lambda/8073842/T8073842.java
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8073842
|
||||
* @summary Invalid method reference when referencing a method on a wildcard type
|
||||
* @compile T8073842.java
|
||||
*/
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class T8073842 {
|
||||
|
||||
static class Chunck {
|
||||
public void work() { }
|
||||
}
|
||||
|
||||
void test(Stream<? extends Chunck> s) {
|
||||
Stream<Runnable> r = s.map(o -> o::work);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user