8000 Compiler support for scala-async (including Git history) by retronym · Pull Request #89 · retronym/scala · GitHub
[go: up one dir, main page]

Skip to content

Compiler support for scala-async (including Git history) #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 644 commits into from

Conversation

retronym
Copy link
Owner

No description provided.

retronym and others added 30 commits July 21, 2014 22:24
Test case for already-fixed NPE with value classes
`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.
Avoid assigning null to vars of derived value 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
E.g. type param, abstrat type.
Fix regression around await of non-class type
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
A worthy optimization, suggested by @danarmak.

Closes #73
Make `f(await(completedFuture))` execute `f` synchronously
…ter-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
I started with:

   scala/scala-swing@a6a8e1d77e#diff-3acefdae08499733e855dd23e1af933dR8

And:
  - modified the regex that derives the version from the tag to
    handle the fact we have the scala binary version appended to
    our tags
  - Removed unnessary cross building with Scala 2.11 (as this is
    on the 2.10.x branch)
  - generated a key pair for the async repository
  - added passphrase for that key, and sonatype credentials, to
    sensitive.sbt
  - encrypted the secrets with the travis key.
…ter-tag-driven-release

Conflicts:
	.travis.yml
…en-release

Merge 2.10.x to master to bring in tag driven publishing
We were leaking untyped trees out of the macro, which crashed
in refchecks.

This commit proactively typechecks the tree returned by `mkZero`.
Fix compiler crash with value class in result position
retronym added 29 commits March 24, 2020 14:45
And reuse existing utility method to change module class owner.
The input trees are always typed now which means the early cases
subsume the ones being deleted here.
  - The state machine generated by the front end macro must Now
    implement a small set of methods as a facade over the
    particular Future/Awaitable/Task type being used. This
    replaces the AST factory methods in `FutureSystem`
  - Remove intrinsic implemnentation for scala-async's async
    macro. Show what it will need to do in a test implementation,
    `s.t.n.partest.Async` and update all test cases to use this.
  - Add a heuristic to interpret `@compileTimeOnly` annotated
    methods to register `await` methods. Defer the check in refchecks
    for all of these and instead check that no references survive
    the async phase.
  - Refactor the test implementations of async front ends to
    share an interface for the state machine. We don't ship
    this but it could be copy/pasted into third party integrations.
  - Add a test integration with Java's CompletableFuture.
  - Expose a method through macro `Internals` API to let
    front ends mark a method in the state machine for async
    translation.
This lets us use IntelliJ's code coverage analysis.
 - Adapt detection logic to the post-erasure tree shapes
 - Lift restriction about || and && in favour of a
   rewrite to `If` in the ANF transform
 - import relevant parts of the test from scala-async.
It seems generally useful enough to move it out of
the async utilities. I've also added a unit test.
@retronym retronym closed this Mar 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0