diff options
-rw-r--r-- | bincompat-backward.whitelist.conf | 8 | ||||
-rw-r--r-- | bincompat-forward.whitelist.conf | 24 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/HasFlags.scala | 3 | ||||
-rw-r--r-- | test/files/run/t7825.scala | 34 |
5 files changed, 71 insertions, 2 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 38d26c7fb7..0500ec10ab 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -303,6 +303,14 @@ filter { { matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques_=" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredNotDefault" + problemName=MissingMethodProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index a64eb0ba5d..2ece671638 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -1407,6 +1407,30 @@ filter { { matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques_=" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.isDeferredNotDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredNotDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees#Modifiers.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees#Modifiers.isDeferredNotDefault" + problemName=MissingMethodProblem } ] } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 09c4878b2f..83afb3a728 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -383,7 +383,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans overrideError("cannot be used here - classes can only override abstract types"); } else if (other.isEffectivelyFinal) { // (1.2) overrideError("cannot override final member"); - } else if (!other.isDeferred && !other.hasFlag(DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*) + } else if (!other.isDeferredOrDefault && !member.isAnyOverride && !member.isSynthetic) { // (*) // (*) Synthetic exclusion for (at least) default getters, fixes SI-5178. We cannot assign the OVERRIDE flag to // the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket. if (isNeitherInClass && !(other.owner isSubClass member.owner)) @@ -565,7 +565,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans def checkNoAbstractMembers(): Unit = { // Avoid spurious duplicates: first gather any missing members. def memberList = clazz.info.nonPrivateMembersAdmitting(VBRIDGE) - val (missing, rest) = memberList partition (m => m.isDeferred && !ignoreDeferred(m)) + val (missing, rest) = memberList partition (m => m.isDeferredNotDefault && !ignoreDeferred(m)) // Group missing members by the name of the underlying symbol, // to consolidate getters and setters. val grouped = missing groupBy (sym => analyzer.underlyingSymbol(sym).name) diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 4a3663b8ea..12fd3a31cd 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -115,6 +115,9 @@ trait HasFlags { def isSynthetic = hasFlag(SYNTHETIC) def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM) + def isDeferredOrDefault = hasFlag(DEFERRED | DEFAULTMETHOD) + def isDeferredNotDefault = isDeferred && !hasFlag(DEFAULTMETHOD) + def flagBitsToString(bits: Long): String = { // Fast path for common case if (bits == 0L) "" else { diff --git a/test/files/run/t7825.scala b/test/files/run/t7825.scala new file mode 100644 index 0000000000..65ca06fdfc --- /dev/null +++ b/test/files/run/t7825.scala @@ -0,0 +1,34 @@ +import scala.tools.partest._ + +object Test extends CompilerTest { + import global._ + + override lazy val units: List[CompilationUnit] = { + // We can test this on JDK6. + javaCompilationUnits(global)(defaultMethodSource) ++ compilationUnits(global)(scalaExtendsDefault) + } + + private def defaultMethodSource = """ +public interface Iterator<E> { + boolean hasNext(); + E next(); + default void remove() { + throw new UnsupportedOperationException("remove"); + } +} + """ + + private def scalaExtendsDefault = """ +object Test { + object X extends Iterator[String] { + def hasNext = true + def next = "!" + } +} + """ + + // We're only checking we that the Scala compilation unit passes refchecks + // No further checks are needed here. + def check(source: String, unit: global.CompilationUnit): Unit = { + } +} |