summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-12-04 17:41:36 +0000
committerMartin Odersky <odersky@gmail.com>2006-12-04 17:41:36 +0000
commit67dfced37f9b5d7a2b7f80f4da7fb5716f557350 (patch)
treec62c6fafcd14d847d45baa8b6155d9c52b76cbfc
parent525018c3cab1aaeb6644e9dacae2ab36ffa28d13 (diff)
downloadscala-67dfced37f9b5d7a2b7f80f4da7fb5716f557350.tar.gz
scala-67dfced37f9b5d7a2b7f80f4da7fb5716f557350.tar.bz2
scala-67dfced37f9b5d7a2b7f80f4da7fb5716f557350.zip
added infix type constructors
added &: infix constructor for pairs optimization to remove redudant outer pointers
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala20
-rw-r--r--src/library/scala/Function.scala2
-rw-r--r--src/library/scala/Predef.scala48
-rw-r--r--test/files/neg/bug845.check4
-rw-r--r--test/files/neg/bug845.scala16
9 files changed, 83 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 844d74cea5..23ba5df865 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1,4 +1,4 @@
-/* NSC -- new Scala compiler
+ /* NSC -- new Scala compiler
* Copyright 2005-2006 LAMP/EPFL
* @author Martin Odersky
*/
@@ -49,6 +49,7 @@ trait Types requires SymbolTable {
private var checkMalformedSwitch = true
private var globalVariance = 1
private final val healTypes = false
+ private final val LubGlbMargin = 0
val emptyTypeArray = new Array[Type](0)
@@ -717,7 +718,7 @@ trait Types requires SymbolTable {
case RefinedType(parents, decls) =>
assert(decls.isEmpty)
//Console.println("compute closure of "+this+" => glb("+parents+")")
- closureCache(j) = mergePrefixAndArgs(parents, -1, maxClosureDepth(parents)) match {
+ closureCache(j) = mergePrefixAndArgs(parents, -1, maxClosureDepth(parents) + LubGlbMargin) match {
case Some(tp0) => tp0
case None => throw new MalformedClosure(parents)
}
@@ -2168,7 +2169,7 @@ trait Types requires SymbolTable {
if (rest exists (t1 => t <:< t1)) rest else t :: rest
}
- def lub(ts: List[Type]): Type = lub(ts, maxClosureDepth(ts))
+ def lub(ts: List[Type]): Type = lub(ts, maxClosureDepth(ts) + LubGlbMargin)
/** The least upper bound wrt &lt;:&lt; of a list of types */
def lub(ts: List[Type], depth: int): Type = {
@@ -2250,7 +2251,7 @@ trait Types requires SymbolTable {
res
}
- def glb(ts: List[Type]): Type = glb(ts, maxClosureDepth(ts))
+ def glb(ts: List[Type]): Type = glb(ts, maxClosureDepth(ts) + LubGlbMargin)
/** The greatest lower bound wrt &lt;:&lt; of a list of types */
private def glb(ts: List[Type], depth: int): Type = {
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 9849af6dcf..54ea55dde8 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -74,7 +74,7 @@ abstract class Constructors extends Transform {
}
else if (tree.symbol.outerSource == clazz && !clazz.isImplClass) {
thisRefSeen = false
- gen.mkAttributedIdent(parameterNamed(nme.OUTER))
+ gen.mkAttributedIdent(parameterNamed(nme.OUTER)) setPos tree.pos
}
else
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9df54f371a..17b3798e34 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -227,8 +227,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
gen.mkRuntimeCall(nme.arrayValue, List(tree1, Literal(pt.typeArgs.head)))
}
else {
- Apply(gen.mkAttributedRef(unboxMethod(pt.symbol)), List(tree)).
- setPos(tree.pos) setType pt
+ atPos(tree.pos) {
+ Apply(gen.mkAttributedRef(unboxMethod(pt.symbol)), List(tree)) setType pt
+ }
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 2080baff5c..70996371b8 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -37,6 +37,17 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
private def isInner(clazz: Symbol) =
!clazz.isPackageClass && !clazz.outerClass.isStaticOwner
+ /** Does given <code>clazz</code> define an outer field? */
+ def hasOuterField(clazz: Symbol) = {
+ def hasSameOuter(parent: Type) =
+ parent.symbol.isClass &&
+ clazz.owner.isClass &&
+ clazz.owner == parent.symbol.owner &&
+ parent.prefix =:= clazz.owner.thisType
+ isInner(clazz) && !clazz.isTrait &&
+ (clazz.info.parents.isEmpty || !hasSameOuter(clazz.info.parents.head))
+ }
+
private def outerField(clazz: Symbol): Symbol = {
val result = clazz.info.member(nme.getterToLocal(nme.OUTER))
if (result == NoSymbol)
@@ -184,12 +195,12 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
outerAcc.expandName(clazz)
val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType
decls1 enter clazz.newOuterAccessor(clazz.pos).setInfo(MethodType(List(), restpe))
- if (!clazz.isTrait) // 2
- //todo: avoid outer field if superclass has same outer value?
+ if (hasOuterField(clazz)) { //2
decls1 enter (
clazz.newValue(clazz.pos, nme.getterToLocal(nme.OUTER))
setFlag (SYNTHETIC | PROTECTED | PARAMACCESSOR)
setInfo clazz.outerClass.thisType)
+ }
}
if (!clazz.isTrait && !parents.isEmpty) {
for (val mc <- clazz.mixinClasses) {
@@ -513,7 +524,8 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
atOwner(tree, currentOwner) {
if (!(currentClass hasFlag INTERFACE) || (currentClass hasFlag lateINTERFACE)) {
if (isInner(currentClass)) {
- if (!currentClass.isTrait) newDefs += outerFieldDef // (1a)
+ if (hasOuterField(currentClass))
+ newDefs += outerFieldDef // (1a)
newDefs += outerAccessorDef // (1)
}
if (!currentClass.isTrait)
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 5871edbf10..2cceae8059 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -48,14 +48,20 @@ abstract class TreeCheckers extends Analyzer {
case EmptyTree | TypeTree() =>
;
case _ =>
- if (!tpeOfTree.contains(tree)) {
- tpeOfTree.update(tree, tree.tpe)
- tree.tpe = null
+ try {
+ if (!tpeOfTree.contains(tree)) {
+ tpeOfTree.update(tree, tree.tpe)
+ tree.tpe = null
+ }
+ val newtree = super.typed(tree, mode, pt);
+ if ((newtree ne tree) && !newtree.isInstanceOf[Literal])
+ error(tree.pos, "trees differ\n old: " + tree + " [" + tree.getClass() +
+ "]\n new: " + newtree + " [" + newtree.getClass() + "]")
+ } catch {
+ case ex: Throwable =>
+ Console.println("exception while typing "+tree)
+ throw ex
}
- val newtree = super.typed(tree, mode, pt);
- if ((newtree ne tree) && !newtree.isInstanceOf[Literal])
- error(tree.pos, "trees differ\n old: " + tree + " [" + tree.getClass() +
- "]\n new: " + newtree + " [" + newtree.getClass() + "]")
}
tree
}
diff --git a/src/library/scala/Function.scala b/src/library/scala/Function.scala
index 6f4c14ed55..12e124779b 100644
--- a/src/library/scala/Function.scala
+++ b/src/library/scala/Function.scala
@@ -16,7 +16,7 @@ package scala
* @author Martin Odersky
* @version 1.0, 29/11/2006
*/
-object Function extends Application {
+object Function {
/** Given a sequence of functions <code>f<sub>1</sub></code>, ...,
* <code>f<sub>n</sub></code>, return the function <code>f<sub>1</sub>
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 9985a4f855..1422aa6d0d 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -54,29 +54,7 @@ object Predef {
type NoSuchElementException = java.util.NoSuchElementException
type NumberFormatException = java.lang.NumberFormatException
-/*
- type ~[a, b] = Tuple2[a, b]
- class FirstOfPair[a](x: a) {
- def ~[b](y: b): Tuple2[a, b] = Tuple2(x, y)
- }
- implicit def any2firstOfPair[a](x: a): FirstOfPair[a] = new FirstOfPair(x)
-*/
-
- type Pair[+a, +b] = Tuple2[a, b]
- def Pair[a, b](x: a, y: b) = Tuple2(x, y)
-
- type Triple[+a, +b, +c] = Tuple3[a, b, c]
- def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z)
-
- def Tuple[a1](x1: a1) = Tuple1(x1)
- def Tuple[a1, a2](x1: a1, x2: a2) = Tuple2(x1, x2)
- def Tuple[a1, a2, a3](x1: a1, x2: a2, x3: a3) = Tuple3(x1, x2, x3)
- def Tuple[a1, a2, a3, a4](x1: a1, x2: a2, x3: a3, x4: a4) = Tuple4(x1, x2, x3, x4)
- def Tuple[a1, a2, a3, a4, a5](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5) = Tuple5(x1, x2, x3, x4, x5)
- def Tuple[a1, a2, a3, a4, a5, a6](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6) = Tuple6(x1, x2, x3, x4, x5, x6)
- def Tuple[a1, a2, a3, a4, a5, a6, a7](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7) = Tuple7(x1, x2, x3, x4, x5, x6, x7)
- def Tuple[a1, a2, a3, a4, a5, a6, a7, a8](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7, x8: a8) = Tuple8(x1, x2, x3, x4, x5, x6, x7, x8)
- def Tuple[a1, a2, a3, a4, a5, a6, a7, a8, a9](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7, x8: a8, x9: a9) = Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9)
+ // --- Miscelleaneous -----------------------------------------------
val $scope = scala.xml.TopScope
@@ -113,6 +91,30 @@ object Predef {
throw new Error("assumption failed: " + message)
}
+ // --- Tupling ----------------------------------------------
+
+ type Pair[+a, +b] = Tuple2[a, b]
+ def Pair[a, b](x: a, y: b) = Tuple2(x, y)
+
+ type Triple[+a, +b, +c] = Tuple3[a, b, c]
+ def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z)
+
+ type &: [+a, +b] = Tuple2[a, b]
+ class SndOfPair[+b](y: b) {
+ def &: [a](x: a): Tuple2[a, b] = Tuple2(x, y)
+ }
+ implicit def any2sndOfPair[b](x: b): SndOfPair[b] = new SndOfPair(x)
+
+ def Tuple[a1](x1: a1) = Tuple1(x1)
+ def Tuple[a1, a2](x1: a1, x2: a2) = Tuple2(x1, x2)
+ def Tuple[a1, a2, a3](x1: a1, x2: a2, x3: a3) = Tuple3(x1, x2, x3)
+ def Tuple[a1, a2, a3, a4](x1: a1, x2: a2, x3: a3, x4: a4) = Tuple4(x1, x2, x3, x4)
+ def Tuple[a1, a2, a3, a4, a5](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5) = Tuple5(x1, x2, x3, x4, x5)
+ def Tuple[a1, a2, a3, a4, a5, a6](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6) = Tuple6(x1, x2, x3, x4, x5, x6)
+ def Tuple[a1, a2, a3, a4, a5, a6, a7](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7) = Tuple7(x1, x2, x3, x4, x5, x6, x7)
+ def Tuple[a1, a2, a3, a4, a5, a6, a7, a8](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7, x8: a8) = Tuple8(x1, x2, x3, x4, x5, x6, x7, x8)
+ def Tuple[a1, a2, a3, a4, a5, a6, a7, a8, a9](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7, x8: a8, x9: a9) = Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9)
+
// views -------------------------------------------------------------
implicit def identity[a](x: a): a = x
diff --git a/test/files/neg/bug845.check b/test/files/neg/bug845.check
new file mode 100644
index 0000000000..1750611993
--- /dev/null
+++ b/test/files/neg/bug845.check
@@ -0,0 +1,4 @@
+bug845.scala:4 error: only classes can have declared but undefined members
+ type Bar;
+ ^
+one error found
diff --git a/test/files/neg/bug845.scala b/test/files/neg/bug845.scala
new file mode 100644
index 0000000000..c8a2faa671
--- /dev/null
+++ b/test/files/neg/bug845.scala
@@ -0,0 +1,16 @@
+package test;
+
+object Test extends Application {
+ type Bar;
+ trait FooImpl;
+
+ trait Bob {
+ def bar : Bar with FooImpl;
+ }
+ def ifn[A,B](a : A)(f : A => B) =
+ if (a != null) f(a) else null;
+
+ val bob : Bob = null;
+ val bar = ifn(bob)(.bar);
+ assert(bar == null);
+}