Skip to content

Commit

Permalink
Add impl restriction related to invokespecial to Java parents
Browse files Browse the repository at this point in the history
  • Loading branch information
retronym committed May 30, 2016
1 parent 841bdba commit 6d2a838
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1077,10 +1077,15 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
if (needsInterfaceCall(receiverClass)) bc.invokeinterface(receiverName, jname, mdescr, pos)
else bc.invokevirtual (receiverName, jname, mdescr, pos)
case Super =>
if (receiverClass.isTraitOrInterface) {
if (receiverClass.isTrait && method.owner.isTrait && !method.owner.isJavaDefined) {
val staticDesc = MethodBType(typeToBType(method.owner.info) :: method.info.paramTypes.map(typeToBType), typeToBType(method.info.resultType)).descriptor
bc.invokestatic(receiverName, jname, staticDesc, pos)
} else bc.invokespecial (receiverName, jname, mdescr, pos)
} else {
if (receiverClass.isTraitOrInterface && !cnode.interfaces.contains(receiverName))
reporter.error(pos, s"Implementation restriction: unable to emit a super call to ${receiverName}.${method.name} from ${cnode.name}. Add $receiverName as a direct parent of ${cnode.name}")
else
bc.invokespecial (receiverName, jname, mdescr, pos)
}
}

bmType.returnType
Expand Down
4 changes: 4 additions & 0 deletions test/files/neg/trait-defaults-super.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
trait-defaults-super.scala:14: error: Implementation restriction: unable to emit a super call to java/lang/Iterable.spliterator from C. Add java/lang/Iterable as a direct parent of C
class C extends T
^
one error found
21 changes: 21 additions & 0 deletions test/files/neg/trait-defaults-super.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
trait T extends java.lang.Iterable[String] {

override def spliterator(): java.util.Spliterator[String] = {
super[Iterable].spliterator
super.spliterator
null
}
def foo = {
super[Iterable].spliterator
super.spliterator
}
def iterator(): java.util.Iterator[String] = java.util.Collections.emptyList().iterator()
}
class C extends T
object Test {
def main(args: Array[String]): Unit = {
val t: T = new C
t.spliterator
t.foo
}
}
21 changes: 21 additions & 0 deletions test/files/pos/trait-defaults-super.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
trait T extends java.lang.Iterable[String] {

override def spliterator(): java.util.Spliterator[String] = {
super[Iterable].spliterator
super.spliterator
null
}
def foo = {
super[Iterable].spliterator
super.spliterator
}
def iterator(): java.util.Iterator[String] = java.util.Collections.emptyList().iterator()
}
class C extends T with java.lang.Iterable[String] // super accessor is okay with Iterable as a direct parent
object Test {
def main(args: Array[String]): Unit = {
val t: T = new C
t.spliterator
t.foo
}
}

0 comments on commit 6d2a838

Please sign in to comment.