8188144: regression in method reference type-checking
Method reference checking prefers unbound lookup when both searches produce same results Reviewed-by: vromero
This commit is contained in:
parent
6ab21308de
commit
870b0834fe
@ -117,7 +117,7 @@ public class Resolve {
|
||||
varNotFound = new SymbolNotFoundError(ABSENT_VAR);
|
||||
methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
|
||||
typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
|
||||
referenceNotFound = new ReferenceLookupResult(methodNotFound, null);
|
||||
referenceNotFound = ReferenceLookupResult.error(methodNotFound);
|
||||
|
||||
names = Names.instance(context);
|
||||
log = Log.instance(context);
|
||||
@ -2968,10 +2968,10 @@ public class Resolve {
|
||||
|
||||
//merge results
|
||||
Pair<Symbol, ReferenceLookupHelper> res;
|
||||
Symbol bestSym = referenceChooser.result(boundRes, unboundRes);
|
||||
res = new Pair<>(bestSym,
|
||||
bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
|
||||
env.info.pendingResolutionPhase = bestSym == unboundSym ?
|
||||
ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes);
|
||||
res = new Pair<>(bestRes.sym,
|
||||
bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper);
|
||||
env.info.pendingResolutionPhase = bestRes == unboundRes ?
|
||||
unboundEnv.info.pendingResolutionPhase :
|
||||
boundEnv.info.pendingResolutionPhase;
|
||||
|
||||
@ -3027,11 +3027,15 @@ public class Resolve {
|
||||
Symbol sym;
|
||||
|
||||
ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
|
||||
this.staticKind = staticKind(sym, resolutionContext);
|
||||
this(sym, staticKind(sym, resolutionContext));
|
||||
}
|
||||
|
||||
private ReferenceLookupResult(Symbol sym, StaticKind staticKind) {
|
||||
this.staticKind = staticKind;
|
||||
this.sym = sym;
|
||||
}
|
||||
|
||||
private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
|
||||
private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
|
||||
switch (sym.kind) {
|
||||
case MTH:
|
||||
case AMBIGUOUS:
|
||||
@ -3080,6 +3084,10 @@ public class Resolve {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ReferenceLookupResult error(Symbol sym) {
|
||||
return new ReferenceLookupResult(sym, StaticKind.UNDEFINED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3092,7 +3100,7 @@ public class Resolve {
|
||||
* Generate a result from a pair of lookup result objects. This method delegates to the
|
||||
* appropriate result generation routine.
|
||||
*/
|
||||
Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||
ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||
return unboundRes != referenceNotFound ?
|
||||
unboundResult(boundRes, unboundRes) :
|
||||
boundResult(boundRes);
|
||||
@ -3101,12 +3109,12 @@ public class Resolve {
|
||||
/**
|
||||
* Generate a symbol from a given bound lookup result.
|
||||
*/
|
||||
abstract Symbol boundResult(ReferenceLookupResult boundRes);
|
||||
abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes);
|
||||
|
||||
/**
|
||||
* Generate a symbol from a pair of bound/unbound lookup results.
|
||||
*/
|
||||
abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
|
||||
abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3116,37 +3124,38 @@ public class Resolve {
|
||||
ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
|
||||
|
||||
@Override
|
||||
Symbol boundResult(ReferenceLookupResult boundRes) {
|
||||
ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
|
||||
return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
|
||||
boundRes.sym : //the search produces a non-static method
|
||||
new BadMethodReferenceError(boundRes.sym, false);
|
||||
boundRes : //the search produces a non-static method
|
||||
ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||
ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||
if (boundRes.hasKind(StaticKind.STATIC) &&
|
||||
(!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
|
||||
//the first search produces a static method and no non-static method is applicable
|
||||
//during the second search
|
||||
return boundRes.sym;
|
||||
return boundRes;
|
||||
} else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
|
||||
(!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
|
||||
//the second search produces a non-static method and no static method is applicable
|
||||
//during the first search
|
||||
return unboundRes.sym;
|
||||
return unboundRes;
|
||||
} else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
|
||||
//both searches produce some result; ambiguity (error recovery)
|
||||
return ambiguityError(boundRes.sym, unboundRes.sym);
|
||||
return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym));
|
||||
} else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
|
||||
//Both searches failed to produce a result with correct staticness (i.e. first search
|
||||
//produces an non-static method). Alternatively, a given search produced a result
|
||||
//with the right staticness, but the other search has applicable methods with wrong
|
||||
//staticness (error recovery)
|
||||
return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
|
||||
return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
|
||||
boundRes.sym : unboundRes.sym, true));
|
||||
} else {
|
||||
//both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
|
||||
return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
|
||||
unboundRes.sym : boundRes.sym;
|
||||
unboundRes : boundRes;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -3158,28 +3167,29 @@ public class Resolve {
|
||||
ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
|
||||
|
||||
@Override
|
||||
Symbol boundResult(ReferenceLookupResult boundRes) {
|
||||
ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
|
||||
return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
|
||||
boundRes.sym : //the search has at least one applicable non-static method
|
||||
new BadMethodReferenceError(boundRes.sym, false);
|
||||
boundRes : //the search has at least one applicable non-static method
|
||||
ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||
ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||
if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
|
||||
//the first serach has at least one applicable static method
|
||||
return boundRes.sym;
|
||||
return boundRes;
|
||||
} else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
|
||||
//the second search has at least one applicable non-static method
|
||||
return unboundRes.sym;
|
||||
return unboundRes;
|
||||
} else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
|
||||
//either the first search produces a non-static method, or second search produces
|
||||
//a non-static method (error recovery)
|
||||
return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
|
||||
return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
|
||||
boundRes.sym : unboundRes.sym, true));
|
||||
} else {
|
||||
//both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
|
||||
return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
|
||||
unboundRes.sym : boundRes.sym;
|
||||
unboundRes : boundRes;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
41
test/langtools/tools/javac/lambda/8188144/T8188144.java
Normal file
41
test/langtools/tools/javac/lambda/8188144/T8188144.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 8188144
|
||||
* @summary regression in method reference type-checking
|
||||
*/
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class T8188144 {
|
||||
public static void main(String[] args) {
|
||||
BiFunction<String, String, String> format = String::format;
|
||||
if (!format.apply("foo %s", "bar").endsWith("foo bar")) {
|
||||
throw new AssertionError("Unexpected output!");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user