Commit Graph

18 Commits

Author SHA1 Message Date
Jason Zaugg 10ed229004 SI-8263 Avoid SOE in Symbol#logicallyEnclosingMember under Scala 2.11
Since the fix for SI-2066, Scala 2.11 calls logicallyEnclosingMember on the
`x` in the expansion of the task macro:

    InitializeInstance.app[[T0[x]](T0[java.io.File], T0[java.io.File]), Seq[java.io.File]]

This exposed the fact that SBT has created `T0` with `NoSymbol` as
the owner. This led to the a SOE.

I will also change the compiler to be more tolerant of this, but we
can observe good discipline in the macro and pick a sensible owner.
2014-02-12 13:30:46 +01:00
Mark Harrah 4d7dccb02e Remove the need for resetLocalAttrs. Fixes #994, #952.
The fix was made possible by the very helpful information provided by @retronym.

This commit does two key things:
 1. changes the owner when splicing original trees into new trees
 2. ensures the synthetic trees that get spliced into original trees do not need typechecking

Given this original source (from Defaults.scala):

  ...
  lazy val sourceConfigPaths = Seq(
    ...
    unmanagedSourceDirectories := Seq(scalaSource.value, javaSource.value),
    ...
  )
  ...

After expansion of .value, this looks something like:

    unmanagedSourceDirectories := Seq(
      InputWrapper.wrapInit[File](scalaSource),
      InputWrapper.wrapInit[File](javaSource)
    )

where wrapInit is something like:

    def wrapInit[T](a: Any): T

After expansion of := we have (approximately):

    unmanagedSourceDirectories <<=
      Instance.app( (scalaSource, javaSource) ) {
        $p1: (File, File) =>
          val $q4: File = $p1._1
          val $q3: File = $p1._2
          Seq($q3, $q4)
      }

So,

 a) `scalaSource` and `javaSource` are user trees that are spliced into a tuple constructor after being temporarily held in `InputWrapper.wrapInit`
 b) the constructed tuple `(scalaSource, javaSource)` is passed as an argument to another method call (without going through a val or anything) and shouldn't need owner changing
 c) the synthetic vals $q3 and $q4 need their owner properly set to the anonymous function
 d) the references (Idents) $q3 and $q4 are spliced into the user tree `Seq(..., ...)` and their symbols need to be the Symbol for the referenced vals
 e) generally, treeCopy needs to be used when substituting Trees in order to preserve attributes, like Types and Positions

changeOwner is called on the body `Seq($q3, $q4)` with the original owner sourceConfigPaths to be changed to the new anonymous function.
In this example, no owners are actually changed, but when the body contains vals or anonymous functions, they will.

An example of the compiler crash seen when the symbol of the references is not that of the vals:

symbol value $q3 does not exist in sbt.Defaults.sourceConfigPaths$lzycompute
	at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
	at scala.tools.nsc.Global.abort(Global.scala:254)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadIdent$1(GenICode.scala:1038)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:1044)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genLoadArguments$1.apply(GenICode.scala:1246)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genLoadArguments$1.apply(GenICode.scala:1244)
   ...

Other problems with the synthetic tree when it is spliced under the original tree often result in type mismatches or some other compiler error that doesn't result in a crash.

If the owner is not changed correctly on the original tree that gets spliced under a synthetic tree, one way it can crash the compiler is:

java.lang.IllegalArgumentException: Could not find proxy for val $q23: java.io.File in List(value $q23, method apply, anonymous class $anonfun$globalCore$5, value globalCore, object Defaults, package sbt, package <root>) (currentOwner= value dir )
   ...
     while compiling: /home/mark/code/sbt/main/src/main/scala/sbt/Defaults.scala
        during phase: global=lambdalift, atPhase=constructors
   ...
  last tree to typer: term $outer
              symbol: value $outer (flags: <synthetic> <paramaccessor> <triedcooking> private[this])
   symbol definition: private[this] val $outer: sbt.BuildCommon
                 tpe: <notype>
       symbol owners: value $outer -> anonymous class $anonfun$87 -> value x$298 -> method derive -> class BuildCommon$class -> package sbt
      context owners: value dir -> value globalCore -> object Defaults -> package sbt
   ...

The problem here is the difference between context owners and the proxy search chain.
2013-11-22 13:08:10 -05:00
Mark Harrah 0f9108d9d8 Merge remote-tracking branch 'cancel-bug' into 0.13 2013-07-19 18:56:01 -04:00
Mark Harrah ca0d2b05cc specify explicit type to work around 2.11 volatile override error 2013-07-18 22:38:16 -04:00
Mark Harrah 9b1cdb7534 set position on parameter references in task/setting macros 2013-06-19 11:53:11 -04:00
Mark Harrah ee5f09d810 Construct input tasks in multiple steps to allow input task reuse. Fixes #407. 2013-03-08 14:23:30 -05:00
Mark Harrah d426035da3 deprecations 2013-02-25 09:24:04 -05:00
Mark Harrah 13e1b00436 Use @compileTimeOnly for .value and .parsed methods.
Needed to set position on wrapper method for correct error message position.
2013-02-19 08:54:40 -05:00
Mark Harrah f6c73ff4c7 use standard Context.weakTypeOf 2013-01-28 17:14:53 -05:00
Mark Harrah 2929e4e724 Reduce InputTask to the ideal wrapper around 'State => Parser[Initialize[Task[T]]]'
Ref #407.
2013-01-28 17:14:53 -05:00
Grzegorz Kossakowski e719c5fb2e Follow source layout convention supported by Eclipse.
Moved source files so directory structure follow package
structure. That makes it possible to use Scala Eclipse plugin
with sbt's source code.
2012-12-07 10:27:08 -08:00
Mark Harrah 41e2fdf647 Explicitly specify type parameters in calls to KCons in KList builder.
scalac couldn't infer the type constructor otherwise.
2012-11-18 09:20:26 -05:00
Mark Harrah 40a034c3a7 InputTask macro
Similar to task macros, the parsed value is accessed by calling `parsed`
on a Parser[T], Initialize[Parser[T]], or Initialize[State => Parser[T]].
Values of tasks and settings may be accessed as usual via `value`.
2012-11-17 20:23:07 -05:00
Mark Harrah c2760ecbdd AbsTypeTag -> WeakTypeTag and converted more settings 2012-11-17 20:23:06 -05:00
Mark Harrah f536e6d9ac Scala 2.10.0-M7 2012-11-17 20:23:06 -05:00
Mark Harrah e967d35448 move explicit task/setting macros to Def, move to AbsTypeTag 2012-11-17 20:23:06 -05:00
Mark Harrah a3d6a5d5b3 Task macro cleanup
* use normal TypeTree constructor
* remove unnecessary 'with Singleton' in macro utility
* integrate changes suggested by @xeno-by
* add refVar back and call asTypeConstructor instead of asType to refer to a type variable
2012-11-17 20:22:39 -05:00
Mark Harrah 087e386c99 task setting macros for :=, +=, ++=
also, bump to 2.10.0-M6
2012-11-17 20:19:24 -05:00