diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-06-02 18:53:04 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-06-02 23:30:40 -0700 |
commit | 5667ff46c134878e35edca1ff57b8007ebec4f9a (patch) | |
tree | ab5787c25841ab11534044d18a2eb34b8c8bb231 /src/compiler/scala | |
parent | 461c896581a6e16d1b79e91e9322eb2d14dc53d2 (diff) | |
download | scala-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/scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 28 |
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) |