| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
`TreeGen#mkZero` returns `q"null"` for derived value classes.
```
scala> class V(val a: String) extends AnyVal
defined class V
scala> showRaw(gen.mkZero(typeOf[V]))
res0: String = Literal(Constant(null))
```
We use this API in async to generate the initial value for
ANF-lifted temporary variables.
However, this leads to NPEs, as after posterasure, we call the
unbox method on a null reference:
```
% cat sandbox/Macro.scala; scalac-hash v2.10.4 sandbox/Macro.scala; scala-hash v2.10.4 -e 'val x = Macros.myMacro'
import scala.reflect.macros.Context
import scala.language.experimental.macros
object Macros {
def macroImpl(c: Context): c.Expr[C] = {
import c.universe._
val e1 = c.Expr[C](Literal(Constant(null)).setType(typeOf[C]))
reify(e1.splice.asInstanceOf[C @annotation.unchecked.uncheckedVariance])
}
def myMacro: C = macro macroImpl
}
class C(val a: String) extends AnyVal
java.lang.NullPointerException
at Main$$anon$1.<init>(scalacmd4059893593754060829.scala:1)
at Main$.main(scalacmd4059893593754060829.scala:1)
at Main.main(scalacmd4059893593754060829.scala)
```
This commit installs a custom version of `mkZero` that instead
returns `q"new C[$..targs](${mkZero(wrappedType)})`.
Thanks to @ewiner for pinpointing the problem.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This progressed along with the fix for #66.
`TreeGen.mkZero` is a bit of a minefield: first with `Nothing` and
now with Value Classes. I wonder if we can provoke the same sort of
bug in the compiler in places where this is used.
Closes #83
|
|\|
| |
| |
| |
| |
| |
| |
| | |
merge/2.10.x-to-master-20140721
Conflicts:
src/main/scala/scala/async/internal/AsyncTransform.scala
src/main/scala/scala/async/internal/Lifter.scala
|
| |\
| | |
| | | |
Fix regression around type skolems and if exprs.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
If we start with:
async({
val res = await[S[_$1 with String]](s);
if (true)
await[Int](0)
res
})
Typechecking the application (before macro expansion) yields
(where the trees are printed in the form `expr{tpe}`):
async[S[_$1#5738 with String#137]]({
val res: S[_$1#5490 with String] forSome { type _$1#5490 } =
await[S[_$1#5487 with String]](
s{S[_$1#5487 with String]}
){S[_$1#5487 with String]};
if (true)
await(0)
else
()
res{S[_$1#5738 with String]}
}{S[_$1#5738 with String]}){S[_$1#5738 with String]}
Note that the type of the second last line contains a skolemized
symbol `_$1#5738` of the existential `_$1#5490`. This is created
by this case in `Typer#adapt`:
case et @ ExistentialType(_, _) if ((mode & (EXPRmode | LHSmode)) == EXPRmode) =>
adapt(tree setType et.skolemizeExistential(context.owner, tree), mode, pt, original)
Our ANF rewrites part of this code to:
<synthetic> val await$1: S[_$1#5487 with String] = await[S[_$1#5487 with String]](awaitable$1);
val res: S[_$1#5490 with String] forSome { type _$1 } = await$1;
And later, the state machine transformation splits the last line into
a blank field and an assignment. Typechecking the `Assign` node
led to the an type error.
This commit manually attributes the types to the `Assign` node so
as to avoid these problem.
It also reigns in an overeager rewriting of `If` nodes in the
ANF transform, which was due to a bug in the label detection
logic introduced in 4fc5463538.
Thanks to @gnovark for yet another devilish test case and
analysis of the problem with label detection.
I worked on a more principled fix on:
https://github.com/retronym/async/compare/ticket/79-2?expand=1
in which I try to use `repackExistential` to convert skolemized
types to existentials for use as the types of synthetic vals
introduced by the ANF transform. This ran into a deeper problem
with existential subtyping in the compiler itself though.
|
| |\ \
| | | |
| | | | |
Fix asymptotic performance issues in live variables analysis.
|
| | |/
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Fix possibly-exponential runtime for DFS graph searches.
Improve DFA fixpoint algorithm to correctly compute worklist
of only changed nodes for each iteration.
Added test that takes > 2 minutes to compile without these
improvements.
|
| |/
| |
| |
| |
| |
| |
| | |
`gen.mkZero(NothingTpe)` gives the tree `Predef.???`. Instead, we should leave
the `await` field uninitialized with `ValDef(..., rhs = EmptyTree)`.
Fixes #66
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- remove unneeded `setType(NoType)`, which was leftover from my
first attempts to find this bug.
- fix typo in error message
- optimize imports
(cherry picked from commit 5c6ea29966fa80faae13892da50fc68ed1bf9ae7)
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We were incorrectly typechecking the `ClassDef` of the state machine
in the macro in a way that discarded the resulting trees, and only
kept around the symbol.
The led to the the macro engine retypechecking
that node, which somehow led to duplicated lazy val initiaializer
`DefDef`-s in the template, which manifest as a `VerifyError`.
This commit:
- rescues the typechecked `ClassDef` node from the eager
typechecking by the macro
- loosens the restriction on lazy vals in async blocks. They are
still prohibited if they contain an await on the RHS
- Adds a test that shows evalution is indeed lazy.
(cherry picked from commit cc4587b1985519f7049d0feb0783d8e22c10f792)
Conflicts:
src/main/scala/scala/async/internal/AsyncAnalysis.scala
src/main/scala/scala/async/internal/AsyncTransform.scala
|
| |
| |
| |
| |
| |
| | |
Works on the 2.10.x branch, so just backprting the test.
Cherry picked from 6f6546ebfc26564843621e79d840209a5103d3c8.
|
| | |
|
| |
| |
| |
| |
| | |
- simpler means to calculate `applyDepth`
- remove unused binder
|
| |
| |
| |
| |
| |
| |
| |
| | |
Namely: https://github.com/scala/scala/pull/3656
I can't find a way to express a QQ that matches an constructor
invocation *and* lets me bind a reference to the `New` tree.
So I've dropped down to a borrowed version of `TreeInfo#Applied`.
|
| |
| |
| |
| |
| |
| |
| | |
- remove unneeded `setType(NoType)`, which was leftover from my
first attempts to find this bug.
- fix typo in error message
- optimize imports
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We were incorrectly typechecking the `ClassDef` of the state machine
in the macro in a way that discarded the resulting trees, and only
kept around the symbol.
The led to the the macro engine retypechecking
that node, which somehow led to duplicated lazy val initiaializer
`DefDef`-s in the template, which manifest as a `VerifyError`.
This commit:
- rescues the typechecked `ClassDef` node from the eager
typechecking by the macro
- loosens the restriction on lazy vals in async blocks. They are
still prohibited if they contain an await on the RHS
- Adds a test that shows evalution is indeed lazy.
Fixes #52
|
| |
| |
| |
| |
| |
| | |
Predicate the `asClass` cast with an `isClass` check.
Fixes #63
|
| |
| |
| |
| |
| |
| |
| |
| | |
- Link to the 2.10.x branch from the README
- use `scala.annotation.compileTimeOnly` (from scala-library.jar)
- no longer impose a transitive dependency on scala-reflect and
scala-compiler.
- Update Travis CI configuration to use only 2.11.0-SNAPSHOT
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
|/ |
|
|
|
|
| |
In favour of the type defined by the active FutureSystem.
|
|\
| |
| | |
Update TODO comment about pres. compiler friendliness.
|
| | |
|
|/
|
|
| |
2013 must have been unlucky.
|
| |
|
|\
| |
| | |
Another take at the 2.10/2.11 spanning suppressMacroAttachment
|