Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SI-10260 better error messages for raw Java types #5847

Merged
merged 1 commit into from Sep 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Expand Up @@ -704,7 +704,7 @@ abstract class RefChecks extends Transform {
// Compilation has already failed so we shouldn't have to worry overmuch
// about forcing types.
if (underlying.isJavaDefined && pa.typeArgs.isEmpty && abstractSym.typeParams.nonEmpty)
". To implement a raw type, use %s[_]".format(pa)
s". To implement this raw type, use ${rawToExistential(pa)}"
else if (pa.prefix =:= pc.prefix)
": their type parameters differ"
else
Expand Down
4 changes: 2 additions & 2 deletions src/reflect/scala/reflect/internal/Types.scala
Expand Up @@ -3876,8 +3876,8 @@ trait Types
}

def typeParamsToExistentials(clazz: Symbol, tparams: List[Symbol]): List[Symbol] = {
val eparams = mapWithIndex(tparams)((tparam, i) =>
clazz.newExistential(newTypeName("?"+i), clazz.pos) setInfo tparam.info.bounds)
val eparams = tparams map (tparam =>
clazz.newExistential(tparam.name.toTypeName, clazz.pos) setInfo tparam.info.bounds)

eparams map (_ substInfo (tparams, eparams))
}
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/abstract-class-error.check
@@ -1,5 +1,5 @@
S.scala:1: error: class S needs to be abstract, since method g in class J of type (y: Int, z: java.util.List)Int is not defined
(Note that java.util.List does not match java.util.List[String]. To implement a raw type, use java.util.List[_])
(Note that java.util.List does not match java.util.List[String]. To implement this raw type, use java.util.List[_])
class S extends J {
^
one error found
17 changes: 17 additions & 0 deletions test/files/neg/t10260.check
@@ -0,0 +1,17 @@
Test.scala:1: error: class IAImpl needs to be abstract, since method foo in trait IA of type (a: A)Unit is not defined
(Note that A does not match A[_]. To implement this raw type, use A[T] forSome { type T <: A[T] })
class IAImpl extends IA { def foo(a: A[_]) = ??? }
^
Test.scala:2: error: class IBImpl needs to be abstract, since method foo in trait IB of type (a: B)Unit is not defined
(Note that B does not match B[_, _]. To implement this raw type, use B[T,R] forSome { type T; type R <: java.util.List[_ >: T] })
class IBImpl extends IB { def foo(a: B[_,_]) = ??? }
^
Test.scala:3: error: class ICImpl needs to be abstract, since method foo in trait IC of type (a: Int, b: C, c: String)C is not defined
(Note that C does not match C[_]. To implement this raw type, use C[_ <: String])
class ICImpl extends IC { def foo(a: Int, b: C[_], c: String) = ??? }
^
Test.scala:4: error: class IDImpl needs to be abstract, since method foo in trait ID of type (a: D)Unit is not defined
(Note that D does not match D[_ <: String]. To implement this raw type, use D[_])
class IDImpl extends ID { def foo(a: D[_ <: String]) = ??? }
^
four errors found
2 changes: 2 additions & 0 deletions test/files/neg/t10260/A.java
@@ -0,0 +1,2 @@
public class A<T extends A<T>> {}

2 changes: 2 additions & 0 deletions test/files/neg/t10260/B.java
@@ -0,0 +1,2 @@
public class B<T, R extends java.util.List<? super T>> {}

2 changes: 2 additions & 0 deletions test/files/neg/t10260/C.java
@@ -0,0 +1,2 @@
public class C<T extends String> {}

2 changes: 2 additions & 0 deletions test/files/neg/t10260/D.java
@@ -0,0 +1,2 @@
public class D<T> {}

3 changes: 3 additions & 0 deletions test/files/neg/t10260/IA.java
@@ -0,0 +1,3 @@
public interface IA {
void foo(A a);
}
3 changes: 3 additions & 0 deletions test/files/neg/t10260/IB.java
@@ -0,0 +1,3 @@
public interface IB {
void foo(B a);
}
3 changes: 3 additions & 0 deletions test/files/neg/t10260/IC.java
@@ -0,0 +1,3 @@
public interface IC {
C foo(int a, C b, String c);
}
3 changes: 3 additions & 0 deletions test/files/neg/t10260/ID.java
@@ -0,0 +1,3 @@
public interface ID {
void foo(D a);
}
4 changes: 4 additions & 0 deletions test/files/neg/t10260/Test.scala
@@ -0,0 +1,4 @@
class IAImpl extends IA { def foo(a: A[_]) = ??? }
class IBImpl extends IB { def foo(a: B[_,_]) = ??? }
class ICImpl extends IC { def foo(a: Int, b: C[_], c: String) = ??? }
class IDImpl extends ID { def foo(a: D[_ <: String]) = ??? }
2 changes: 1 addition & 1 deletion test/files/neg/t8244.check
@@ -1,4 +1,4 @@
Test_2.scala:9: error: value exxx is not a member of ?0
Test_2.scala:9: error: value exxx is not a member of T
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be interesting to investigate this one -- should indicate it's an existential skolem

raw.t.exxx // java.lang.ClassCastException: java.lang.String cannot be cast to X
^
one error found
2 changes: 1 addition & 1 deletion test/files/neg/t8244e.check
@@ -1,4 +1,4 @@
Test.scala:9: error: value exxx is not a member of ?0
Test.scala:9: error: value exxx is not a member of T
raw.t.exxx // java.lang.ClassCastException: java.lang.String cannot be cast to X
^
one error found
24 changes: 12 additions & 12 deletions test/files/run/existentials-in-compiler.check
Expand Up @@ -2,16 +2,16 @@ abstract trait Bippy[A <: AnyRef, B] extends AnyRef
extest.Bippy[_ <: AnyRef, _]

abstract trait BippyBud[A <: AnyRef, B, C <: List[A]] extends AnyRef
extest.BippyBud[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1; type ?2 <: List[?0] }
extest.BippyBud[A,B,C] forSome { type A <: AnyRef; type B; type C <: List[A] }

abstract trait BippyLike[A <: AnyRef, B <: List[A], This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B]] extends AnyRef
extest.BippyLike[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1 <: List[?0]; type ?2 <: extest.BippyLike[?0,?1,?2] with extest.Bippy[?0,?1] }
extest.BippyLike[A,B,This] forSome { type A <: AnyRef; type B <: List[A]; type This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B] }

