summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-21 20:57:27 +0000
committerPaul Phillips <paulp@improving.org>2009-10-21 20:57:27 +0000
commit7349476e5cf7984acf40055cb55d78cbaed41043 (patch)
tree527229fd0cdab2451fd9feabfcdef2730f9ec453 /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent322b823276a3f40db95bb3306c842021e77572df (diff)
downloadscala-7349476e5cf7984acf40055cb55d78cbaed41043.tar.gz
scala-7349476e5cf7984acf40055cb55d78cbaed41043.tar.bz2
scala-7349476e5cf7984acf40055cb55d78cbaed41043.zip
A selection of cleanups stemming from recent in...
A selection of cleanups stemming from recent investigations.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala65
1 files changed, 39 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7307a0d379..b81c087901 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -879,23 +879,16 @@ trait Typers { self: Analyzer =>
if (extractor != NoSymbol) {
tree setSymbol extractor
val unapply = unapplyMember(extractor.tpe)
- val clazz = if (unapply.tpe.paramTypes.length == 1) unapply.tpe.paramTypes.head.typeSymbol
- else NoSymbol
- if ((unapply hasFlag CASE) && (clazz hasFlag CASE) &&
- !(clazz.info.baseClasses.tail exists (_ hasFlag CASE))) {
- if (!phase.erasedTypes) checkStable(tree) //todo: do we need to demand this?
+ val clazz = unapplyParameterType(unapply)
+
+ if ((unapply hasFlag CASE) && (clazz hasFlag CASE) && !(clazz.ancestors exists (_ hasFlag CASE))) {
+ if (!phase.erasedTypes) checkStable(tree) // todo: do we need to demand this?
// convert synthetic unapply of case class to case class constructor
val prefix = tree.tpe.prefix
val tree1 = TypeTree(clazz.primaryConstructor.tpe.asSeenFrom(prefix, clazz.owner))
.setOriginal(tree)
- try {
- inferConstructorInstance(tree1, clazz.typeParams, pt)
- } catch {
- case tpe : TypeError => throw tpe
- case t : Exception =>
- logError("CONTEXT: " + (tree.pos).dbgString, t)
- throw t
- }
+
+ inferConstructorInstance(tree1, clazz.typeParams, pt)
tree1
} else {
tree
@@ -1051,6 +1044,20 @@ trait Typers { self: Analyzer =>
typed(cbody)
}
+ private def validateNoCaseAncestor(clazz: Symbol) = {
+ // XXX I think this should issue a sharper warning of some kind like
+ // "change your code now!" as there are material bugs (which are very unlikely
+ // to be fixed) associated with case class inheritance.
+ if (!phase.erasedTypes) {
+ for (ancestor <- clazz.ancestors find (_ hasFlag CASE))
+ unit.deprecationWarning(clazz.pos, (
+ "case class `%s' has case class ancestor `%s'. This has been deprecated " +
+ "for unduly complicating both usage and implementation. You should instead " +
+ "use extractors for pattern matching on non-leaf nodes." ).format(clazz, ancestor)
+ )
+ }
+ }
+
def parentTypes(templ: Template): List[Tree] =
if (templ.parents.isEmpty) List()
else try {
@@ -1177,17 +1184,6 @@ trait Typers { self: Analyzer =>
if (psym hasFlag FINAL) {
error(parent.pos, "illegal inheritance from final "+psym)
}
- // XXX I think this should issue a sharper warning of some kind like
- // "change your code now!" as there are material bugs (which will not be fixed)
- // associated with case class inheritance.
- if ((context.owner hasFlag CASE) && !phase.erasedTypes) {
- for (ancestor <- parent.tpe.baseClasses find (_ hasFlag CASE))
- unit.deprecationWarning(parent.pos, (
- "case class `%s' has case class ancestor `%s'. This has been deprecated " +
- "for unduly complicating both usage and implementation. You should instead " +
- "use extractors for pattern matching on non-leaf nodes." ).format(context.owner, ancestor)
- )
- }
if (psym.isSealed && !phase.erasedTypes) {
if (context.unit.source.file != psym.sourceFile)
error(parent.pos, "illegal inheritance from sealed "+psym)
@@ -1435,6 +1431,9 @@ trait Typers { self: Analyzer =>
assert(clazz.info.decls != EmptyScope)
enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body)
validateParentClasses(parents1, selfType)
+ if (clazz hasFlag CASE)
+ validateNoCaseAncestor(clazz)
+
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
@@ -1897,7 +1896,7 @@ trait Typers { self: Analyzer =>
val stats1 = typedStats(stats, NoSymbol)
for (stat <- stats1 if stat.isDef) {
val member = stat.symbol
- if (!(context.owner.info.baseClasses.tail forall
+ if (!(context.owner.ancestors forall
(bc => member.matchingSymbol(bc, context.owner.thisType) == NoSymbol))) {
member setFlag OVERRIDE
}
@@ -3945,8 +3944,22 @@ trait Typers { self: Analyzer =>
typed(tree, EXPRmode | FUNmode | POLYmode | TAPPmode, WildcardType)
/** Types a pattern with prototype <code>pt</code> */
- def typedPattern(tree: Tree, pt: Type): Tree =
+ def typedPattern(tree: Tree, pt: Type): Tree = {
+ // The commented out code stems from investigation into whether
+ // "abc" match { case Seq('a', 'b', 'c') => true }
+ // can be ruled out statically. At present this is a runtime
+ // error both because there is an implicit from String to Seq
+ // (even though such implicits are not used by the matcher) and
+ // because the typer is fine with concluding that "abc" might
+ // be of type "String with Seq[T]" and thus eligible for a call
+ // to unapplySeq.
+ //
+ // val savedImplicitsEnabled = context.implicitsEnabled
+ // context.implicitsEnabled = false
+ // try
typed(tree, PATTERNmode, pt)
+ // finally context.implicitsEnabled = savedImplicitsEnabled
+ }
/** Types a (fully parameterized) type tree */
def typedType(tree: Tree, mode: Int): Tree =