提交 18cfba99 编写于 作者: M mcimadamore

6932571: Compiling Generics causing Inconvertible types

Summary: Types.rewriteQuantifiers() does not work well with recursive type-variable bounds
Reviewed-by: jjg
上级 d3d644c0
......@@ -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.
......
/*
* 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;
}
}
/*
* 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;
}
}
T6270087neg.java:36:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6270087neg.Foo<V>, T6270087neg.Foo<U>
1 error
/*
* 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;
}
}
/*
* 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;
}
}
/*
* 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;
}
}
}
/*
* 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();
}
}
/*
* 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;
}
}
T6932571neg.java:39:19: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6932571neg.S, G
1 error
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册