aboutsummaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
| * Avoid assigning null to vars of derived value typeJason Zaugg2014-09-294-7/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `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-217-34/+211
|\| | | | | | | | | | | | | | | 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-213-4/+70
| |\ | | | | | | Fix regression around type skolems and if exprs.
| | * Fix regression around type skolems and if exprs.Jason Zaugg2014-07-183-4/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-182-28/+120
| |\ \ | | | | | | | | Fix asymptotic performance issues in live variables analysis.
| | * | Fix asymptotic performance issues in live variables analysis.Gene Novark2014-07-152-28/+120
| | |/ | | | | | | | | | | | | | | | | | | | | | | | | 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-142-2/+17
| |/ | | | | | | | | | | | | `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-274-8/+3
| | | | | | | | | | | | | | | | | | - 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-274-8/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
| |
* | Refactoring in ANFTransformJason Zaugg2014-04-051-15/+2
| | | | | | | | | | - simpler means to calculate `applyDepth` - remove unused binder
* | Update to Scala 2.11.0-RC4, adapting to change in quasiquotesJason Zaugg2014-04-052-2/+69
| | | | | | | | | | | | | | | | 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`.
* | Incorporate pull request feedbackJason Zaugg2014-03-274-8/+3
| | | | | | | | | | | | | | - 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-274-8/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-122-1/+30
| | | | | | | | | | | | Predicate the `asClass` cast with an `isClass` check. Fixes #63
* | Finalize the move to Scala 2.11.xJason Zaugg2014-02-211-1/+1
| | | | | | | | | | | | | | | | - 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
* | AsyncMacro.global is goneEugene Burmako2014-02-159-53/+76
| |
* | AsyncMacro.macroApplication is goneEugene Burmako2014-02-153-6/+4
| |
* | callSiteTyper and TypingTransformers are goneEugene Burmako2014-02-152-13/+1
| |
* | migrates SelectiveAnfTransform to typingTransformEugene Burmako2014-02-151-233/+227
| |
* | oh God, in-place typechecking!!!Eugene Burmako2014-02-151-1/+1
| |
* | migrates UseFields to typingTransformEugene Burmako2014-02-151-26/+20
| |
* | migrates transformAt to typingTransformEugene Burmako2014-02-152-17/+13
| |
* | replaces mkAttributedCastEugene Burmako2014-02-151-2/+3
| |
* | gets rid of home-grown changeOwnerEugene Burmako2014-02-153-29/+11
| |
* | cleans up AnfTransformEugene Burmako2014-02-151-3/+5
| |
* | cleans up AsyncAnalysisEugene Burmako2014-02-151-1/+1
| |
* | cleans up AsyncTransformEugene Burmako2014-02-151-2/+2
| |
* | cleans up ExprBuilderEugene Burmako2014-02-151-1/+1
| |
* | cleans up FutureSystemEugene Burmako2014-02-154-23/+18
| |
* | cleans up LifterEugene Burmako2014-02-151-2/+2
| |
* | cleans up LiveVariablesEugene Burmako2014-02-151-3/+2
| |
* | eliminates all usages of global in TransformUtilsEugene Burmako2014-02-151-2/+3
| |
* | removes "import global._" and "def Expr" in TransformUtilsEugene Burmako2014-02-153-16/+14
| |
* | currentUnit.freshName => c.freshName (leads to less precise tests...)Eugene Burmako2014-02-155-16/+25
| |
* | abort => c.abortEugene Burmako2014-02-153-7/+4
| |
* | injects context into AsyncBaseEugene Burmako2014-02-151-3/+5
| |
* | compat => internalEugene Burmako2014-02-151-3/+2
| |
* | removes logic that branches on forInteractiveEugene Burmako2014-02-152-30/+4
| |
* | using compat._ to plug source compatibility breakagesEugene Burmako2014-02-151-2/+3
| |
* | silences a warning in AsyncAnalysisEugene Burmako2014-02-121-1/+1
| |
* | toolboxClasspath now works for snapshotsEugene Burmako2014-02-121-0/+2
|/
* Unhardcode use of scala.util.TryJason Zaugg2014-01-282-5/+2
| | | | In favour of the type defined by the active FutureSystem.
* Merge pull request #56 from retronym/topic/still-todoJason Zaugg2014-01-141-1/+1
|\ | | | | Update TODO comment about pres. compiler friendliness.
| * Update TODO comment about pres. compiler friendliness.Jason Zaugg2014-01-141-1/+1
| |
* | Update copyright years.Jason Zaugg2014-01-1432-33/+33
|/ | | | 2013 must have been unlucky.
* Minor fixes in Async`s scaladoc.akomar2014-01-121-2/+2
|
* Merge pull request #47 from retronym/topic/pres2Jason Zaugg2013-11-221-6/+5
|\ | | | | Another take at the 2.10/2.11 spanning suppressMacroAttachment