summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-06-02 18:53:04 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-06-02 23:30:40 -0700
commit5667ff46c134878e35edca1ff57b8007ebec4f9a (patch)
treeab5787c25841ab11534044d18a2eb34b8c8bb231 /src/compiler
parent461c896581a6e16d1b79e91e9322eb2d14dc53d2 (diff)
downloadscala-5667ff46c134878e35edca1ff57b8007ebec4f9a.tar.gz
scala-5667ff46c134878e35edca1ff57b8007ebec4f9a.tar.bz2
scala-5667ff46c134878e35edca1ff57b8007ebec4f9a.zip
Prohibit @native method in trait
On the JVM, a @native interface method results in a VerifyError. Other platforms could decide to be more permissive, but it seems like allowing them in classes is enough.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala28
1 files changed, 18 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index a5a680d135..d1764ea482 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1659,24 +1659,32 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// inside annotations.
applyRefchecksToAnnotations(tree)
var result: Tree = tree match {
- case DefDef(_, _, _, _, _, EmptyTree) if sym hasAnnotation NativeAttr =>
- sym resetFlag DEFERRED
- transform(deriveDefDef(tree)(_ => typed(gen.mkSysErrorCall("native method stub"))))
-
- case ValDef(_, _, _, _) | DefDef(_, _, _, _, _, _) =>
+ case vod: ValOrDefDef =>
checkDeprecatedOvers(tree)
- checkInfiniteLoop(tree.asInstanceOf[ValOrDefDef])
+ checkInfiniteLoop(vod)
if (settings.warnNullaryUnit)
checkNullaryMethodReturnType(sym)
if (settings.warnInaccessible) {
if (!sym.isConstructor && !sym.isEffectivelyFinalOrNotOverridden && !sym.isSynthetic)
checkAccessibilityOfReferencedTypes(tree)
}
- tree match {
- case dd: DefDef => checkByNameRightAssociativeDef(dd)
- case _ =>
+ vod match {
+ case dd: DefDef =>
+ checkByNameRightAssociativeDef(dd)
+
+ if (sym hasAnnotation NativeAttr) {
+ if (sym.owner.isTrait) {
+ reporter.error(tree.pos, "A trait cannot define a native method.")
+ tree
+ } else if (dd.rhs == EmptyTree) {
+ // pretend it had a stub implementation
+ sym resetFlag DEFERRED
+ deriveDefDef(dd)(_ => typed(gen.mkSysErrorCall("native method stub")))
+ } else tree
+ } else tree
+
+ case _ => tree
}
- tree
case Template(parents, self, body) =>
localTyper = localTyper.atOwner(tree, currentOwner)