diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-10-20 22:29:04 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-10-20 22:29:04 +0000 |
commit | d5b81b6cb1f3880a791118609c2d308c34c075f2 (patch) | |
tree | e67554e7045d8edf600b9da76bca743e6b296ee4 /src/compiler | |
parent | 8704ed2fc92e3d82287317fe34126c5d4d84e10c (diff) | |
download | scala-d5b81b6cb1f3880a791118609c2d308c34c075f2.tar.gz scala-d5b81b6cb1f3880a791118609c2d308c34c075f2.tar.bz2 scala-d5b81b6cb1f3880a791118609c2d308c34c075f2.zip |
misc fixes while working on virtualizing patter...
misc fixes while working on virtualizing pattern matching not directly
related to pattern matching, though
review by extempore
Diffstat (limited to 'src/compiler')
9 files changed, 28 insertions, 22 deletions
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala index 9ff2232840..01a93c0ada 100644 --- a/src/compiler/scala/reflect/internal/NameManglers.scala +++ b/src/compiler/scala/reflect/internal/NameManglers.scala @@ -72,7 +72,6 @@ trait NameManglers { val LOCALDUMMY_PREFIX = "<local " // owner of local blocks val PROTECTED_PREFIX = "protected$" val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set" - val SELECTOR_DUMMY = "<unapply-selector>" val SETTER_SUFFIX = encode("_=") val SINGLETON_SUFFIX = ".type" val SUPER_PREFIX_STRING = "super$" diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 254c2e3b7e..a59a9040bc 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -187,6 +187,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy val SPECIALIZED_INSTANCE: NameType = "specInstance$" val STAR: NameType = "*" val THIS: NameType = "_$this" + val SELECTOR_DUMMY: NameType = "<unapply-selector>" final val Nil: NameType = "Nil" final val Predef: NameType = "Predef" diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 88eb79c9d8..c469834ac8 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -279,7 +279,7 @@ trait Trees extends api.Trees { self: SymbolTable => override def traverse(t: Tree) { if (t != EmptyTree && t.pos == NoPosition) { t.setPos(pos) - super.traverse(t) + super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? } } } @@ -320,12 +320,15 @@ trait Trees extends api.Trees { self: SymbolTable => "subst[%s, %s](%s)".format(fromStr, toStr, (from, to).zipped map (_ + " -> " + _) mkString ", ") } + // NOTE: if symbols in `from` occur multiple times in the `tree` passed to `transform`, + // the resulting Tree will be a graph, not a tree... this breaks all sorts of stuff, + // notably concerning the mutable aspects of Trees (such as setting their .tpe) class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { override def transform(tree: Tree): Tree = tree match { case Ident(_) => def subst(from: List[Symbol], to: List[Tree]): Tree = if (from.isEmpty) tree - else if (tree.symbol == from.head) to.head + else if (tree.symbol == from.head) to.head.shallowDuplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? else subst(from.tail, to.tail); subst(from, to) case _ => diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index a0bd994a97..aaf4ae5561 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2568,6 +2568,7 @@ A type's typeSymbol should never be inspected directly. // would be pointless. In this case, each check we perform causes us to lose specificity: in // the end the best we'll do is the least specific type we tested against, since the typevar // does not see these checks as "probes" but as requirements to fulfill. + // TODO: the `suspended` flag can be used to poke around with leaving a trace // // So the strategy used here is to test first the type, then the direct parents, and finally // to fall back on the individual base types. This warrants eventual re-examination. diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index 60e761048b..8add556741 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -68,7 +68,7 @@ trait TreeDSL { /** Note - calling ANY_== in the matcher caused primitives to get boxed * for the comparison, whereas looking up nme.EQ does not. See #3570 for * an example of how target.tpe can be non-null, yet it claims not to have - * a mmeber called nme.EQ. Not sure if that should happen, but we can be + * a member called nme.EQ. Not sure if that should happen, but we can be * robust by dragging in Any regardless. */ def MEMBER_== (other: Tree) = { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index cc87ea7e06..aaae703d06 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -476,7 +476,8 @@ abstract class Erasure extends AddInterfaces else BLOCK(tree, UNIT) case x => assert(x != ArrayClass) - Apply(unboxMethod(pt.typeSymbol), tree) setType pt + // don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type + Apply(unboxMethod(pt.typeSymbol), tree) }) } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 0181c80bff..c7d3b331a6 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1135,7 +1135,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { */ private def postTransform(tree: Tree): Tree = { val sym = tree.symbol - + // assert(tree.tpe ne null, tree.getClass +" : "+ tree +" in "+ localTyper.context.tree) // change every node type that refers to an implementation class to its // corresponding interface, unless the node's symbol is an implementation class. if (tree.tpe.typeSymbol.isImplClass && ((sym eq null) || !sym.isImplClass)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index f6fc6cedd2..7debe23a89 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -640,21 +640,22 @@ trait Infer { * type parameters that are inferred as `scala.Nothing` and that are not covariant in <code>restpe</code> are taken to be undetermined */ def adjustTypeArgs(tparams: List[Symbol], tvars: List[TypeVar], targs: List[Type], restpe: Type = WildcardType): AdjustedTypeArgs.Result = { - @inline def notCovariantIn(tparam: Symbol, restpe: Type) = - (varianceInType(restpe)(tparam) & COVARIANT) == 0 // tparam occurred non-covariantly (in invariant or contravariant position) + @inline def keep(targ: Type, tparam: Symbol) = ( + targ.typeSymbol != NothingClass // definitely not retracting, it's not Nothing! + || (!restpe.isWildcard && (varianceInType(restpe)(tparam) & COVARIANT) != 0)) // occured covariantly --> don't retract + + @inline def adjusted(targ: Type, tvar: TypeVar) = + if (targ.typeSymbol == RepeatedParamClass) + targ.baseType(SeqClass) + else if (targ.typeSymbol == JavaRepeatedParamClass) + targ.baseType(ArrayClass) + else if (targ.typeSymbol.isModuleClass || (opt.experimental && tvar.constr.avoidWiden)) + targ // this infers Foo.type instead of "object Foo" (see also widenIfNecessary) + else + targ.widen - (tparams, tvars, targs).zipped.map{ (tparam, tvar, targ) => - if (targ.typeSymbol == NothingClass && - (restpe.isWildcard || notCovariantIn(tparam, restpe))) { - tparam -> None - } else { - tparam -> Some( - if (targ.typeSymbol == RepeatedParamClass) targ.baseType(SeqClass) - else if (targ.typeSymbol == JavaRepeatedParamClass) targ.baseType(ArrayClass) - else if (targ.typeSymbol.isModuleClass || (opt.experimental && tvar.constr.avoidWiden)) targ // this infers Foo.type instead of "object Foo" (see also widenIfNecessary) - else targ.widen - ) - } + (tparams, tvars, targs).zipped.map { (tparam, tvar, targ) => + tparam -> (if(keep(targ, tparam)) Some(adjusted(targ, tvar)) else None) }(collection.breakOut) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 097def8390..b68b4d708e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -511,8 +511,8 @@ trait Typers extends Modes with Adaptations { private def makeAccessible(tree: Tree, sym: Symbol, pre: Type, site: Tree): (Tree, Type) = if (isInPackageObject(sym, pre.typeSymbol)) { if (pre.typeSymbol == ScalaPackageClass && sym.isTerm) { - // short cut some aliases. It seems that without that pattern matching - // fails to notice exhaustiveness and to generate good code when + // short cut some aliases. It seems pattern matching needs this + // to notice exhaustiveness and to generate good code when // List extractors are mixed with :: patterns. See Test5 in lists.scala. def dealias(sym: Symbol) = (atPos(tree.pos) {gen.mkAttributedRef(sym)}, sym.owner.thisType) |