abstract trait Contra[-A >: AnyRef, -B] extends AnyRef
extest.Contra[_ >: AnyRef, _]

abstract trait ContraLike[-A >: AnyRef, -B >: List[A]] extends AnyRef
extest.ContraLike[?0,?1] forSome { type ?0 >: AnyRef; type ?1 >: List[?0] }
extest.ContraLike[A,B] forSome { type A >: AnyRef; type B >: List[A] }

abstract trait Cov01[+A <: AnyRef, +B] extends AnyRef
extest.Cov01[_ <: AnyRef, _]
Expand Down Expand Up @@ -95,28 +95,28 @@ abstract trait Cov29[-A, -B] extends AnyRef
extest.Cov29[_, _]

abstract trait Cov31[+A, +B, C <: (A, B)] extends AnyRef
extest.Cov31[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
extest.Cov31[A,B,C] forSome { type A; type B; type C <: (A, B) }

abstract trait Cov32[+A, B, C <: (A, B)] extends AnyRef
extest.Cov32[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
extest.Cov32[A,B,C] forSome { type A; type B; type C <: (A, B) }

abstract trait Cov33[+A, -B, C <: Tuple2[A, _]] extends AnyRef
extest.Cov33[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[?0, _] }
extest.Cov33[A,B,C] forSome { type A; type B; type C <: Tuple2[A, _] }

abstract trait Cov34[A, +B, C <: (A, B)] extends AnyRef
extest.Cov34[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
extest.Cov34[A,B,C] forSome { type A; type B; type C <: (A, B) }

abstract trait Cov35[A, B, C <: (A, B)] extends AnyRef
extest.Cov35[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
extest.Cov35[A,B,C] forSome { type A; type B; type C <: (A, B) }

abstract trait Cov36[A, -B, C <: Tuple2[A, _]] extends AnyRef
extest.Cov36[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[?0, _] }
extest.Cov36[A,B,C] forSome { type A; type B; type C <: Tuple2[A, _] }

abstract trait Cov37[-A, +B, C <: Tuple2[_, B]] extends AnyRef
extest.Cov37[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[_, ?1] }
extest.Cov37[A,B,C] forSome { type A; type B; type C <: Tuple2[_, B] }

abstract trait Cov38[-A, B, C <: Tuple2[_, B]] extends AnyRef
extest.Cov38[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[_, ?1] }
extest.Cov38[A,B,C] forSome { type A; type B; type C <: Tuple2[_, B] }

abstract trait Cov39[-A, -B, C <: Tuple2[_, _]] extends AnyRef
extest.Cov39[_, _, _ <: Tuple2[_, _]]
Expand Down Expand Up @@ -152,5 +152,5 @@ abstract trait Covariant[+A <: AnyRef, +B] extends AnyRef
extest.Covariant[_ <: AnyRef, _]

abstract trait CovariantLike[+A <: AnyRef, +B <: List[A], +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B]] extends AnyRef
extest.CovariantLike[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1 <: List[?0]; type ?2 <: extest.CovariantLike[?0,?1,?2] with extest.Covariant[?0,?1] }
extest.CovariantLike[A,B,This] forSome { type A <: AnyRef; type B <: List[A]; type This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B] }

2 changes: 1 addition & 1 deletion test/files/run/t5418b.check
@@ -1,2 +1,2 @@
new Object().getClass()
TypeRef(ThisType(java.lang), java.lang.Class, List(TypeRef(NoPrefix, TypeName("?0"), List())))
TypeRef(ThisType(java.lang), java.lang.Class, List(TypeRef(NoPrefix, TypeName("T"), List())))