summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-08-27 14:45:35 +0000
committerMartin Odersky <odersky@gmail.com>2009-08-27 14:45:35 +0000
commita04195e63727872f04ad01900a18f6ca9ec5cf2b (patch)
tree48964da67438a04e802a5c2324f0a02f2d22efb7 /src/compiler
parent2c39b8b0839a5dfd48dfd073944f7b176cc63f4b (diff)
downloadscala-a04195e63727872f04ad01900a18f6ca9ec5cf2b.tar.gz
scala-a04195e63727872f04ad01900a18f6ca9ec5cf2b.tar.bz2
scala-a04195e63727872f04ad01900a18f6ca9ec5cf2b.zip
added manifests to most parts of standard libra...
added manifests to most parts of standard library which deal with arrays. One test is temporarily disabled, as it shows a deep problem with multi-dimensional arrays (which was present all along).
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala28
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala21
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala22
9 files changed, 60 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index aa057c43b5..66b358383d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -512,7 +512,7 @@ abstract class TreeBuilder {
if (contextBounds.isEmpty) vparamss
else {
val mods = Modifiers(if (owner.isTypeName) PARAMACCESSOR | LOCAL | PRIVATE else PARAM)
- def makeEvidenceParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName("man$"), tpt, EmptyTree)
+ def makeEvidenceParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName(nme.EVIDENCE_PARAM_PREFIX), tpt, EmptyTree)
vparamss ::: List(contextBounds map makeEvidenceParam)
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 71f005a98a..87c874465a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -649,6 +649,10 @@ trait Definitions {
addModuleMethod(DoubleClass, "NegativeInfinity", java.lang.Double.NEGATIVE_INFINITY)
}
+ /** Is symbol a phantom class for which no runtime representation exists? */
+ def isPhantomClass(sym: Symbol) =
+ sym == AnyClass || sym == AnyValClass || sym == NullClass || sym == NothingClass
+
/** Is symbol a value class? */
def isValueClass(sym: Symbol): Boolean =
(sym eq UnitClass) || (boxedClass contains sym)
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 5426a76643..894291d4dc 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -82,6 +82,7 @@ trait StdNames {
val INTERPRETER_VAR_PREFIX = "res"
val INTERPRETER_IMPORT_WRAPPER = "$iw"
val INTERPRETER_SYNTHVAR_PREFIX = "synthvar$"
+ val EVIDENCE_PARAM_PREFIX = "evidence$"
def LOCAL(clazz: Symbol) = newTermName(LOCALDUMMY_PREFIX_STRING + clazz.name+">")
def TUPLE_FIELD(index: Int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index c3de8d6bd9..6618480d58 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -21,10 +21,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
// @S: XXX: why is this here? earsure is a typer, if you comment this
// out erasure still works, uses its own typed methods.
lazy val typerXXX = this.typer
- import typerXXX.{typed} // methods to type trees
+ import typerXXX.{typed, typedPos} // methods to type trees
import CODE._
- def typedPos(pos: Position)(tree: Tree) = typed { atPos(pos)(tree) }
val phaseName: String = "erasure"
@@ -387,7 +386,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
})
}
- /** generate ScalaRuntime.boxArray(tree) */
+ /** generate ScalaRuntime.boxArray(tree)
+ * !!! todo: optimize this in case the runtime type is known
+ */
private def boxArray(tree: Tree): Tree = tree match {
case LabelDef(name, params, rhs) =>
val rhs1 = boxArray(rhs)
@@ -451,12 +452,12 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
ELSE (x())
)
)
- else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass) once (x =>
- (IF (x() IS_OBJ BoxedArrayClass.tpe) THEN (x()) ELSE boxArray(x()))
- )
- else if (isSeqClass(pt.typeSymbol)) once (x =>
- (IF (x() IS_OBJ pt) THEN (x()) ELSE (boxArray(x())))
- )
+ else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass)
+ once (x =>
+ (IF (x() IS_OBJ BoxedArrayClass.tpe) THEN (x()) ELSE boxArray(x())))
+ else if (isSeqClass(pt.typeSymbol))
+ once (x =>
+ (IF (x() IS_OBJ pt) THEN (x()) ELSE (boxArray(x()))))
else asPt(tree)
} else asPt(tree)
}
@@ -560,12 +561,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
tree match {
case Apply(Select(New(tpt), name), args) if (tpt.tpe.typeSymbol == BoxedArrayClass) =>
assert(name == nme.CONSTRUCTOR);
- val translated: Tree =
- if (args.length >= 2) REF(ArrayModule) DOT nme.ofDim
- else NEW(BoxedAnyArrayClass) DOT name
-
- atPos(tree.pos) {
- Typed(Apply(translated, args), tpt)
+ assert(args.length < 2)
+ typedPos(tree.pos) {
+ Typed(Apply(NEW(BoxedAnyArrayClass) DOT name, args), tpt)
}
case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_asInstanceOf =>
val qual1 = typedQualifier(qual)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 7af0c4f56c..9b2b9e2248 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -392,15 +392,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
if (traversableTpe != NoType && toArray != NoSymbol) {
val arguments =
if (toArray.tpe.paramTypes.isEmpty) List() // !!! old style toArray
- else { // new style, with manifest
- val manifestOpt = localTyper.findManifest(tree.tpe.typeArgs.head, false)
- if (manifestOpt.tree.isEmpty) {
- unit.error(tree.pos, "cannot find class manifest for element type of "+tree.tpe)
- List(Literal(Constant(null)))
- } else {
- List(manifestOpt.tree)
- }
- }
+ else List(localTyper.getManifestTree(tree.pos, tree.tpe.typeArgs.head, false)) // new style, with manifest
atPhase(phase.next) {
localTyper.typed {
atPos(pos) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 9d3cccab37..7ebaa27872 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -599,7 +599,7 @@ self: Analyzer =>
* reflect.Manifest for type 'tp'. An EmptyTree is returned if
* no manifest is found. todo: make this instantiate take type params as well?
*/
- def manifestOfType(tp: Type, full: Boolean): Tree = {
+ private def manifestOfType(tp: Type, full: Boolean): Tree = {
/** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
def manifestFactoryCall(constructor: String, args: Tree*): Tree =
@@ -627,25 +627,22 @@ self: Analyzer =>
case ConstantType(value) =>
manifestOfType(tp0.deconst, full)
case TypeRef(pre, sym, args) =>
- if (isValueClass(sym)) {
+ if (isValueClass(sym) || isPhantomClass(sym)) {
typed { atPos(tree.pos.focus) {
Select(gen.mkAttributedRef(FullManifestModule), sym.name.toString)
}}
- }
- else if (sym.isClass) {
+ } else if (sym.isClass) {
val suffix = gen.mkClassOf(tp0) :: (args map findSubManifest)
manifestFactoryCall(
"classType",
(if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix
else findSubManifest(pre) :: suffix): _*)
- }
- else if (sym.isTypeParameterOrSkolem || sym.isExistential) {
- EmptyTree // a manifest should have been found by normal searchImplicit
- }
- else {
+ } else if (sym.isAbstractType && !sym.isTypeParameterOrSkolem && !sym.isExistential) {
manifestFactoryCall(
"abstractType",
findSubManifest(pre) :: Literal(sym.name.toString) :: findManifest(tp0.bounds.hi) :: (args map findSubManifest): _*)
+ } else {
+ EmptyTree // a manifest should have been found by normal searchImplicit
}
case RefinedType(parents, decls) =>
// refinement is not generated yet
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index d86c9f3b44..25af71be19 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -31,7 +31,7 @@ trait NamesDefaults { self: Analyzer =>
/** @param pos maps indicies from old to new */
- def reorderArgs[T](args: List[T], pos: Int => Int): List[T] = {
+ def reorderArgs[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
val res = new Array[T](args.length)
// (hopefully) faster than zipWithIndex
(0 /: args) { case (index, arg) => res(pos(index)) = arg; index + 1 }
@@ -39,7 +39,7 @@ trait NamesDefaults { self: Analyzer =>
}
/** @param pos maps indicies from new to old (!) */
- def reorderArgsInv[T](args: List[T], pos: Int => Int): List[T] = {
+ def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
val argsArray = args.toArray
val res = new ListBuffer[T]
for (i <- 0 until argsArray.length)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 42d0dd80fb..3dec50e03d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -708,13 +708,7 @@ abstract class RefChecks extends InfoTransform {
List(transform(cdef))
}
} else {
- val vdef =
- localTyper.typed {
- atPos(tree.pos) {
- gen.mkModuleVarDef(sym)
- }
- }
-
+ val vdef = localTyper.typedPos(tree.pos) { gen.mkModuleVarDef(sym) }
val ddef =
atPhase(phase.next) {
localTyper.typed {
@@ -930,6 +924,19 @@ abstract class RefChecks extends InfoTransform {
if (tpt.tpe.typeSymbol == ArrayClass && args.length >= 2) =>
unit.deprecationWarning(tree.pos,
"new Array(...) with multiple dimensions has been deprecated; use Array.ofDim(...) instead")
+ val manif = {
+ var etpe = tpt.tpe
+ for (_ <- args) { etpe = etpe.typeArgs.headOption.getOrElse(NoType) }
+ if (etpe == NoType) {
+ unit.error(tree.pos, "too many dimensions for array creation")
+ Literal(Constant(null))
+ } else {
+ localTyper.getManifestTree(tree.pos, etpe, false)
+ }
+ }
+ result = localTyper.typedPos(tree.pos) {
+ Apply(Apply(Select(gen.mkAttributedRef(ArrayModule), nme.ofDim), args), List(manif))
+ }
currentApplication = tree
case Apply(fn, args) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index cbb9129b30..372f8965e4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -180,7 +180,7 @@ trait Typers { self: Analyzer =>
def applyImplicitArgs(fun: Tree): Tree = fun.tpe match {
case MethodType(params, _) =>
var positional = true
- val argResults = params map (_.tpe) map (inferImplicit(fun, _, true, false, context))
+ val argResults = params map (p => inferImplicit(fun, p.tpe, true, false, context))
val args = argResults.zip(params) flatMap {
case (arg, param) =>
if (arg != SearchFailure) {
@@ -188,8 +188,10 @@ trait Typers { self: Analyzer =>
else List(atPos(arg.tree.pos)(new AssignOrNamedArg(Ident(param.name), (arg.tree))))
} else {
if (!param.hasFlag(DEFAULTPARAM))
- context.error(fun.pos, "could not find implicit value for parameter "+
- param.name +":"+ param.tpe +".")
+ context.error(
+ fun.pos, "could not find implicit value for "+
+ (if (param.name startsWith nme.EVIDENCE_PARAM_PREFIX) "evidence parameter of type "
+ else "parameter "+param.name+": ")+param.tpe)
positional = false
Nil
}
@@ -956,7 +958,7 @@ trait Typers { self: Analyzer =>
if (coercion != EmptyTree) {
if (settings.debug.value) log("inferred view from "+tree.tpe+" to "+pt+" = "+coercion+":"+coercion.tpe)
return newTyper(context.makeImplicit(context.reportAmbiguousErrors)).typed(
- Apply(coercion, List(tree)) setPos tree.pos, mode, pt)
+ Apply(coercion, List(tree)) setPos tree.pos, mode, pt)
}
}
}
@@ -3778,6 +3780,8 @@ trait Typers { self: Analyzer =>
ret
}
+ def typedPos(pos: Position)(tree: Tree) = typed(atPos(pos)(tree))
+
/** Types expression <code>tree</code> with given prototype <code>pt</code>.
*
* @param tree ...
@@ -3851,6 +3855,16 @@ trait Typers { self: Analyzer =>
EmptyTree,
appliedType((if (full) FullManifestClass else PartialManifestClass).typeConstructor, List(tp)),
true, false, context)
+
+ def getManifestTree(pos: Position, tp: Type, full: Boolean): Tree = {
+ val manifestOpt = findManifest(tp, false)
+ if (manifestOpt.tree.isEmpty) {
+ error(pos, "cannot find "+(if (full) "" else "class ")+"manifest for element type of "+tp)
+ Literal(Constant(null))
+ } else {
+ manifestOpt.tree
+ }
+ }
/*
def convertToTypeTree(tree: Tree): Tree = tree match {
case TypeTree() => tree