diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-07-14 02:58:29 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-07-14 02:58:29 +0200 |
commit | ef979c02da887b7c56bc1da9c4eb888e92af570f (patch) | |
tree | 2e105d3a0c3374875bede127dd6afaf7a1c88715 /src | |
parent | 2247593472031fd9712b652bab0b978a788e46ef (diff) | |
download | scala-ef979c02da887b7c56bc1da9c4eb888e92af570f.tar.gz scala-ef979c02da887b7c56bc1da9c4eb888e92af570f.tar.bz2 scala-ef979c02da887b7c56bc1da9c4eb888e92af570f.zip |
SI-7657 clarifies the "macro overrides method" rule
Currently we allow macros to override non-abstract methods (in order
to provide performance enhancements such as foreach for collections),
and we also disallow macros to override abstract methods (otherwise
downcasting might lead to AbstractMethodErrors).
This patch fixes an oversight in the disallowing rule that prohibited
macros from overriding a concrete method if that concrete method itself
overrides an abstract method. RefCheck entertains all overriding pairs,
not only the immediate ones, so the disallowing rule was triggered.
Now macros can override abstract methods if and only if either the base
type or the self type contain a matching non-abstract method.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 03ce710700..9c374e85ea 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -225,7 +225,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans * 1.8.1 M's type is a subtype of O's type, or * 1.8.2 M is of type []S, O is of type ()T and S <: T, or * 1.8.3 M is of type ()S, O is of type []T and S <: T, or - * 1.9. If M is a macro def, O cannot be deferred. + * 1.9. If M is a macro def, O cannot be deferred unless there's a concrete method overriding O. * 1.10. If M is not a macro def, O cannot be a macro def. * 2. Check that only abstract classes have deferred members * 3. Check that concrete classes do not have deferred definitions @@ -417,7 +417,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } else if (other.isValue && other.isLazy && !other.isSourceMethod && !other.isDeferred && member.isValue && !member.isLazy) { overrideError("must be declared lazy to override a concrete lazy value") - } else if (other.isDeferred && member.isTermMacro) { // (1.9) + } else if (other.isDeferred && member.isTermMacro && member.extendedOverriddenSymbols.forall(_.isDeferred)) { // (1.9) overrideError("cannot override an abstract method") } else if (other.isTermMacro && !member.isTermMacro) { // (1.10) overrideError("cannot override a macro") |