mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-02 22:48:35 +00:00
6932571: Compiling Generics causing Inconvertible types
Types.rewriteQuantifiers() does not work well with recursive type-variable bounds Reviewed-by: jjg
This commit is contained in:
parent
634d001c64
commit
f5dd0bab3f
@ -328,6 +328,10 @@ public class Type implements PrimitiveType {
|
||||
return (tsym.flags() & INTERFACE) != 0;
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return (tsym.flags() & FINAL) != 0;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return tag < VOID;
|
||||
}
|
||||
|
||||
@ -960,7 +960,7 @@ public class Types {
|
||||
return true;
|
||||
|
||||
if (s.tag == TYPEVAR) {
|
||||
if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {
|
||||
if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
|
||||
warnStack.head.warnUnchecked();
|
||||
return true;
|
||||
} else {
|
||||
@ -1030,7 +1030,12 @@ public class Types {
|
||||
&& !disjointTypes(aHigh.allparams(), lowSub.allparams())
|
||||
&& !disjointTypes(aLow.allparams(), highSub.allparams())
|
||||
&& !disjointTypes(aLow.allparams(), lowSub.allparams())) {
|
||||
if (upcast ? giveWarning(a, b) :
|
||||
if (s.isInterface() &&
|
||||
!t.isInterface() &&
|
||||
t.isFinal() &&
|
||||
!isSubtype(t, s)) {
|
||||
return false;
|
||||
} else if (upcast ? giveWarning(a, b) :
|
||||
giveWarning(b, a))
|
||||
warnStack.head.warnUnchecked();
|
||||
return true;
|
||||
@ -1230,18 +1235,23 @@ public class Types {
|
||||
if (t == s) return false;
|
||||
if (t.tag == TYPEVAR) {
|
||||
TypeVar tv = (TypeVar) t;
|
||||
if (s.tag == TYPEVAR)
|
||||
s = s.getUpperBound();
|
||||
return !isCastable(tv.bound,
|
||||
s,
|
||||
relaxBound(s),
|
||||
Warner.noWarnings);
|
||||
}
|
||||
if (s.tag != WILDCARD)
|
||||
s = upperBound(s);
|
||||
if (s.tag == TYPEVAR)
|
||||
s = s.getUpperBound();
|
||||
|
||||
return !isSubtype(t, s);
|
||||
return !isSubtype(t, relaxBound(s));
|
||||
}
|
||||
|
||||
private Type relaxBound(Type t) {
|
||||
if (t.tag == TYPEVAR) {
|
||||
while (t.tag == TYPEVAR)
|
||||
t = t.getUpperBound();
|
||||
t = rewriteQuantifiers(t, true, true);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
@ -3280,7 +3290,7 @@ public class Types {
|
||||
* quantifiers) only
|
||||
*/
|
||||
private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
|
||||
return new Rewriter(high, rewriteTypeVars).rewrite(t);
|
||||
return new Rewriter(high, rewriteTypeVars).visit(t);
|
||||
}
|
||||
|
||||
class Rewriter extends UnaryVisitor<Type> {
|
||||
@ -3293,25 +3303,21 @@ public class Types {
|
||||
this.rewriteTypeVars = rewriteTypeVars;
|
||||
}
|
||||
|
||||
Type rewrite(Type t) {
|
||||
ListBuffer<Type> from = new ListBuffer<Type>();
|
||||
ListBuffer<Type> to = new ListBuffer<Type>();
|
||||
adaptSelf(t, from, to);
|
||||
@Override
|
||||
public Type visitClassType(ClassType t, Void s) {
|
||||
ListBuffer<Type> rewritten = new ListBuffer<Type>();
|
||||
List<Type> formals = from.toList();
|
||||
boolean changed = false;
|
||||
for (Type arg : to.toList()) {
|
||||
for (Type arg : t.allparams()) {
|
||||
Type bound = visit(arg);
|
||||
if (arg != bound) {
|
||||
changed = true;
|
||||
bound = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
|
||||
: makeSuperWildcard(bound, (TypeVar)formals.head);
|
||||
}
|
||||
rewritten.append(bound);
|
||||
formals = formals.tail;
|
||||
}
|
||||
if (changed)
|
||||
return subst(t.tsym.type, from.toList(), rewritten.toList());
|
||||
return subst(t.tsym.type,
|
||||
t.tsym.type.allparams(),
|
||||
rewritten.toList());
|
||||
else
|
||||
return t;
|
||||
}
|
||||
@ -3322,13 +3328,22 @@ public class Types {
|
||||
|
||||
@Override
|
||||
public Type visitCapturedType(CapturedType t, Void s) {
|
||||
return visitWildcardType(t.wildcard, null);
|
||||
Type bound = visitWildcardType(t.wildcard, null);
|
||||
return (bound.contains(t)) ?
|
||||
(high ? syms.objectType : syms.botType) :
|
||||
bound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitTypeVar(TypeVar t, Void s) {
|
||||
if (rewriteTypeVars)
|
||||
return high ? t.bound : syms.botType;
|
||||
if (rewriteTypeVars) {
|
||||
Type bound = high ?
|
||||
(t.bound.contains(t) ?
|
||||
syms.objectType :
|
||||
visit(t.bound)) :
|
||||
syms.botType;
|
||||
return rewriteAsWildcardType(bound, t);
|
||||
}
|
||||
else
|
||||
return t;
|
||||
}
|
||||
@ -3338,11 +3353,31 @@ public class Types {
|
||||
Type bound = high ? t.getExtendsBound() :
|
||||
t.getSuperBound();
|
||||
if (bound == null)
|
||||
bound = high ? syms.objectType : syms.botType;
|
||||
return bound;
|
||||
bound = high ? syms.objectType : syms.botType;
|
||||
return rewriteAsWildcardType(visit(bound), t.bound);
|
||||
}
|
||||
|
||||
private Type rewriteAsWildcardType(Type bound, TypeVar formal) {
|
||||
return high ?
|
||||
makeExtendsWildcard(B(bound), formal) :
|
||||
makeSuperWildcard(B(bound), formal);
|
||||
}
|
||||
|
||||
Type B(Type t) {
|
||||
while (t.tag == WILDCARD) {
|
||||
WildcardType w = (WildcardType)t;
|
||||
t = high ?
|
||||
w.getExtendsBound() :
|
||||
w.getSuperBound();
|
||||
if (t == null) {
|
||||
t = high ? syms.objectType : syms.botType;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a wildcard with the given upper (extends) bound; create
|
||||
* an unbounded wildcard if bound is Object.
|
||||
|
||||
42
langtools/test/tools/javac/cast/6270087/T6270087.java
Normal file
42
langtools/test/tools/javac/cast/6270087/T6270087.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6270087 6932571
|
||||
* @summary Javac rejects legal cast
|
||||
* @compile T6270087.java
|
||||
*/
|
||||
|
||||
class T6270087 {
|
||||
|
||||
static class Foo<X> {}
|
||||
|
||||
<S extends Comparable<S>> void test1(Comparable<Integer> c) {
|
||||
Object o = (Comparable<S>)c;
|
||||
}
|
||||
|
||||
<U extends Throwable, V extends Runnable> void test2(Foo<V> lv) {
|
||||
Object o = (Foo<U>) lv;
|
||||
}
|
||||
}
|
||||
38
langtools/test/tools/javac/cast/6270087/T6270087neg.java
Normal file
38
langtools/test/tools/javac/cast/6270087/T6270087neg.java
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6270087 6932571
|
||||
* @summary Javac rejects legal cast
|
||||
* @compile/fail/ref=T6270087neg.out -XDrawDiagnostics T6270087neg.java
|
||||
*/
|
||||
|
||||
class T6270087neg {
|
||||
|
||||
static class Foo<X> {}
|
||||
|
||||
<U extends Integer, V extends String> void test2(Foo<V> lv) {
|
||||
Object o = (Foo<U>) lv;
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/cast/6270087/T6270087neg.out
Normal file
2
langtools/test/tools/javac/cast/6270087/T6270087neg.out
Normal file
@ -0,0 +1,2 @@
|
||||
T6270087neg.java:36:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6270087neg.Foo<V>, T6270087neg.Foo<U>
|
||||
1 error
|
||||
37
langtools/test/tools/javac/cast/6507317/T6507317.java
Normal file
37
langtools/test/tools/javac/cast/6507317/T6507317.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6507317 6932571
|
||||
* @summary Problem when casting from parametrized type to concrete class
|
||||
* @compile T6507317.java
|
||||
*/
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
abstract class T6507317<T extends Comparable<T>> implements Comparator<T> {
|
||||
void test(T t) {
|
||||
String s = (String)t;
|
||||
}
|
||||
}
|
||||
43
langtools/test/tools/javac/cast/6569057/T6569057.java
Normal file
43
langtools/test/tools/javac/cast/6569057/T6569057.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6569057 6932571
|
||||
* @summary Generics regression on cast
|
||||
* @compile T6569057.java
|
||||
*/
|
||||
|
||||
class T6569057 {
|
||||
static class A<X extends B<?>> { }
|
||||
|
||||
static class B<X extends A<?>> {
|
||||
D<? extends B<X>> get() { return null; }
|
||||
}
|
||||
|
||||
static class D<Y extends B<?>> {}
|
||||
|
||||
<E extends B<?>> void test(E x, D<B<A<?>>> d) {
|
||||
boolean b = x.get() == d;
|
||||
}
|
||||
}
|
||||
43
langtools/test/tools/javac/cast/6932571/T6932571a.java
Normal file
43
langtools/test/tools/javac/cast/6932571/T6932571a.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6932571
|
||||
* @summary Compiling Generics causing Inconvertible types
|
||||
* @compile T6932571a.java
|
||||
*/
|
||||
|
||||
class T6932571a {
|
||||
static class A<T extends Comparable<? super T>> {
|
||||
public void test(T v) {
|
||||
Object obj = (Integer)v;
|
||||
}
|
||||
}
|
||||
|
||||
static class B<T extends Comparable<? extends T>> {
|
||||
public void test(T v) {
|
||||
Object obj = (Integer)v;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
langtools/test/tools/javac/cast/6932571/T6932571b.java
Normal file
52
langtools/test/tools/javac/cast/6932571/T6932571b.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6932571
|
||||
* @summary Compiling Generics causing Inconvertible types
|
||||
* @compile T6932571b.java
|
||||
*/
|
||||
|
||||
class T6932571b {
|
||||
|
||||
interface A1<T extends B<? super T>> {
|
||||
public T getT();
|
||||
}
|
||||
|
||||
interface A2<T extends B<? extends T>> {
|
||||
public T getT();
|
||||
}
|
||||
|
||||
class B<T extends B<T>> {}
|
||||
|
||||
class C extends B<C> {}
|
||||
|
||||
void test1(A1<?> a) {
|
||||
Object o = (C)a.getT();
|
||||
}
|
||||
|
||||
void test2(A2<?> a) {
|
||||
Object o = (C)a.getT();
|
||||
}
|
||||
}
|
||||
41
langtools/test/tools/javac/cast/6932571/T6932571neg.java
Normal file
41
langtools/test/tools/javac/cast/6932571/T6932571neg.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 6932571
|
||||
* @summary Compiling Generics causing Inconvertible types
|
||||
* @compile/fail/ref=T6932571neg.out -XDrawDiagnostics T6932571neg.java
|
||||
*/
|
||||
|
||||
class T6932571neg {
|
||||
interface I<T>{ }
|
||||
interface I1 extends I<String> {}
|
||||
static class Y implements I<String> {}
|
||||
final static class S implements I<String> {}
|
||||
|
||||
<G extends I<G>> void test() {
|
||||
S s = new S();
|
||||
G g = (G) s;
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/cast/6932571/T6932571neg.out
Normal file
2
langtools/test/tools/javac/cast/6932571/T6932571neg.out
Normal file
@ -0,0 +1,2 @@
|
||||
T6932571neg.java:39:19: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6932571neg.S, G
|
||||
1 error
|
||||
Loading…
x
Reference in New Issue
Block a user