Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SI-6231 Report unsupported free var capture by a trait.
If a class nested in a trait captures a free variable from the enclosing scope of the trait, the transformation to add that variable to the `init` method of the trait implementation class happens *after* the abstract trait interface has been extracted. This would lead to a crash when trying to find the corresponding interface method. This commit detects this situation and reports an implementation restriction. The enclosed test case shows a workaround. To lift this restriction, LambdaLifter should add the getters and make sure they end up in the trait interface. Looks like Martin tried this once: // LambdaLift.scala // // Disabled attempt to to add getters to freeParams // this does not work yet. Problem is that local symbols need local names // and references to local symbols need to be transformed into // method calls to setters. // def paramGetter(param: Symbol): Tree = { // val getter = param.newGetter setFlag TRANS_FLAG resetFlag PARAMACCESSOR // mark because we have to add them to interface // sym.info.decls.enter(getter) // val rhs = Select(gen.mkAttributedThis(sym), param) setType param.tpe // DefDef(getter, rhs) setPos tree.pos setType NoType // } // val newDefs = if (sym.isTrait) freeParams ::: (ps map paramGetter) else freeParams
- Loading branch information
Showing
4 changed files
with
40 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
t6231.scala:4: error: Implementation restriction: local trait Bug$X$1 is unable to automatically capture the | ||
free variable value ev$1 on behalf of anonymous class anonfun$qux$1. You can manually assign it to a val inside the trait, | ||
and refer that that val in anonymous class anonfun$qux$1. For more details, see SI-6231. | ||
def qux = { () => ev } | ||
^ | ||
one error found |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
object Bug { | ||
def bar(ev: Any) = { | ||
trait X { | ||
def qux = { () => ev } | ||
} | ||
new X {}.qux() | ||
|
||
// workaround | ||
trait Y { | ||
val ev2 = ev // manually capture `ev` so that `ev2` is added to the trait interface. | ||
def qux = { () => ev2 } | ||
} | ||
} | ||
} | ||
|