# HG changeset patch # User mcimadamore # Date 1450355366 0 # Node ID 85ceb9850b1d8e2c23ebc9b737efdb278a372b72 # Parent d31f11c4cc75de8ccec60005953b856309e24c95 8142876: Javac does not correctly implement wildcards removal from functional interfaces Summary: Rewrite code for removing wildcard from target functional interface to be in sync with JLS 9.9 Reviewed-by: vromero, dlsmith diff -r d31f11c4cc75 -r 85ceb9850b1d langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Dec 16 14:23:08 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Dec 17 12:29:26 2015 +0000 @@ -597,36 +597,42 @@ } public Type removeWildcards(Type site) { - Type capturedSite = capture(site); - if (capturedSite != site) { - Type formalInterface = site.tsym.type; - ListBuffer typeargs = new ListBuffer<>(); - List actualTypeargs = site.getTypeArguments(); - List capturedTypeargs = capturedSite.getTypeArguments(); - //simply replace the wildcards with its bound - for (Type t : formalInterface.getTypeArguments()) { - if (actualTypeargs.head.hasTag(WILDCARD)) { - WildcardType wt = (WildcardType)actualTypeargs.head; - Type bound; - switch (wt.kind) { - case EXTENDS: - case UNBOUND: - CapturedType capVar = (CapturedType)capturedTypeargs.head; - //use declared bound if it doesn't depend on formal type-args - bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ? - wt.type : capVar.bound; - break; - default: - bound = wt.type; + if (site.getTypeArguments().stream().anyMatch(t -> t.hasTag(WILDCARD))) { + //compute non-wildcard parameterization - JLS 9.9 + List actuals = site.getTypeArguments(); + List formals = site.tsym.type.getTypeArguments(); + ListBuffer targs = new ListBuffer<>(); + for (Type formal : formals) { + Type actual = actuals.head; + Type bound = formal.getUpperBound(); + if (actuals.head.hasTag(WILDCARD)) { + WildcardType wt = (WildcardType)actual; + //check that bound does not contain other formals + if (bound.containsAny(formals)) { + targs.add(wt.type); + } else { + //compute new type-argument based on declared bound and wildcard bound + switch (wt.kind) { + case UNBOUND: + targs.add(bound); + break; + case EXTENDS: + targs.add(glb(bound, wt.type)); + break; + case SUPER: + targs.add(wt.type); + break; + default: + Assert.error("Cannot get here!"); + } } - typeargs.append(bound); } else { - typeargs.append(actualTypeargs.head); + //not a wildcard - the new type argument remains unchanged + targs.add(actual); } - actualTypeargs = actualTypeargs.tail; - capturedTypeargs = capturedTypeargs.tail; + actuals = actuals.tail; } - return subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList()); + return subst(site.tsym.type, formals, targs.toList()); } else { return site; } diff -r d31f11c4cc75 -r 85ceb9850b1d langtools/test/tools/javac/lambda/8142876/T8142876.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8142876/T8142876.java Thu Dec 17 12:29:26 2015 +0000 @@ -0,0 +1,45 @@ +/* + * 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 8142876 + * @summary Javac does not correctly implement wildcards removal from functional interfaces + * @compile T8142876.java + */ +class T8142876 { + interface I { + void m(); + } + + void test() { + I succeed = this::ff; + I, String> failed = this::ff; + } + + interface O {} + + private void ff(){} +}