summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-03-05 15:31:40 +0000
committerMartin Odersky <odersky@gmail.com>2010-03-05 15:31:40 +0000
commit87b2ffd8db7a2d236a85b2e0f9e4dcd4db15b001 (patch)
tree8c16e4eff5cd573b222bb9877a7467eeb2a9abcd /src
parent34b2093601b4047d27d848df603895629ed31c0e (diff)
downloadscala-87b2ffd8db7a2d236a85b2e0f9e4dcd4db15b001.tar.gz
scala-87b2ffd8db7a2d236a85b2e0f9e4dcd4db15b001.tar.bz2
scala-87b2ffd8db7a2d236a85b2e0f9e4dcd4db15b001.zip
Closes #3037. Review by extempore.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala13
3 files changed, 36 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index d540b67c82..f1a9a8ae97 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -582,7 +582,9 @@ trait Definitions extends reflect.generic.StandardDefinitions {
}
}
- /** Test whether a method symbol is that of a boxing method. */
+ /** Test whether a method symbol is that of a boxing method
+ * Martin @Paul: why the condition? Is not (boxMethod.valuesIterator contains m) enough?
+ */
def isBox(m: Symbol) = (boxMethod.valuesIterator contains m) && cond(m.tpe) {
case MethodType(List(arg), _) => cond(boxMethod get arg.tpe.typeSymbol) {
case Some(`m`) => true
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index f37b809744..ba6ef7168b 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -432,6 +432,24 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
override def newTyper(context: Context) = new Eraser(context)
+ /** An extractor object for boxed expressions
+ object Boxed {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case LabelDef(name, params, Boxed(rhs)) =>
+ Some(treeCopy.LabelDef(tree, name, params, rhs) setType rhs.tpe)
+ case Select(_, _) if tree.symbol == BoxedUnit_UNIT =>
+ Some(Literal(()) setPos tree.pos setType UnitClass.tpe)
+ case Block(List(unboxed), ret @ Select(_, _)) if ret.symbol == BoxedUnit_UNIT =>
+ Some(if (unboxed.tpe.typeSymbol == UnitClass) tree
+ else Block(List(unboxed), Literal(()) setPos tree.pos setType UnitClass.tpe))
+ case Apply(fn, List(unboxed)) if isBox(fn.symbol) =>
+ Some(unboxed)
+ case _ =>
+ None
+ }
+ }
+ */
+
/** The modifier typer which retypes with erased types. */
class Eraser(context: Context) extends Typer(context) {
@@ -458,6 +476,11 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
* @return the unboxed tree
*/
private def unbox(tree: Tree, pt: Type): Tree = tree match {
+/*
+ case Boxed(unboxed) =>
+ println("unbox shorten: "+tree) // this never seems to kick in during build and test; therefore disabled.
+ adaptToType(unboxed, pt)
+ */
case LabelDef(name, params, rhs) =>
val rhs1 = unbox(rhs, pt)
treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe
@@ -564,7 +587,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
//Console.println("adaptMember: " + tree);
tree match {
case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_asInstanceOf =>
- val qual1 = typedQualifier(qual)
+ val qual1 = typedQualifier(qual, NOmode, ObjectClass.tpe) // need to have an expected type, see #3037
val qualClass = qual1.tpe.typeSymbol
val targClass = targ.tpe.typeSymbol
/*
@@ -585,7 +608,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
else if (tree.symbol.owner == AnyClass)
adaptMember(atPos(tree.pos)(Select(qual, getMember(ObjectClass, name))))
else {
- var qual1 = typedQualifier(qual);
+ var qual1 = typedQualifier(qual)
if ((isValueClass(qual1.tpe.typeSymbol) && !isUnboxedValueMember(tree.symbol)))
qual1 = box(qual1)
else if (!isValueClass(qual1.tpe.typeSymbol) && isUnboxedValueMember(tree.symbol))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b0afda02f1..d6eafcde39 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4185,14 +4185,17 @@ trait Typers { self: Analyzer =>
/** Types qualifier <code>tree</code> of a select node.
* E.g. is tree occurs in a context like <code>tree.m</code>.
- *
- * @param tree ...
- * @return ...
+ */
+ def typedQualifier(tree: Tree, mode: Int, pt: Type): Tree =
+ typed(tree, EXPRmode | QUALmode | POLYmode | mode & TYPEPATmode, pt) // TR: don't set BYVALmode, since qualifier might end up as by-name param to an implicit
+
+ /** Types qualifier <code>tree</code> of a select node.
+ * E.g. is tree occurs in a context like <code>tree.m</code>.
*/
def typedQualifier(tree: Tree, mode: Int): Tree =
- typed(tree, EXPRmode | QUALmode | POLYmode | mode & TYPEPATmode, WildcardType) // TR: don't set BYVALmode, since qualifier might end up as by-name param to an implicit
+ typedQualifier(tree, mode, WildcardType)
- def typedQualifier(tree: Tree): Tree = typedQualifier(tree, NOmode)
+ def typedQualifier(tree: Tree): Tree = typedQualifier(tree, NOmode, WildcardType)
/** Types function part of an application */
def typedOperator(tree: Tree): Tree =