summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-10-27 01:58:46 +0000
committerPaul Phillips <paulp@improving.org>2010-10-27 01:58:46 +0000
commit0e3e701870e705a453df5f4e178af377eeb54aec (patch)
tree0ab1e63acd6eb4c1893e2a98223e154e41ccf730 /src/compiler/scala/tools/nsc/typechecker
parenta15e48df88fde5172526f68939530862f72f19ca (diff)
downloadscala-0e3e701870e705a453df5f4e178af377eeb54aec.tar.gz
scala-0e3e701870e705a453df5f4e178af377eeb54aec.tar.bz2
scala-0e3e701870e705a453df5f4e178af377eeb54aec.zip
Some uninteresting code related to error messag...
Some uninteresting code related to error messages, which I'm checking in mostly because I booted the r23379 commit in a git-svn meltdown and posterity demands the message, which was: You can now use the self-type of an anonymous class as a singleton type in a pattern match ON THE MOON. Actual test case excerpt: val x4 = new { self => def f(x: Any) = x match { case _: x1.type => 1 case _: x2.type => 2 case _: x3.type => 3 case _: self.type => 4 case x: Dingus.type => x.IamDingus } } Closes #576, no review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala59
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
3 files changed, 42 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index f4f089931e..717b4e672e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -29,6 +29,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
IntClass, UnitClass, ByNameParamClass, Any_asInstanceOf,
Any_isInstanceOf, Object_isInstanceOf, Object_##, Object_==, Object_!=
}
+ import analyzer.{ restrictionError }
/** the following two members override abstract members in Transform */
val phaseName: String = "superaccessors"
@@ -419,37 +420,35 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
* classes, this has to be signaled as error.
*/
private def needsProtectedAccessor(sym: Symbol, pos: Position): Boolean = {
- def errorRestriction(msg: String) {
- unit.error(pos, "Implementation restriction: " + msg)
+ val clazz = currentOwner.enclClass
+ def accessibleThroughSubclassing =
+ validCurrentOwner && clazz.thisSym.isSubClass(sym.owner) && !clazz.isTrait
+
+ val isCandidate = (
+ sym.isProtected
+ && sym.isJavaDefined
+ && !sym.definedInPackage
+ && !accessibleThroughSubclassing
+ && (sym.owner.enclosingPackageClass != currentOwner.enclosingPackageClass)
+ && (sym.owner.enclosingPackageClass == sym.accessBoundary(sym.owner).enclosingPackageClass)
+ )
+ val host = hostForAccessorOf(sym, clazz)
+ def isSelfType = (host.thisSym != host) && {
+ if (host.thisSym.tpe.typeSymbol.isJavaDefined)
+ restrictionError(pos, unit,
+ "%s accesses protected %s from self type %s.".format(clazz, sym, host.thisSym.tpe)
+ )
+ true
}
-
- def accessibleThroughSubclassing: Boolean =
- (validCurrentOwner
- && currentOwner.enclClass.thisSym.isSubClass(sym.owner)
- && !currentOwner.enclClass.isTrait)
-
- val res = /* settings.debug.value && */
- ((sym hasFlag PROTECTED)
- && sym.hasFlag(JAVA)
- && !sym.owner.isPackageClass
- && !accessibleThroughSubclassing
- && (sym.owner.enclosingPackageClass != currentOwner.enclosingPackageClass)
- && (sym.owner.enclosingPackageClass == sym.accessBoundary(sym.owner).enclosingPackageClass))
-
- if (res) {
- val host = hostForAccessorOf(sym, currentOwner.enclClass)
- // bug #1393 - as things stand now the "host" could be a package.
- if (host.isPackageClass) false
- else if (host.thisSym != host) {
- if (host.thisSym.tpe.typeSymbol.hasFlag(JAVA))
- errorRestriction("%s accesses protected %s from self type %s.".format(currentOwner.enclClass, sym, host.thisSym.tpe))
- false
- } else if (host.isTrait && sym.hasFlag(JAVA)) {
- errorRestriction(("%s accesses protected %s inside a concrete trait method. " +
- "Add an accessor in a class extending %s to work around this bug.").format(currentOwner.enclClass, sym, sym.enclClass))
- false
- } else res
- } else res
+ def isJavaProtected = host.isTrait && sym.isJavaDefined && {
+ restrictionError(pos, unit,
+ "%s accesses protected %s inside a concrete trait method. " +
+ "Add an accessor in a class extending %s to work around this bug." .
+ format(clazz, sym, sym.enclClass)
+ )
+ true
+ }
+ isCandidate && !host.isPackageClass && !isSelfType && !isJavaProtected
}
/** Return the innermost enclosing class C of referencingClass for which either
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index be576289f6..d5bb546b7f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -39,6 +39,8 @@ trait TypeDiagnostics {
import definitions._
import global.typer.infer
+ private def currentUnit = currentRun.currentUnit
+
/** It can be quite difficult to know which of the many functions called "error"
* is being called at any given point in the compiler. To alleviate this I am
* renaming such functions inside this trait based on where it originated.
@@ -53,6 +55,14 @@ trait TypeDiagnostics {
def noErroneousSyms(syms: Symbol*) = syms forall (x => !x.isErroneous)
def noErroneousTrees(trees: Tree*) = trees forall (x => !x.isErroneous)
+ /** For errors which are artifacts of the implementation: such messages
+ * indicate that the restriction may be lifted in the future.
+ */
+ def restrictionWarning(pos: Position, unit: CompilationUnit, msg: String): Unit =
+ unit.warning(pos, "Implementation restriction: " + msg)
+ def restrictionError(pos: Position, unit: CompilationUnit, msg: String): Unit =
+ unit.error(pos, "Implementation restriction: " + msg)
+
/** A map of Positions to addendums - if an error involves a position in
* the map, the addendum should also be printed.
*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9397156f41..31eea8c9ed 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1305,8 +1305,8 @@ trait Typers { self: Analyzer =>
val impl2 = typerAddSyntheticMethods(impl1, clazz, context)
if ((clazz != ClassfileAnnotationClass) &&
(clazz isNonBottomSubClass ClassfileAnnotationClass))
- unit.warning (cdef.pos,
- "implementation restriction: subclassing Classfile does not\n"+
+ restrictionWarning(cdef.pos, unit,
+ "subclassing Classfile does not\n"+
"make your annotation visible at runtime. If that is what\n"+
"you want, you must write the annotation class in Java.")
if (phase.id <= currentRun.typerPhase.id) {
@@ -3504,7 +3504,7 @@ trait Typers { self: Analyzer =>
Console.println(site.parents map (_.typeSymbol.name))//debug
if (phase.erasedTypes && context.enclClass.owner.isImplClass) {
// the reference to super class got lost during erasure
- unit.error(tree.pos, "implementation restriction: traits may not select fields or methods from to super[C] where C is a class")
+ restrictionError(tree.pos, unit, "traits may not select fields or methods from to super[C] where C is a class")
} else {
error(tree.pos, mix+" does not name a parent class of "+clazz)
}