aboutsummaryrefslogtreecommitdiff
path: root/src/test
Commit message (Collapse)AuthorAgeFilesLines
* Merge remote-tracking branch 'origin/2.10.x' into ↵Jason Zaugg2014-12-184-3/+65
|\ | | | | | | | | | | | | | | | | 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
| * Make `f(await(completedFuture))` execute `f` synchronouslyJason Zaugg2014-12-162-1/+28
| | | | | | | | | | | | A worthy optimization, suggested by @danarmak. Closes #73
| * Avoid unbounded stack consumption for synchronous control flowJason Zaugg2014-12-153-2/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* | Fix regression around await of non-class typeGene Novark2014-12-091-0/+15
| | | | | | | | E.g. type param, abstrat type.
* | Additional tests and comments around mkZero for value classesJason Zaugg2014-10-011-0/+24
| |
* | Merge branch 'ticket/86-mkZero' into merge/2.10.x-to-master-20140930Jason Zaugg2014-10-011-2/+51
|\| | | | | | | | | | | | | 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
| * Avoid assigning null to vars of derived value typeJason Zaugg2014-09-291-0/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `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.
* | Test case for already-fixed NPE with value classesJason Zaugg2014-07-211-0/+14
| | | | | | | | | | | | | | | | | | | | 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 remote-tracking branch 'origin/2.10.x' into ↵Jason Zaugg2014-07-213-0/+156
|\| | | | | | | | | | | | | | | merge/2.10.x-to-master-20140721 Conflicts: src/main/scala/scala/async/internal/AsyncTransform.scala src/main/scala/scala/async/internal/Lifter.scala
| * Merge pull request #80 from retronym/ticket/79Jason Zaugg2014-07-211-0/+63
| |\ | | | | | | Fix regression around type skolems and if exprs.
| | * Fix regression around type skolems and if exprs.Jason Zaugg2014-07-181-0/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * | Merge pull request #82 from retronym/topic/live-variable-speedupPhilipp Haller2014-07-181-0/+77
| |\ \ | | | | | | | | Fix asymptotic performance issues in live variables analysis.
| | * | Fix asymptotic performance issues in live variables analysis.Gene Novark2014-07-151-0/+77
| | |/ | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * / Avoid NotImplementedError awaiting a Future[Nothing]Jason Zaugg2014-06-141-0/+16
| |/ | | | | | | | | | | | | `gen.mkZero(NothingTpe)` gives the tree `Predef.???`. Instead, we should leave the `await` field uninitialized with `ValDef(..., rhs = EmptyTree)`. Fixes #66
| * Incorporate pull request feedbackJason Zaugg2014-03-272-6/+1
| | | | | | | | | | | | | | | | | | - 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)
| * [backport] Allow lazy vals without await in the initializerJason Zaugg2014-03-272-2/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
| * [backport] Test case for "not a class" crasher in live variableJason Zaugg2014-03-121-0/+28
| | | | | | | | | | | | Works on the 2.10.x branch, so just backprting the test. Cherry picked from 6f6546ebfc26564843621e79d840209a5103d3c8.
* | Update TreeInterrogation.scala杨博 (Yang Bo)2014-04-161-1/+1
| |
* | Incorporate pull request feedbackJason Zaugg2014-03-272-6/+1
| | | | | | | | | | | | | | - remove unneeded `setType(NoType)`, which was leftover from my first attempts to find this bug. - fix typo in error message - optimize imports
* | Allow lazy vals without await in the initializerJason Zaugg2014-03-272-2/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* | Fix "not a class" crasher in live variable analysisJason Zaugg2014-03-121-0/+28
| | | | | | | | | | | | Predicate the `asClass` cast with an `isClass` check. Fixes #63
* | currentUnit.freshName => c.freshName (leads to less precise tests...)Eugene Burmako2014-02-154-14/+23
| |
* | toolboxClasspath now works for snapshotsEugene Burmako2014-02-121-0/+2
|/
* Update copyright years.Jason Zaugg2014-01-1422-23/+23
| | | | 2013 must have been unlucky.
* Fix crashers in do/while and while(await(..))Jason Zaugg2013-11-222-31/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | The new tree shapes handled for do/while look like: // type checked async({ val b = false; doWhile$1(){ await(()); if (b) doWhile$1() else () }; () }) We had to change ExprBuilder to create states for the if/else that concludes the doWhile body, and also loosen the assertion that the label jump must be the last thing we see. We also have to look for more than just `containsAwait` when deciding whether an `If` needs to be transformed into states; it might also contain a jump to the enclosing label that is on the other side of an `await`, and hence needs to be a state transition instead.
* Fix crasher in icode due to symbol mismatches in lifted methodsJason Zaugg2013-11-141-0/+50
| | | | | | | | | These stem from the handling of the internal/external view or method type parameters by `thisMethodType` in `Namers`. I've now preseversed the orginal ValDefs favoured the latter when constructing the new DefDef, and made construction of all liftables consistent in this regard.
* Don't aggressively null out captured varsJason Zaugg2013-11-122-7/+151
| | | | | Once they escape, we leave the references in the state machines fields untouched.
* Minimize the public APIJason Zaugg2013-11-071-46/+0
| | | | | | | | | | - Remove the CPS fallback version of async. That was not intended to be part of 1.0. - Lookup the await method beside the macro, rather than requiring all calls to go to AsyncBase.await. - Create a minimal version of Async that just contains await/async and delegates to the macro implementation in internal._ - Add scaladoc.
* Scala 2.11 compatibilityJason Zaugg2013-11-071-0/+2
| | | | | | We were relying on an internal API that no longer exists. We also need to tweak the way our tests infer scalaBinaryVersion.
* Avoid zero-ing out dead fields of primitive value class typePhilipp Haller2013-10-221-10/+122
| | | | | - Zero out fields of type Any - Zero out fields of value class type
* Enables testing the resetting of lifted local variablesPhilipp Haller2013-10-221-0/+40
| | | | | | | - Adds a hook that lets a derived macro insert additional code when zero-ing out a lifted field. - Adds a variant of the `AsyncId` macro that logs zeroed-out fields. - Adds a test using this mechanism
* Handle while loops as expressions in ANF transform.Jason Zaugg2013-10-141-0/+14
| | | | | | | Append a `()`, as we do for `Unit` returning `if`-s and `try-s` We don't currently support `await` in try/catch, otherwise I'd write tests for that case, too.
* Merge pull request #30 from retronym/topic/unchecked-boundsJason Zaugg2013-08-2322-64/+65
|\ | | | | Use @uncheckedBounds to avoid introducing refchecks errors …
| * Use @uncheckedBounds to avoid introducing refchecks errorsJason Zaugg2013-08-222-1/+65
| | | | | | | | | | | | | | | | | | ... in code that would otherwise have smuggled through these slack LUBs in the types of trees but never in a TypeTree. More details in SI-7694. Fixes #29
| * Remove @RunWith annotations from test cases.Jason Zaugg2013-08-1521-63/+0
| | | | | | | | | | These are are at odds with the junit-interface SBT test framework under SBT 0.13.+, and appear to be superfluous.
* | Collection of clean-upsPhilipp Haller2013-08-141-1/+0
|/ | | | | | - removed outdated comments in ANF transform - added a few comments - removed some unnecessary imports
* Set the type of case bodies to Unit after ANF.Jason Zaugg2013-08-071-0/+14
| | | | Avoids runtime errors like: "java.lang.Double cannot be cast to scala.runtime.BoxedUnit"
* Disallow await in pattern guards (for now)Jason Zaugg2013-07-251-0/+10
|
* Preserve ApplyImplicitView / ApplyImplicitArgs in AnfTransform.Jason Zaugg2013-07-252-6/+21
|
* Test case for await in an Assign node.Jason Zaugg2013-07-241-0/+11
| | | | This case already works.
* Support await in Typed nodes.Jason Zaugg2013-07-241-0/+8
|
* Support await in throws.Jason Zaugg2013-07-241-0/+10
| | | | | Also support AsyncId.async[Nothing], which was triggering a NPE in the generated `null.asInstanceOf[Nothing]`.
* Fix "BoxedUnit cannot be cast to String" error.Jason Zaugg2013-07-091-0/+21
| | | | | When convering If and Match nodes to ANF, set the type to Unit. Otherwise, erasure might end up casting BoxedUnit to a real type.
* Move implementation details to scala.async.internal._.Jason Zaugg2013-07-0711-41/+47
| | | | | If we intend to keep CPS fallback around for any length of time it should probably move there too.
* Fix another interation with existentials and a name clash.Jason Zaugg2013-07-073-2/+46
|
* An overdue overhaul of macro internals.Jason Zaugg2013-07-035-110/+115
| | | | | | | | | | | | - Avoid reset + retypecheck, instead hang onto the original types/symbols - Eliminated duplication between AsyncDefinitionUseAnalyzer and ExprBuilder - Instead, decide what do lift *after* running ExprBuilder - Account for transitive references local classes/objects and lift them as needed. - Make the execution context an regular implicit parameter of the macro - Fixes interaction with existential skolems and singleton types Fixes #6, #13, #16, #17, #19, #21.
* Avoid hardcoded "2.10" in tests.Jason Zaugg2013-07-022-4/+19
| | | | This allows us to cross build against 2.10.x and 2.11.x.
* Mark `await` as @compileTimeOnlyJason Zaugg2013-04-171-1/+1
| | | | | | Rather than as @deprecated. This commit means we can no longer build against 2.10.0.
* Merge pull request #9 from retronym/ticket/4-multi-paramPhilipp Haller2013-04-172-28/+65
|\ | | | | Allow await in applications with multiple argument lists
| * Allow await in applications with multiple argument listsJason Zaugg2013-04-112-28/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before, we levied an implementation restriction to prevent this. As it turned out, that needlessly prevented use of `await` in the receiver of a multi-param-list application. This commit lifts the restriction altogether, and treats such applications holistically, being careful to preserve the left-to-right evaluation order of arguments in the translated code. - use `TreeInfo.Applied` and `Type#paramss` from `reflect.internal` to get the info we need - use the parameter name for the lifted argument val, rather than `argN` - encapsulate handling of by-name-ness and parameter names in `mapArgumentss` - test for evaluation order preservation