summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2011-10-20 22:29:04 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2011-10-20 22:29:04 +0000
commitd5b81b6cb1f3880a791118609c2d308c34c075f2 (patch)
treee67554e7045d8edf600b9da76bca743e6b296ee4
parent8704ed2fc92e3d82287317fe34126c5d4d84e10c (diff)
downloadscala-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
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala1
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala7
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala29
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--src/library/scala/Predef.scala2
10 files changed, 29 insertions, 23 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)
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 1d3239a176..018cbdefd7 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -111,7 +111,7 @@ object Predef extends LowPriorityImplicits {
// Minor variations on identity functions
def identity[A](x: A): A = x // @see `conforms` for the implicit version
- def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world
+ @inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero`
@inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements
// Apparently needed for the xml library