summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstenman <stenman@epfl.ch>2003-09-02 15:53:24 +0000
committerstenman <stenman@epfl.ch>2003-09-02 15:53:24 +0000
commit40bdb6bee6d2bd91da44c351db7e9e709024c24c (patch)
tree24e208c8c2851132cd146fe36dc9b509ccd5b10a
parent155189bcfa95266320418b38992e46ea0d5140f0 (diff)
downloadscala-40bdb6bee6d2bd91da44c351db7e9e709024c24c.tar.gz
scala-40bdb6bee6d2bd91da44c351db7e9e709024c24c.tar.bz2
scala-40bdb6bee6d2bd91da44c351db7e9e709024c24c.zip
Tailcall fixed to handle some more cases.
-rw-r--r--sources/scalac/symtab/Symbol.java6
-rw-r--r--sources/scalac/transformer/TailCall.java21
2 files changed, 21 insertions, 6 deletions
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index e36dc1489e..04eff30d3a 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -374,6 +374,12 @@ public abstract class Symbol implements Modifiers, Kinds {
return (flags & PRIVATE) != 0;
}
+ /** Has this symbol been lifted? */
+ public final boolean isLifted() {
+ preInitialize();
+ return (flags & LIFTED) != 0;
+ }
+
/** Does this symbol denote a deferred symbol? */
public final boolean isDeferred() {
return (flags & DEFERRED) != 0;
diff --git a/sources/scalac/transformer/TailCall.java b/sources/scalac/transformer/TailCall.java
index e4f5bb4fb5..19914f78ba 100644
--- a/sources/scalac/transformer/TailCall.java
+++ b/sources/scalac/transformer/TailCall.java
@@ -143,13 +143,20 @@ public class TailCall extends Transformer {
switch (fun) {
case Select(Tree qual, Name name):
if (state.currentFunction == fun.symbol()) { // Is is self-recursive?
- // Make sure that function is from the same class as we are in.
- if (qual.type.isSameAs(state.currentClass.thisType().widen())) {
+ // Make sure that function is from the same instance of the class as we are in.
+ // If it is an Object (Module) we don't necessarily have a THIS, so we compare
+ // the types.
+ // If it's a class we have to make sure that the qulifier is a THIS node.
+ if ((state.currentClass.isModuleClass() &&
+ qual.type.isSameAs(state.currentClass.thisType().widen())) ||
+ (qual instanceof This && qual.symbol() == state.currentClass)){
+
// We can only rewrite final functions in a safe way.
- // (Local lifted functions should be safe but they should
- // have the final flag set.)
- Modifiers.Helper H = new Modifiers.Helper();
- if(H.isFinal(state.currentFunction.flags)) { // Is the function final?
+ if(state.currentFunction.isFinal() ||
+ state.currentFunction.isPrivate() ||
+ state.currentFunction.isLifted()
+ ) { // It would be nice if we had a cant-be-overridden function in symbol...
+
Tree[] newArgs = tail_transform(args,false);
// Redirect the call to the LabelDef.
Tree newTarget = new ExtIdent(state.newLabel).setType(fun.type());
@@ -160,6 +167,8 @@ public class TailCall extends Transformer {
}
}
break;
+ // TODO: Handle the case of Apply(TypeApply(T))
+ // Have to check that the type T is the same as currentFunction.type()
default:
break;
}