diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-01-21 10:45:36 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-01-21 11:12:57 +0100 |
commit | f6168b8a4d661985b0fb4d6d3cbba256bfc69607 (patch) | |
tree | 386c6695d03fb0b3787ead0a4aececc47a24fa58 /test/files | |
parent | 6f72ed85c3882d2a8c824a41e6e42d7f33b8d1d6 (diff) | |
download | scala-f6168b8a4d661985b0fb4d6d3cbba256bfc69607.tar.gz scala-f6168b8a4d661985b0fb4d6d3cbba256bfc69607.tar.bz2 scala-f6168b8a4d661985b0fb4d6d3cbba256bfc69607.zip |
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
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/neg/t6231.check | 6 | ||||
-rw-r--r-- | test/files/neg/t6231.scala | 15 |
2 files changed, 21 insertions, 0 deletions
diff --git a/test/files/neg/t6231.check b/test/files/neg/t6231.check new file mode 100644 index 0000000000..b27961d393 --- /dev/null +++ b/test/files/neg/t6231.check @@ -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 diff --git a/test/files/neg/t6231.scala b/test/files/neg/t6231.scala new file mode 100644 index 0000000000..1e5b4e0e1a --- /dev/null +++ b/test/files/neg/t6231.scala @@ -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 } + } + } +} + |