diff options
author | Paul Phillips <paulp@improving.org> | 2009-10-21 20:57:27 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-10-21 20:57:27 +0000 |
commit | 7349476e5cf7984acf40055cb55d78cbaed41043 (patch) | |
tree | 527229fd0cdab2451fd9feabfcdef2730f9ec453 /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | 322b823276a3f40db95bb3306c842021e77572df (diff) | |
download | scala-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.scala | 65 |
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 = |