Skip to content

Commit

Permalink
SI-10260 better error messages for raw Java types
Browse files Browse the repository at this point in the history
  • Loading branch information
Jasper-M committed Apr 12, 2017
1 parent b68cc6c commit 9eb8631
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 2 deletions.
26 changes: 24 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Expand Up @@ -684,6 +684,23 @@ abstract class RefChecks extends Transform {
(m.tpe.paramTypes.size == underlying.tpe.paramTypes.size) &&
(m.tpe.typeParams.size == underlying.tpe.typeParams.size)
}

def prepareRawTypeForMessage(abstractSym: Symbol): Option[Type] =
underlying.paramLists.head.find(s => s.info.typeSymbolDirect == abstractSym) flatMap { param =>
val clone = underlying.cloneSymbol
clone.cookJavaRawInfo()
clone.paramLists.head.find(s => s.name == param.name) map { cooked =>
val tpe = cooked.info
tpe match {
case ext @ ExistentialType(_,_) if !ext.isRepresentableWithWildcards =>
((tpe.typeArgs map (_.typeSymbolDirect)) zip abstractSym.typeParams) foreach {
case (s1, s2) => s1.name = s2.name
}
case _ =>
}
tpe
}
}

matchingArity match {
// So far so good: only one candidate method
Expand All @@ -703,8 +720,13 @@ abstract class RefChecks extends Transform {
// TODO: what is the optimal way to test for a raw type at this point?
// 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)
if (underlying.isJavaDefined && pa.typeArgs.isEmpty && abstractSym.typeParams.nonEmpty) {
prepareRawTypeForMessage(abstractSym).fold(
". To implement a raw type, use %s[_]".format(pa)
)(
". To implement this raw type, use %s".format(_)
)
}
else if (pa.prefix =:= pc.prefix)
": their type parameters differ"
else
Expand Down
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 <: String; 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: C)Unit 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: C[_]) = ??? }
^
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
1 change: 1 addition & 0 deletions test/files/neg/t10260.flags
@@ -0,0 +1 @@
-language:existentials
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 extends String, R extends java.util.List<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 {
void foo(C a);
}
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: C[_]) = ??? }
class IDImpl extends ID { def foo(a: D[_ <: String]) = ??? }

0 comments on commit 9eb8631

Please sign in to comment.