Skip to content

Commit a9d5a6d

Browse files
committed
Add impl restriction related to invokespecial to Java parents
1 parent 68aa84f commit a9d5a6d

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala

+7-2
Original file line numberDiff line numberDiff line change
@@ -1077,10 +1077,15 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
10771077
if (needsInterfaceCall(receiverClass)) bc.invokeinterface(receiverName, jname, mdescr, pos)
10781078
else bc.invokevirtual (receiverName, jname, mdescr, pos)
10791079
case Super =>
1080-
if (receiverClass.isTraitOrInterface) {
1080+
if (receiverClass.isTrait && method.owner.isTrait && !method.owner.isJavaDefined) {
10811081
val staticDesc = MethodBType(typeToBType(method.owner.info) :: method.info.paramTypes.map(typeToBType), typeToBType(method.info.resultType)).descriptor
10821082
bc.invokestatic(receiverName, jname, staticDesc, pos)
1083-
} else bc.invokespecial (receiverName, jname, mdescr, pos)
1083+
} else {
1084+
if (receiverClass.isTraitOrInterface && !cnode.interfaces.contains(receiverName))
1085+
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}")
1086+
else
1087+
bc.invokespecial (receiverName, jname, mdescr, pos)
1088+
}
10841089
}
10851090

10861091
bmType.returnType

src/compiler/scala/tools/nsc/transform/Mixin.scala

+5
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
345345
reporter.error(clazz.pos, "Member %s of mixin %s is missing a concrete super implementation.".format(
346346
mixinMember.alias, mixinClass))
347347
case alias1 =>
348+
val temp = alias1
349+
if (temp.owner.isJavaDefined && temp.owner.isInterface && !clazz.parentSymbols.contains(temp.owner)) {
350+
val suggestedParent = exitingTyper(clazz.info.baseType(temp.owner))
351+
reporter.error(clazz.pos, s"Unable to implement a super accessor required by trait ${mixinClass.name} unless $suggestedParent is directly extended by $clazz.")
352+
}
348353
superAccessor.asInstanceOf[TermSymbol] setAlias alias1
349354
}
350355
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait-defaults-super.scala:14: error: Unable to implement a super accessor required by trait T unless Iterable[String] is directly extended by class C
2+
class C extends T
3+
^
4+
one error found
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait T extends java.lang.Iterable[String] {
2+
3+
override def spliterator(): java.util.Spliterator[String] = {
4+
super[Iterable].spliterator
5+
super.spliterator
6+
null
7+
}
8+
def foo = {
9+
super[Iterable].spliterator
10+
super.spliterator
11+
}
12+
def iterator(): java.util.Iterator[String] = java.util.Collections.emptyList().iterator()
13+
}
14+
class C extends T
15+
object Test {
16+
def main(args: Array[String]): Unit = {
17+
val t: T = new C
18+
t.spliterator
19+
t.foo
20+
}
21+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait T extends java.lang.Iterable[String] {
2+
3+
override def spliterator(): java.util.Spliterator[String] = {
4+
super[Iterable].spliterator
5+
super.spliterator
6+
null
7+
}
8+
def foo = {
9+
super[Iterable].spliterator
10+
super.spliterator
11+
}
12+
def iterator(): java.util.Iterator[String] = java.util.Collections.emptyList().iterator()
13+
}
14+
class C extends T with java.lang.Iterable[String] // super accessor is okay with Iterable as a direct parent
15+
object Test {
16+
def main(args: Array[String]): Unit = {
17+
val t: T = new C
18+
t.spliterator
19+
t.foo
20+
}
21+
}

0 commit comments

Comments
 (0)