summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-07-08 13:19:33 +0000
committerMartin Odersky <odersky@gmail.com>2003-07-08 13:19:33 +0000
commitfedbced652b533da4baeea37c39c058d2cd2afd8 (patch)
tree6abfe4284db8f92c12fba14d671de6f7b827068e
parent639f1084419fb54acf6ee9f6c405e302ba21abd3 (diff)
downloadscala-fedbced652b533da4baeea37c39c058d2cd2afd8.tar.gz
scala-fedbced652b533da4baeea37c39c058d2cd2afd8.tar.bz2
scala-fedbced652b533da4baeea37c39c058d2cd2afd8.zip
*** empty log message ***
-rw-r--r--sources/scalac/symtab/Modifiers.java1
-rw-r--r--sources/scalac/symtab/Type.java6
-rw-r--r--sources/scalac/transformer/LambdaLift.java83
-rw-r--r--test/files/neg/bug52.check6
-rw-r--r--test/files/neg/bug52.scala4
-rw-r--r--test/files/neg/refine.check9
-rw-r--r--test/files/pos/bug30.scala9
-rw-r--r--test/files/pos/bug31.scala29
-rw-r--r--test/files/pos/bug36.scala8
-rw-r--r--test/files/pos/bug39.scala6
-rw-r--r--test/files/pos/refine.scala6
-rw-r--r--test/files/pos/seqtest2.scala13
-rw-r--r--test/neg/bug52.check6
-rw-r--r--test/neg/bug52.scala4
-rw-r--r--test/neg/refine.check9
-rw-r--r--test/pos/bug30.scala9
-rw-r--r--test/pos/bug31.scala29
-rw-r--r--test/pos/bug36.scala8
-rw-r--r--test/pos/bug39.scala6
-rw-r--r--test/pos/refine.scala6
-rw-r--r--test/pos/seqtest2.scala13
21 files changed, 251 insertions, 19 deletions
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index 00509ad16b..5948dc2157 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -48,6 +48,7 @@ public interface Modifiers {
int ACCESSOR = 0x04000000; // function is an access function for a
// value or variable
int BRIDGE = 0x08000000; // function is a bridge method.
+ int LIFTED = BRIDGE; // transient flag for lambdalift
int SNDTIME = BRIDGE; // debug
int INTERFACE = 0x10000000; // symbol is a Java interface
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 430bcaa5e9..ae2960bb4e 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -29,7 +29,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
public case ThisType(Symbol sym);
/** pre.sym.type
- * sym represents a value
+ * sym represents a valueS
*/
public case SingleType(Type pre, Symbol sym) {
assert this instanceof ExtSingleType;
@@ -1272,7 +1272,9 @@ public class Type implements Modifiers, Kinds, TypeTags {
case TypeRef(Type pre1, Symbol sym1, Type[] args1):
switch (this) {
case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym.name == sym1.name && pre.isSubType(pre1) &&
+ boolean samepre = pre.isSameAs(pre1);
+ if ((samepre && sym == sym1 /* fast case */ ||
+ !samepre && pre.isSubType(pre1) && sym == pre.rebind(sym1)) &&
isSubArgs(args, args1, sym.typeParams())
||
sym.kind == TYPE && pre.memberInfo(sym).isSubType(that))
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 1e90f95624..a86c39c793 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -50,6 +50,7 @@ public class LambdaLift extends OwnerTransformer
public void apply(Unit unit) {
global.log(unit.source.toString());
free.initialize(unit);
+ currentOwner = global.definitions.ROOT_CLASS;
unit.body = transformTemplateStats(unit.body, currentOwner);
}
@@ -315,42 +316,49 @@ public class LambdaLift extends OwnerTransformer
tree.type = descr.transform(tree.type, currentOwner);
//System.out.println(tree.type);//DEBUG
switch (tree) {
- case ClassDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
+ case Block(Tree[] stats):
+ for (int i = 0; i < stats.length; i++)
+ liftSymbol(stats[i]);
+ return copy.Block(tree, transform(stats));
+
+ case ClassDef(int mods, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
Symbol sym = tree.symbol();
- if (sym.isLocal()) {
- Symbol[] newtparams = ftvsParams(sym.constructor());
- Symbol[] newparams = fvsParams(sym.constructor());
- liftSymbol(sym, newtparams, newparams);
+ if ((mods & LIFTED) != 0) {
+ ((ClassDef) tree).mods &= ~LIFTED;
Tree tree1 = copy.ClassDef(
tree, sym,
- addTypeParams(transform(tparams, sym), newtparams),
- new ValDef[][]{addParams(transform(vparams, sym)[0], newparams)},
+ addTypeParams(transform(tparams, sym), newtparams(sym.constructor())),
+ new ValDef[][]{
+ addParams(transform(vparams, sym)[0], newparams(sym.constructor()))},
transform(tpe, sym),
transform(impl, sym));
liftedDefs.append(tree1);
return Tree.Empty;
} else {
+ assert !sym.isLocal() : sym;
return copy.ClassDef(
tree, sym,
- transform(tparams, sym), transform(vparams, sym), transform(tpe, sym),
+ transform(tparams, sym),
+ transform(vparams, sym),
+ transform(tpe, sym),
transform(impl, sym));
}
- case DefDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(int mods, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
Symbol sym = tree.symbol();
- if (sym.isLocal()) {
- Symbol[] newtparams = ftvsParams(sym);
- Symbol[] newparams = fvsParams(sym);
- liftSymbol(sym, newtparams, newparams);
+ if ((mods & LIFTED) != 0) {
+ ((DefDef) tree).mods &= ~LIFTED;
Tree tree1 = copy.DefDef(
tree, sym,
- addTypeParams(transform(tparams, sym), newtparams),
- new ValDef[][]{addParams(transform(vparams, sym)[0], newparams)},
+ addTypeParams(transform(tparams, sym), newtparams(sym)),
+ new ValDef[][]{
+ addParams(transform(vparams, sym)[0], newparams(sym))},
transform(tpe, sym),
transform(rhs, sym));
liftedDefs.append(tree1);
return Tree.Empty;
} else {
+ assert !sym.isLocal() : sym;
return copy.DefDef(
tree, sym,
transform(tparams, sym), transform(vparams, sym), transform(tpe, sym),
@@ -400,7 +408,8 @@ public class LambdaLift extends OwnerTransformer
default:
Tree[] targs = addFreeArgs(
tree.pos, get(free.ftvs, fsym), Tree.EMPTY_ARRAY);
- if (targs.length > 0) fn1 = gen.TypeApply(fn1, targs);
+ if (targs.length > 0)
+ fn1 = gen.TypeApply(fn1, targs);
}
Tree[] args1 = transform(args);
return copy.Apply(
@@ -451,11 +460,47 @@ public class LambdaLift extends OwnerTransformer
return params;
}
- /** change symbol so that
+ Symbol[] newtparams(Symbol owner) {
+ Symbol[] tparams = owner.typeAt(descr.nextPhase).typeParams();
+ int nfree = get(free.ftvs, owner).size();
+ assert nfree == tparams.length - owner.type().typeParams().length
+ : owner + " " + nfree + " " + tparams.length + " " + owner.type().firstParams().length;
+ Symbol[] newtparams = new Symbol[nfree];
+ System.arraycopy(tparams, tparams.length - nfree, newtparams, 0, nfree);
+ return newtparams;
+ }
+
+ Symbol[] newparams(Symbol owner) {
+ Symbol[] params = owner.typeAt(descr.nextPhase).firstParams();
+ int nfree = get(free.fvs, owner).size();
+ assert nfree == params.length - owner.type().firstParams().length;
+ Symbol[] newparams = new Symbol[nfree];
+ System.arraycopy(params, params.length - nfree, newparams, 0, nfree);
+ return newparams;
+ }
+
+ /** change symbol of tree so that
* owner = currentClass
* newparams are added
* enter symbol in scope of currentClass
*/
+ void liftSymbol(Tree tree) {
+ switch (tree) {
+ case ClassDef(_, _, _, _, _, _):
+ ((ClassDef) tree).mods |= LIFTED;
+ Symbol sym = tree.symbol();
+ assert sym.isLocal() : sym;
+ liftSymbol(sym, ftvsParams(sym.constructor()), fvsParams(sym.constructor()));
+ break;
+
+ case DefDef(_, _, _, _, _, _):
+ ((DefDef) tree).mods |= LIFTED;
+ Symbol sym = tree.symbol();
+ assert sym.isLocal() : sym;
+ liftSymbol(sym, ftvsParams(sym), fvsParams(sym));
+ }
+ }
+
void liftSymbol(Symbol sym, Symbol[] newtparams, Symbol[] newparams) {
Symbol enclClass = sym.owner().enclClass();
if (!sym.isPrimaryConstructor()) sym.setOwner(enclClass);
@@ -491,6 +536,10 @@ public class LambdaLift extends OwnerTransformer
}
}
+ boolean isLocal() {
+ return currentOwner.kind == VAL && currentOwner.name != Name.EMPTY;
+ }
+
Type addParams(Type tp, Symbol[] newparams) {
if (newparams.length == 0) return tp;
switch (tp) {
diff --git a/test/files/neg/bug52.check b/test/files/neg/bug52.check
new file mode 100644
index 0000000000..cd4b5eccce
--- /dev/null
+++ b/test/files/neg/bug52.check
@@ -0,0 +1,6 @@
+bug52.scala:3: type mismatch;
+ found : scala.Any
+ required: scala.Int
+ val y: Int = x(2);
+ ^
+one error found
diff --git a/test/files/neg/bug52.scala b/test/files/neg/bug52.scala
new file mode 100644
index 0000000000..e171022eb6
--- /dev/null
+++ b/test/files/neg/bug52.scala
@@ -0,0 +1,4 @@
+object test {
+ val x = if (2 == 3) (x: Int => 0) else (x: Int => "");
+ val y: Int = x(2);
+}
diff --git a/test/files/neg/refine.check b/test/files/neg/refine.check
new file mode 100644
index 0000000000..38d961bb34
--- /dev/null
+++ b/test/files/neg/refine.check
@@ -0,0 +1,9 @@
+refine.scala:3: method t overrides nothing
+ val x: Object { def t(): String } = new Object {
+ ^
+refine.scala:3: type mismatch;
+ found : scala.Object
+ required: scala.Object { def t(): java.lang.String }
+ val x: Object { def t(): String } = new Object {
+ ^
+two errors found
diff --git a/test/files/pos/bug30.scala b/test/files/pos/bug30.scala
new file mode 100644
index 0000000000..6d28e18c0d
--- /dev/null
+++ b/test/files/pos/bug30.scala
@@ -0,0 +1,9 @@
+trait A {
+ def f(x: int): unit;
+ def f(x: String): unit;
+}
+
+class B extends A {
+ def f(x: int): unit = ();
+ def f(x: String): unit = ();
+}
diff --git a/test/files/pos/bug31.scala b/test/files/pos/bug31.scala
new file mode 100644
index 0000000000..607dd4ce4f
--- /dev/null
+++ b/test/files/pos/bug31.scala
@@ -0,0 +1,29 @@
+object Main {
+
+ trait Ensure[a] {
+ def ensure(postcondition: a => Boolean): a
+ }
+
+ def require[a](def precondition: Boolean)(def command: a): Ensure[a] =
+ if (precondition)
+ new Ensure[a] {
+ def ensure(postcondition: a => Boolean): a = {
+ val result = command;
+ if (postcondition(result)) result
+ else error("Assertion error")
+ }
+ }
+ else
+ error("Assertion error");
+
+ def arb[a](s: List[a]) =
+ require (! s.isEmpty) {
+ s.head
+ } ensure (result => s contains result);
+
+ def main(args: Array[String]) = {
+ val s = List(1, 2);
+ System.out.println(arb(s))
+ }
+
+}
diff --git a/test/files/pos/bug36.scala b/test/files/pos/bug36.scala
new file mode 100644
index 0000000000..1d923b0017
--- /dev/null
+++ b/test/files/pos/bug36.scala
@@ -0,0 +1,8 @@
+object m {
+
+ val xs: List[int] = Nil;
+ def f(i: int) = 0;
+ val v = xs map f;
+
+ def m() = {}
+}
diff --git a/test/files/pos/bug39.scala b/test/files/pos/bug39.scala
new file mode 100644
index 0000000000..a131bc0450
--- /dev/null
+++ b/test/files/pos/bug39.scala
@@ -0,0 +1,6 @@
+abstract class Extensible[A, This <: Extensible[A, This]](x: A, xs: This): This {
+ def mkObj(x: A, xs: This): This;
+}
+class Fixed[A](x: A, xs: Fixed[A]) extends Extensible[A, Fixed[A]](x, xs) {
+ def mkObj(x: A, xs: Fixed[A]) = new Fixed(x, xs);
+}
diff --git a/test/files/pos/refine.scala b/test/files/pos/refine.scala
new file mode 100644
index 0000000000..255621ad43
--- /dev/null
+++ b/test/files/pos/refine.scala
@@ -0,0 +1,6 @@
+object test {
+
+ val x: Object { def toString(): String } = new Object {
+ override def toString(): String = "1";
+ }
+}
diff --git a/test/files/pos/seqtest2.scala b/test/files/pos/seqtest2.scala
new file mode 100644
index 0000000000..903b270c95
--- /dev/null
+++ b/test/files/pos/seqtest2.scala
@@ -0,0 +1,13 @@
+object test {
+
+ val b = List(1, 2, 3);
+
+ def main(args: Array[String]) =
+ System.out.println(
+ b match {
+ case List(1, 2, 3) => true;
+ case _ => false;
+ }
+ )
+
+}
diff --git a/test/neg/bug52.check b/test/neg/bug52.check
new file mode 100644
index 0000000000..cd4b5eccce
--- /dev/null
+++ b/test/neg/bug52.check
@@ -0,0 +1,6 @@
+bug52.scala:3: type mismatch;
+ found : scala.Any
+ required: scala.Int
+ val y: Int = x(2);
+ ^
+one error found
diff --git a/test/neg/bug52.scala b/test/neg/bug52.scala
new file mode 100644
index 0000000000..e171022eb6
--- /dev/null
+++ b/test/neg/bug52.scala
@@ -0,0 +1,4 @@
+object test {
+ val x = if (2 == 3) (x: Int => 0) else (x: Int => "");
+ val y: Int = x(2);
+}
diff --git a/test/neg/refine.check b/test/neg/refine.check
new file mode 100644
index 0000000000..38d961bb34
--- /dev/null
+++ b/test/neg/refine.check
@@ -0,0 +1,9 @@
+refine.scala:3: method t overrides nothing
+ val x: Object { def t(): String } = new Object {
+ ^
+refine.scala:3: type mismatch;
+ found : scala.Object
+ required: scala.Object { def t(): java.lang.String }
+ val x: Object { def t(): String } = new Object {
+ ^
+two errors found
diff --git a/test/pos/bug30.scala b/test/pos/bug30.scala
new file mode 100644
index 0000000000..6d28e18c0d
--- /dev/null
+++ b/test/pos/bug30.scala
@@ -0,0 +1,9 @@
+trait A {
+ def f(x: int): unit;
+ def f(x: String): unit;
+}
+
+class B extends A {
+ def f(x: int): unit = ();
+ def f(x: String): unit = ();
+}
diff --git a/test/pos/bug31.scala b/test/pos/bug31.scala
new file mode 100644
index 0000000000..607dd4ce4f
--- /dev/null
+++ b/test/pos/bug31.scala
@@ -0,0 +1,29 @@
+object Main {
+
+ trait Ensure[a] {
+ def ensure(postcondition: a => Boolean): a
+ }
+
+ def require[a](def precondition: Boolean)(def command: a): Ensure[a] =
+ if (precondition)
+ new Ensure[a] {
+ def ensure(postcondition: a => Boolean): a = {
+ val result = command;
+ if (postcondition(result)) result
+ else error("Assertion error")
+ }
+ }
+ else
+ error("Assertion error");
+
+ def arb[a](s: List[a]) =
+ require (! s.isEmpty) {
+ s.head
+ } ensure (result => s contains result);
+
+ def main(args: Array[String]) = {
+ val s = List(1, 2);
+ System.out.println(arb(s))
+ }
+
+}
diff --git a/test/pos/bug36.scala b/test/pos/bug36.scala
new file mode 100644
index 0000000000..1d923b0017
--- /dev/null
+++ b/test/pos/bug36.scala
@@ -0,0 +1,8 @@
+object m {
+
+ val xs: List[int] = Nil;
+ def f(i: int) = 0;
+ val v = xs map f;
+
+ def m() = {}
+}
diff --git a/test/pos/bug39.scala b/test/pos/bug39.scala
new file mode 100644
index 0000000000..a131bc0450
--- /dev/null
+++ b/test/pos/bug39.scala
@@ -0,0 +1,6 @@
+abstract class Extensible[A, This <: Extensible[A, This]](x: A, xs: This): This {
+ def mkObj(x: A, xs: This): This;
+}
+class Fixed[A](x: A, xs: Fixed[A]) extends Extensible[A, Fixed[A]](x, xs) {
+ def mkObj(x: A, xs: Fixed[A]) = new Fixed(x, xs);
+}
diff --git a/test/pos/refine.scala b/test/pos/refine.scala
new file mode 100644
index 0000000000..255621ad43
--- /dev/null
+++ b/test/pos/refine.scala
@@ -0,0 +1,6 @@
+object test {
+
+ val x: Object { def toString(): String } = new Object {
+ override def toString(): String = "1";
+ }
+}
diff --git a/test/pos/seqtest2.scala b/test/pos/seqtest2.scala
new file mode 100644
index 0000000000..903b270c95
--- /dev/null
+++ b/test/pos/seqtest2.scala
@@ -0,0 +1,13 @@
+object test {
+
+ val b = List(1, 2, 3);
+
+ def main(args: Array[String]) =
+ System.out.println(
+ b match {
+ case List(1, 2, 3) => true;
+ case _ => false;
+ }
+ )
+
+}