diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 28 | ||||
-rw-r--r-- | src/library/scala/native.scala | 9 |
2 files changed, 24 insertions, 13 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) diff --git a/src/library/scala/native.scala b/src/library/scala/native.scala index dbacc78618..49d3ced805 100644 --- a/src/library/scala/native.scala +++ b/src/library/scala/native.scala @@ -16,8 +16,11 @@ package scala * @native def f(x: Int, y: List[Long]): String = ... * }}} * - * Method body is not generated if method is marked with `@native`, - * but it is type checked when present. + * A `@native` method is compiled to the platform's native method, + * while discarding the method's body (if any). The body will be type checked if present. * - * @since 2.6 */ + * A method marked @native must be a member of a class, not a trait (since 2.12). + * + * @since 2.6 + */ class native extends scala.annotation.StaticAnnotation {} |