| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
also upgrade Scala 2.12.4 -> 2.12.6
|
|
|
|
| |
as discovered by the Scala 2.13 community build
|
|
|
|
|
| |
Remove use of scala.concurrent.forkjoin.
Remove support for JDK 6.
|
|
|
|
|
|
|
|
|
|
| |
the old code would fail with e.g.
> ++2.12.5-bin-76f588e-SNAPSHOT
> testOnly *WarningsSpec
this was showing up repeatedly when running the Scala community
build against as-yet-unmerged scala/scala PRs
|
| |
|
| |
|
|
|
|
|
| |
we need to handle a Scala version like `2.13.0-pre-5e84129`,
as we see in nightly builds before bincompat is locked down
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
e.g `val x2 = Foo[$1] with Bar = boundValue`
is rewritten to `val x2 = (Foo[$1] @uncheckedBounds) with Bar = boundValue`
This is to have refchecks turn a blind eye to the type argument that
doesn't conform the to type parameter bounds.
For regular compilation, without the async transform between patmat
and refchecks, bound conformance is disabled with:
https://github.com/scala/scala/blob/v2.11.7/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala#L1743
Using the `uncheckedBounds` annotation is a newer, more inclusive way
of acheiving the same thing:
https://github.com/scala/scala/blob/v2.11.7/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala#L1677
|
| |
|
|\
| |
| | |
Fix decision about whether to use a trait or class as the parent
|
| | |
|
| | |
|
| | |
|
|/
|
|
|
| |
Unfortunately I wasn't able to extract a test case, but the patch
has been tested to fix a problem on a real world code base.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If a state does nothing but unconditionally transition to the
next state, remove it and rewrite predecessors to directly jump
to the successor state (or to the first non-dead successor.)
While we're doing this, compact the remaining state IDs to be
contiguous, which will allow use of a tableswitch in bytecode.
Sample bytecode demonstrating a tableswitch:
https://gist.github.com/retronym/6880c35b501fc1c91bed7f30c0f2c045
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
After this change tests pass also on Windows.
|
|\
| |
| | |
Compatibility with Scala 2.12.0-RC1
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- method local lazy vals are now encoded as a single ValDef
rather than a ValDef + DefDef pair. We need to treat ValDef-s
with the LAZY flag in the same way as we used to treat the
DefDef.
- Rename one of the symbols `ANF,anf` in the same scope to avoid
generating anonymous class names that differ only in case. The
compiler warned about this one.
- When patching the LabelDefs to have a `Unit` result type, propagate
this other LabelDefs conclude with a jump to that label. Not sure
why, but without this we now hit an error in the backend about the
nonsensical attempt to emit a coercion from void to int.
- Use crossScalaVersions in the build and update the Scala versions
tested in CI.
|
|/
|
|
|
|
|
|
|
|
|
|
| |
The current extension point assumes that if a future is in the
completed state, a subsequent call to get the already completed
value will succeed. While this assumption holds for
scala.concurrent.Future, it might not hold for a future system
that has semantics like a weak reference.
This commit uses a single call `getCompleted` to query the state
and get the already completed value. This returns null if the
value is not available.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Detect cross-state symbol references where the RefTree is nested
in a LabelDef. Failure to do so led to ill-scoped local variable
references which sometimes manifest as VerifyErrors.
- Emit a default case in the Match intended to be a tableswitch.
We have to do this ourselves if we expand after pattern matcher
- Cleanup generated code to avoid redundant blocks
- Avoid unnecessary `matchRes` temporary variable for unit-typed
pattern matches
- Fix the trace level logging in the ANF transform to restore
indented output.
- Emit `{ state = nextState; ... }` rather than
`try { ... } finally { state = nextState }` in state handlers.
This simplifies generated code and has the same meaning, as the
code in the state machine isn't reentrant and can't observe the
"early" transition of the state.
|
|
|
|
|
|
|
|
|
| |
Avoids mixing in all the specialized apply variants.
We could go further and create an base class for all state machines,
but that would require scala-async to be on the runtime classpath,
which currently isn't a requirement. For now, I'm keeping it this
way.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The presentation compiler runs with `-Ymacro-expand:discard`, which
retains the macro expandee in the typechecked trees, rather than
substituting in the expansion. This mode was motivated as a means
to keep IDE functionality working (e.g. completion, navigation,
refactoring) inside macro applications.
However, if one has nested async macro applications, as reported in
the IDE ticket:
https://www.assembla.com/spaces/scala-ide/tickets/1002561
... the expansion of the outer async application was reporting
await calls enclosed by the inner async application.
This change tweaks the traversers used for this analysis to
stop whenever it sees an async.
|
|
|
|
|
|
|
|
| |
- More internal docs
- Be more frugal with the `NoAwait` attachment, for some AST node
types this is implied.
- Just use `x`, rather than what was effectively
`x.reverseMap(identity).reverse`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently, the async transformation is performed during the typer
phase, like all other macros.
We have to levy a few artificial restrictions on whern an async
boundary may be: for instance we don't support await within a
pattern guard. A more natural home for the transform would be
after patterns have been translated.
The test case in this commit shows how to use the async transform
from a custom compiler phase after patmat.
The remainder of the commit updates the implementation to handle
the new tree shapes.
For states that correspond to a label definition, we use `-symbol.id`
as the state ID. This made it easier to emit the forward jumps to when
processing the label application before we had seen the label
definition.
I've also made the transformation more efficient in the way it checks
whether a given tree encloses an `await` call: we traverse the input
tree at the start of the macro, and decorate it with tree attachments
containig the answer to this question. Even after the ANF and state
machine transforms introduce new layers of synthetic trees, the
`containsAwait` code need only traverse shallowly through those
trees to find a child that has the cached answer from the original
traversal.
I had to special case the ANF transform for expressions that always
lead to a label jump: we avoids trying to push an assignment to a result
variable into `if (cond) jump1() else jump2()`, in trees of the form:
```
% cat sandbox/jump.scala
class Test {
def test = {
(null: Any) match {
case _: String => ""
case _ => ""
}
}
}
% qscalac -Xprint:patmat -Xprint-types sandbox/jump.scala
def test: String = {
case <synthetic> val x1: Any = (null{Null(null)}: Any){Any};
case5(){
if (x1.isInstanceOf{[T0]=> Boolean}[String]{Boolean})
matchEnd4{(x: String)String}(""{String("")}){String}
else
case6{()String}(){String}{String}
}{String};
case6(){
matchEnd4{(x: String)String}(""{String("")}){String}
}{String};
matchEnd4(x: String){
x{String}
}{String}
}{String}
```
|
| |
|
|
|
|
| |
And remove unused code.
|
|
|
|
|
| |
This avoids leaving .class files in the working directory
after running the test.
|
|
|
|
|
|
| |
By declararing the parameter of `async` as by-name.
Fixes #150 (the bug in the original ticket.)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If we blindly splicing `{..$stats, ..$generatedCode}`, and the last
expression in `$stats` is of type `Nothing`, we'll incur a dead
code warning when typechecking the block.
This commit:
- introduces a helper method to augment user-written stats with
synthetic code
- Emit a try/finally in that code (so we advance the state, even if we
are about to exit the state machine in the async-block global
exception handler
- Hide `Nothing` typed expressions from the dead code analysis
by wrapping them in an `expr: Any`
Fixes #150 (the part reported in the comments, not the original ticket.)
|
|
|
|
|
|
|
| |
Don't bother adding `{ ...; () }` if we can use the original tree(s) instead,
e.g. if the last tree in `...` conforms to `Unit`.
This makes the debug output of the macro a little easier to read.
|
|\
| |
| | |
Avoid masking user exception with ??? for Nothing typed expressions
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Code like:
val x = if (cond) throw new A else throw new B
Was being transformed to:
val ifRes = ???
if (cond) ifRes = throw new A else ifRes = throw new B
val x = ifRes
by way of the use of `gen.mkZero` which throws `???` if the requested type is `Nothing`
This commit special cases `Nothing` typed expressions in a similar manner to `Unit` type expressions.
The example above is now translated to:
if (cond) throw new A else throw new B
val x = throw new IllegalStateException()
Fixes #120
|
|/
|
|
|
|
|
|
|
|
| |
The stack trace and bisection in #119 made me notice that we
are failing to typecheck the cast we generated in the fix for #74.
The ticket doesn't have a reproduction, so I'm submitting this
without a test case.
Fixes #119
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
During the ANF transform, we were generating a tree of the shape:
{
val temp: Unit = await(futureOfUnit)
temp
()
}
I tried to simplifiy this to avoid creating the temporary value,
but this proved difficult as it would have required changes to
the subsequent state machine transformation.
Even replacing `temp` with `()` made the state machine transform
harder.
So for now, I've just inserted `temp.asInstanceOf[Unit]` to hide
from the compiler warning.
Fixes #74
|
|
|
|
|
|
| |
This commit disabled live variable analysis for intermediate values of type Nothing.
Fixes #104
|
|
|
|
|
|
|
| |
We were leaking untyped trees out of the macro, which crashed
in refchecks.
This commit proactively typechecks the tree returned by `mkZero`.
|
|\
| |
| |
| |
| |
| |
| |
| |
| | |
merge/2.10.x-to-master-20141219
Conflicts:
src/main/scala/scala/async/internal/AsyncTransform.scala
src/main/scala/scala/async/internal/ExprBuilder.scala
src/test/scala/scala/async/TreeInterrogation.scala
|
| |
| |
| |
| |
| |
| | |
A worthy optimization, suggested by @danarmak.
Closes #73
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Previously, as sequence of state transitions that did not pass through
an asynchrous boundary incurred stack frames. The trivial loop in
the enclosed test case would then overflow the stack.
This commit merges the `resume` and `apply(tr: Try[Any])` methods into
a `apply`. It changes the body of this method to be an infinite loop
with returns at the terminal points in the state machine (or at a
terminal failure.)
To allow merging of these previously separate matches, states that
contain an await are now allocated two state ids: one for the setup
code that calls `onComplete`, and one for the code in the continuation
that records the result and advances the state machine.
Fixes #93
|
| |
| |
| |
| | |
E.g. type param, abstrat type.
|
| | |
|
|\|
| |
| |
| |
| |
| |
| | |
Conflicts:
src/main/scala/scala/async/internal/AnfTransform.scala
src/main/scala/scala/async/internal/AsyncTransform.scala
src/test/scala/scala/async/run/toughtype/ToughType.scala
|