sbt throws AssertionError at compilation with indecipherable error message - scala

I've been getting these weird error messages when trying to recompile my sbt project, after adding some small changes to the code. Sometimes, depending on the edited code, the error disappears after cleaning the sbt project, but other times the error persists.
One example of how the error appears (but doesn't persist)
Adding this method to the Terrain class and compiling gives an error message that disappears after cleaning the project and recompiling:
def genChunkInputData(p: Vector3i): FloatBuffer = {
val inputData = MemoryUtil.memAllocFloat(4 * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1))
val r = (0 to Chunk.SIZE + 1)
for (i <- r; j <- r; k <- r) {
inputData.put(0.1F + 0.5F*min(i, Chunk.SIZE - i).toFloat/ Chunk.SIZE). //RED
put(0.1F + 0.5F*min(j, Chunk.SIZE - j).toFloat/ Chunk.SIZE). //GREEN
put(0.1F + 0.5F*min(k, Chunk.SIZE - k).toFloat/ Chunk.SIZE).//BLUE
put(isovalue((i + p(2)*Chunk.SIZE).toDouble, (j + p(1)*Chunk.SIZE).toDouble, (k + p(0)*Chunk.SIZE).toDouble)) //ISOVALUE
}
inputData.flip()
inputData
}
Here are some snippets from the error message:
[error] ## Exception when compiling 21 sources to D:\Computer science\Scala\Meandering Depths\target\scala-2.13\classes
[error] java.lang.AssertionError: assertion failed:
[error] List(method apply$mcI$sp, method apply$mcI$sp)
[error] while compiling: D:\Computer science\Scala\Meandering Depths\src\main\scala\game\Terrain.scala
[error] during phase: globalPhase=specialize, enteringPhase=explicitouter
[error] library version: version 2.13.3
[error] compiler version: version 2.13.3
[error] reconstructed args:
and
[error]
[error] last tree to typer: Select(Ident(r), foreach$mVc$sp)
[error] tree position: line 77 of D:\Computer science\Scala\Meandering Depths\src\main\scala\game\Terrain.scala
[error] tree tpe: (f: Int => Unit): Unit
[error] symbol: (final override) method foreach$mVc$sp in class Range
[error] symbol definition: final override def foreach$mVc$sp(f: Int => Unit): Unit (a MethodSymbol)
[error] symbol package: scala.collection.immutable
[error] symbol owners: method foreach$mVc$sp -> class Range
[error] call site: method $anonfun$genChunkInputData in package game
[error]
[error] == Source file context for tree position ==
[error]
[error] 74 def genChunkInputData(p: Vector3i): FloatBuffer = {
[error] 75 val inputData = MemoryUtil.memAllocFloat(4 * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1) * (Chunk.SIZE+ 1))
[error] 76 val r = (0 to Chunk.SIZE)
[error] 77 for (i <- r; j <- r; k <- r) {
[error] 78 inputData.put(0.1F + 0.5F*min(i, Chunk.SIZE - i).toFloat/ Chunk.SIZE). //RED
[error] 79 put(0.1F + 0.5F*min(j, Chunk.SIZE - j).toFloat/ Chunk.SIZE). //GREEN
[error] 80 put(0.1F + 0.5F*min(k, Chunk.SIZE - k).toFloat/ Chunk.SIZE).//BLUE
[error] scala.reflect.internal.SymbolTable.throwAssertionError(SymbolTable.scala:170)
[error] scala.reflect.internal.Symbols$Symbol.suchThat(Symbols.scala:2024)[error] scala.tools.nsc.transform.SpecializeTypes$SpecializationTransformer.matchingSymbolInPrefix$1(SpecializeTypes.scala:1573)
However, after following these steps, if you choose to remove that method from the Terrain class, it will again throw a similar error, but this time the source seems to have changed (to a different method, which had had no issue before and worked just fine). Again, by cleaning the build and recompiling, the error disappears.
Here is the change to the error message:
[error] last tree to typer: Function(value $anonfun)
[error] tree position: line 150 of D:\Computer science\Scala\Meandering Depths\src\main\scala\game\Terrain.scala
[error] tree tpe: Int => Unit
[error] symbol: value $anonfun
[error] == Source file context for tree position ==
[error]
[error] 147
[error] 148 private def isovalue(x: Double, y: Double, z: Double): Float = {
[error] 149 var res = -0.1F
[error] 150 for (i <- 0 until 4)
[error] 151 res += amp(i) * noise(i).noise3_XYBeforeZ(freq(i) * x, freqY(i) * y,freq(i) * z).toFloat
[error] 152 res
[error] 153 }
What is weird is, sometimes after following these steps of adding some code, compiling and getting an error, cleaning the build and recompiling with no error and then removing said code and compiling to get a new error message, the apparent source of the new error might come from a completely different class, which was behaving just fine prior to that.
What is more, and this is actually my real issue, is that sometimes the change in code causes the error to persist despite cleaning the build.
It also doesn't help that the error message doesn't tell me much, and confusingly enough it seems to be pointing to the wrong source at times. I must confess however that I don't really understand how sbt works and I'm just using it to import some libraries, but I had no issues with it before.
EDIT: Apparently it's caused by the scala compiler, not sbt itself. Error message seems to be similar to this one: https://github.com/scala/bug/issues/9578
I've tested the code from that link and it does give the same type of error I was getting with my code (and the source presented in the error message is again irrelevant to the error). I am using breeze in my project, so that seems to be the source of the problem. I'll attempt to remove it from the project and see if the error still occurs.

I have managed to find the source of the problem, which as expected has nothing to do with sbt, but with Breeze. The problem is exactly the one in this open issue: https://github.com/scala/bug/issues/9578
My workaround was to stop using DenseVector[Int] (right now I am using DenseVector[Float] but will probably switch to a different linear algebra library soon).

Related

Scala internal compiler error (possibly?)

Code runs fine in scala repl, will not compile as part of a scala source code base. Seems like the compiler is throwing some kind of an internal error.
I have a List[(String,(Int,Int))] I want to convert to Map[String,List[(Int,Int)] so that I can search it faster. It is basically a set of buckets indexed by the String component of the map that I can then search over and over using maybe binary search, once I have zeroed in on a bucket. I am trying to build the Map structure from the List structure, using a foldLeft operation.
val tpls:List[(String,(Int,Int))] = sm.compressedSegmentList.
map(_.split("|")).
map(s => (s(1), s(2).toInt, s(3).toInt)).
sortBy(_._1).
map(s => (s._1 -> (s._2,s._3)))
val chrBuckets:Map[String,List[(Int,Int)]] =
tpls.
foldLeft(Map().empty.asInstanceOf[String,List[(Int,Int)]])(
(y,x) => {
if (!y.contains(x._1)) y ++ Map(x._1->List(x._2))
else y ++ Map(x._1 -> (y(x._1):+x._2))
}
)
In the scala REPL, I can do the following:
scala> val l1 = List(("a",(1,2)),("a", (2,3)), ("a",(3,4)), ("b", (17,18)), ("b", (18,19)), ("c", (20,21)), ("d",(0,0)))
l1: List[(String, (Int, Int))] = List((a,(1,2)), (a,(2,3)), (a,(3,4)), (b,(17,18)), (b,(18,19)), (c,(20,21)), (d,(0,0)))
scala> l1.foldLeft(Map().empty.asInstanceOf[Map[String,List[(Int,Int)]]])((y,x) => if (!y.contains(x._1)) y ++ Map(x._1->List(x._2)) else y ++ Map(x._1 -> (y(x._1):+x._2)))
res88: Map[String,List[(Int, Int)]] = Map(a -> List((1,2), (2,3), (3,4)), b -> List((17,18), (18,19)), c -> List((20,21)), d -> List((0,0)))
However, when I compile my project using "sbt compile", it fails to compile by throwing up, such as:
[error] last tree to typer: Ident(scala)
[error] tree position: line 26 of /usr/home/maketo/util/SegmentMatcher.scala
[error] tree tpe: scala.type
[error] symbol: final package scala
[error] symbol definition: final package scala (a ModuleSymbol)
[error] symbol package: <none>
[error] symbol owners: package scala
[error] call site: class SegmentMatcher in package util in package util
[error]
[error] == Source file context for tree position ==
[error]
[error] 23 // within the bucket we can do binary search on "segStart" and "segEnd" fields
[error] 24 // after we sort first by segStart and then segEnd
[error] 25 val chrBuckets:Map[String,List[(Int,Int)]] = tpls.
[error] 26 foldLeft(Map().empty.asInstanceOf[String,List[(Int,Int)]])((y,x) => { if (!y.contains(x._1)) y ++ Map(x._1->List(x._2)) else y ++ Map(x._1 -> (y(x._1):+x._2))})
[error] 27
[error] 28 // take a segment and match it against a segmentation
[error] 29 // return segment ID or None
[error] at scala.reflect.internal.SymbolTable.throwAssertionError(SymbolTable.scala:183)
[error] at scala.tools.nsc.typechecker.Typers$Typer.vanillaAdapt$1(Typers.scala:1189)
[error] at scala.tools.nsc.typechecker.Typers$Typer.adapt(Typers.scala:1243)
[error] at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5740)
[error] at scala.tools.nsc.typechecker.Typers$Typer.$anonfun$typed1$60(Typers.scala:5142)
[error] at scala.tools.nsc.typechecker.Typers$Typer.typedTypeSelectionQualifier$1(Typers.scala:5142)
[error] at scala.tools.nsc.typechecker.Typers$Typer.typedSelectOrSuperCall$1(Typers.scala:5150)
.. snipped for brevity, to this:
[error] (Compile / compileIncremental) java.lang.AssertionError: assertion failed:
[error] Context(SegmentMatcher.scala) {
[error] owner = value chrBuckets
[error] tree = Apply:tpls.foldLeft(Map().empty.asInstanceOf[String, List[scala.Tuple2[Int,
[error] scope = 0 decls
[error] contextMode = MacrosEnabled TypeConstructorAllowed
[error] outer.owner = value chrBuckets
[error] }
[error] while compiling: /usr/home/maketo/SegmentMatcher.scala
[error] during phase: typer
[error] library version: version 2.12.8
[error] compiler version: version 2.12.8
Yes, that's an internal compiler error. The following snippet crashes 2.12.5 - 2.12.8 and 2.13.0-M5:
Map().asInstanceOf[Int, List[(Int, Int)]]
Workaround (that's what you should have done anyway, compiler error or not):
Map.empty[Int, List[(Int, Int)]]
I understand you are looking to figure out whether the above was a compiler error, but, if you are looking for a workaround, see if one of these 2 snippets work for you.
// Initialize
val tpls: List[(String, (Int, Int))] = List(
"foo" -> (1, 2),
"bar" -> (3, 4),
"foo" -> (5, 6)
)
// Option 1
tpls.groupBy(_._1).mapValues(_.map(_._2))
// returns Map(foo -> List((1,2), (5,6)), bar -> List((3,4)))
// Option 2
val emptyMap = Map.empty[String, List[(Int,Int)]].withDefaultValue(List.empty[(Int, Int)])
tpls.foldLeft(emptyMap) { case (mapSoFar, (segmentName, interval)) =>
mapSoFar.updated(segmentName, interval::mapSoFar(segmentName))
}
// returns Map(foo -> List((5,6), (1,2)), bar -> List((3,4)))
The second result is in reverse order, but, I just wanted to note that for lists :: is significantly less expensive that :+ (in case you don't care about the order)

Macro untypecheck required

I'm running into problems in my open-source project using Macros to generate some code. Everything works fine if I use c.untypecheck, but ideally I'd prefer not to have to do that.
This is the relevant code: https://github.com/outr/reactify/blob/master/shared/src/main/scala/com/outr/reactify/Macros.scala#L46
If I remove the c.untypecheck I get the following compile-time error:
[error] (reactifyJVM/test:compileIncremental) java.lang.AssertionError: assertion failed:
[error] transformCaseApply: name = previousVal tree = previousVal / class scala.reflect.internal.Trees$Ident
[error] while compiling: /home/mhicks/projects/open-source/reactify/shared/src/test/scala/specs/BasicSpec.scala
[error] during phase: refchecks
[error] library version: version 2.12.1
[error] compiler version: version 2.12.1
[error] reconstructed args: -classpath /home/mhicks/projects/open-source/reactify/jvm/target/scala-2.12/test-classes:/home/mhicks/projects/open-source/reactify/jvm/target/scala-2.12/classes:/home/mhicks/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.12.1.jar:/home/mhicks/.ivy2/cache/org.scalatest/scalatest_2.12/bundles/scalatest_2.12-3.0.1.jar:/home/mhicks/.ivy2/cache/org.scalactic/scalactic_2.12/bundles/scalactic_2.12-3.0.1.jar:/home/mhicks/.ivy2/cache/org.scala-lang.modules/scala-xml_2.12/bundles/scala-xml_2.12-1.0.5.jar:/home/mhicks/.ivy2/cache/org.scala-lang.modules/scala-parser-combinators_2.12/bundles/scala-parser-combinators_2.12-1.0.4.jar -bootclasspath /usr/java/jdk1.8.0_92/jre/lib/resources.jar:/usr/java/jdk1.8.0_92/jre/lib/rt.jar:/usr/java/jdk1.8.0_92/jre/lib/sunrsasign.jar:/usr/java/jdk1.8.0_92/jre/lib/jsse.jar:/usr/java/jdk1.8.0_92/jre/lib/jce.jar:/usr/java/jdk1.8.0_92/jre/lib/charsets.jar:/usr/java/jdk1.8.0_92/jre/lib/jfr.jar:/usr/java/jdk1.8.0_92/jre/classes:/home/mhicks/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.1.jar
[error]
[error] last tree to typer: TypeTree(class Position)
[error] tree position: line 148 of /home/mhicks/projects/open-source/reactify/shared/src/test/scala/specs/BasicSpec.scala
[error] tree tpe: org.scalactic.source.Position
[error] symbol: case class Position in package source
[error] symbol definition: case class Position extends Product with Serializable (a ClassSymbol)
[error] symbol package: org.scalactic.source
[error] symbol owners: class Position
[error] call site: <$anon: com.outr.reactify.ChangeListener[Int]> in package specs
[error]
[error] == Source file context for tree position ==
[error]
[error] 145 current should be(15)
[error] 146 }
[error] 147 "observe a complex change" in {
[error] 148 val v1 = Var(5)
[error] 149 val v2 = Var(10)
[error] 150 val v3 = Var(v1 + v2)
[error] 151 var changed = 0
[error] Total time: 1 s, completed Jan 31, 2017 4:43:03 PM
If I add it back everything compiles and works just fine. In more complex use-cases I've been encountering some issues at compile-time Could not find proxy for ... and I think this might be the reason.
Any suggestions would be greatly appreciated.
You're introducing an untyped tree into a typed tree.
The incoming tree is typechecked, and then the outgoing tree (that your macro emits) is typechecked again, but the typer does not descend into a tree that is already typechecked (i.e., that has a type already assigned to it).
Because you're introducing new symbols, you can't just use the incoming context to typecheck your reference.
So, the simplest solution is what you arrived at, to untypecheck the outgoing tree. It's also sufficient to untypecheck the transformed tree, to allow typer to descend to your new, untyped tree.
I had to reduce the exploding test by commenting out code. It's unfortunate that it's not immediately obvious what source line causes the error. Maybe it's more obvious if you're familiar with the macro involved.
class Sample {
def sample(): Unit = {
val v = Var(5)
v := v + 5
}
}
The tree in question, from -Xprint:typer -Yshow-trees:
Apply( // def +(x: Int): Int in class Int, tree.tpe=Int
com.outr.reactify.`package`.state2Value[Int](previousVal)."$plus" // def +(x: Int): Int in class Int, tree.tpe=(x: Int)Int
5
)
Also worth mentioning that it was easier to write a quick compile script with the "reconstructed args" in the error message, to eliminate sbt incremental compilation, ScalaTest macros and other mysteries.
Edit, the API for setting by hand:
def setStateChannel(value: c.Tree): c.Tree = {
val observables = retrieveObservables(c)(value)
val channel = c.prefix.tree
val selfReference = observables.exists(_.equalsStructure(channel))
val untyped =
q"""
val previousValue = com.outr.reactify.State.internalFunction($channel)
val previousVal = com.outr.reactify.Val(previousValue())
"""
val retyped = c.typecheck(untyped)
val transformed = if (selfReference) {
val transformer = new Transformer {
override def transform(tree: c.universe.Tree): c.universe.Tree = if (tree.equalsStructure(channel)) {
val t = q"previousVal"
val Block(_ :: v :: Nil, _) = retyped
c.internal.setSymbol(t, v.symbol)
c.internal.setType(t, v.tpe)
} else {
super.transform(tree)
}
}
transformer.transform(value)
} else {
value
}
val res = q"$channel.update(List(..$observables), $transformed)"
q"$retyped ; $res"
}

Error after running "sbt test" in Chisel 3

I'm trying to use chisel 3.
I tried to test GCD.scala file in the chisel project template repo using sbt test and sbt "test-only example.GCD" commands following the answer to a previous question. But this gives an error(s) that I cannot find the reason for. I didn't do any changes to the build.sbt file or repo layout. I'm posting only the last part of the error message since it is very long and repetitive.
[info] Loading project definition from /home/isuru/fyp/ChiselProjects/TrialProject/project
[info] Set current project to chisel-module-template (in build file:/home/isuru/fyp/ChiselProjects/TrialProject/)
[info] Compiling 1 Scala source to /home/isuru/fyp/ChiselProjects/TrialProject/target/scala-2.11/classes...
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:5: not found: object Chisel3
[error] import Chisel3._
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:7: not found: type Module
[error] class GCD extends Module {
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:8: not found: type Bundle
[error] val io = new Bundle {
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:9: not found: value UInt
[error] val a = UInt(INPUT, 16)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:9: not found: value INPUT
[error] val a = UInt(INPUT, 16)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:10: not found: value UInt
[error] val b = UInt(INPUT, 16)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:10: not found: value INPUT
[error] val b = UInt(INPUT, 16)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:11: not found: value Bool
[error] val e = Bool(INPUT)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:11: not found: value INPUT
[error] val e = Bool(INPUT)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:12: not found: value UInt
[error] val z = UInt(OUTPUT, 16)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:12: not found: value OUTPUT
[error] val z = UInt(OUTPUT, 16)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:13: not found: value Bool
[error] val v = Bool(OUTPUT)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:13: not found: value OUTPUT
[error] val v = Bool(OUTPUT)
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:15: not found: value Reg
[error] val x = Reg(UInt())
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:15: not found: value UInt
[error] val x = Reg(UInt())
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:16: not found: value Reg
[error] val y = Reg(UInt())
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:16: not found: value UInt
[error] val y = Reg(UInt())
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:17: not found: value when
[error] when (x > y) { x := x - y }
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:18: not found: value unless
[error] unless (x > y) { y := y - x }
[error] ^
[error] /home/isuru/fyp/ChiselProjects/TrialProject/src/main/scala/example/GCD.scala:19: not found: value when
[error] when (io.e) { x := io.a; y := io.b }
[error] ^
[error] 20 errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 2 s, completed Dec 1, 2016 8:26:25 PM
The errors you have shown suggest that sbt is somehow not finding Chisel, could you by chance show the full list of errors (especially early on ones)? With the following sequence of commands I am unable to reproduce the errors you are seeing:
git clone git#github.com:ucb-bar/chisel-template.git
cd chisel-template
sbt test
It is not the cause of this issue, but to run the test in chisel-template you should actually run sbt "test-only examples.test.GCDTester". example.GCD is the top of the design, but to run the test you have to refer to the Tester class in src/test/scala/examples/test/GCDUnitTest.scala.
I just encountered this same problem when making my own chisel project. However it was not that the import chisel3._ was wrong. The problem I had was I did not have a build.sbt file included in my directory.
I found my solution here.
https://chisel.eecs.berkeley.edu/2.0.6/getting-started.html

Specs2 won't print scalacheck counterexamples?

I'm using specs2 to run my tests. I'm able to get it running scalacheck, but in the below (when I run with sbt test) it doesn't print the counterexample. This is almost useless without the counterexample:
import org.specs2.mutable.Specification
import org.scalacheck.Properties
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.scalacheck.Parameters
import org.scalacheck.Gen
class StripeExportSpec extends Specification with ScalaCheck {
import StripeExportJob._
//.verbose makes no difference
implicit val params = Parameters().setVerbosity(10)
val p2: Properties = new Properties("dayIntervals") {
val dayEpochs = for {
n <- Gen.choose(1l, 500l)
m <- Gen.choose(n, 500l)
} yield (n*twentyFourHours,m*twentyFourHours)
property("aligns start to first parameter") = Prop.forAll(dayEpochs) { x: (Long,Long) =>
val (a, b) = x
val result = dayIntervals(a, b)
result.head._1 == a
}
property("aligns end correctly to 24 hours after b") = Prop.forAll(dayEpochs) { x: (Long,Long) =>
val (a, b) = x
val result = dayIntervals(a, b)
result.last._2 == b+twentyFourHours
}
}
//s2"dayIntervals respects ${properties(p2)}"
"dayIntervals respects " >> addFragments(properties(p2))
}
Instead all I get is:
[info] StripeExportSpec
[info]
[info] dayIntervals respects
[info]
[error] ! dayIntervals.aligns start to first parameter
[error] java.lang.AssertionError: assertion failed (StripeExport.scala:157)
[error] com.handy.pipeline.jobs.StripeExportJob$.dayIntervals(StripeExport.scala:157)
[error] com.handy.pipeline.jobs.StripeExportSpec$$anon$1$$anonfun$2.apply(StripeExportSpec.scala:28)
[error] com.handy.pipeline.jobs.StripeExportSpec$$anon$1$$anonfun$2.apply(StripeExportSpec.scala:26)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:713)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:713)
[error] org.scalacheck.Prop$.secure(Prop.scala:457)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.org$scalacheck$Prop$$anonfun$$result$1(Prop.scala:713)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$4.apply(Prop.scala:720)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$4.apply(Prop.scala:720)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.getFirstFailure$1(Prop.scala:720)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.shrinker$1(Prop.scala:730)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:752)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:707)
[error] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:292)
[error] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:291)
[error] org.scalacheck.PropFromFun.apply(Prop.scala:22)
[error] org.scalacheck.Test$.org$scalacheck$Test$$workerFun$1(Test.scala:294)
[error] org.scalacheck.Test$$anonfun$3.apply(Test.scala:323)
[error] org.scalacheck.Test$$anonfun$3.apply(Test.scala:323)
[error] org.scalacheck.Platform$.runWorkers(Platform.scala:40)
[error] org.scalacheck.Test$.check(Test.scala:323)
[error] com.handy.pipeline.jobs.StripeExportSpec.check(StripeExportSpec.scala:14)
[info]
[error] ! dayIntervals.aligns end correctly to 24 hours after b
[error] java.lang.AssertionError: assertion failed (StripeExport.scala:157)
[error] com.handy.pipeline.jobs.StripeExportJob$.dayIntervals(StripeExport.scala:157)
[error] com.handy.pipeline.jobs.StripeExportSpec$$anon$1$$anonfun$5.apply(StripeExportSpec.scala:34)
[error] com.handy.pipeline.jobs.StripeExportSpec$$anon$1$$anonfun$5.apply(StripeExportSpec.scala:32)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:713)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:713)
[error] org.scalacheck.Prop$.secure(Prop.scala:457)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.org$scalacheck$Prop$$anonfun$$result$1(Prop.scala:713)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$4.apply(Prop.scala:720)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$4.apply(Prop.scala:720)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.getFirstFailure$1(Prop.scala:720)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.shrinker$1(Prop.scala:730)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:752)
[error] org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:707)
[error] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:292)
[error] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:291)
[error] org.scalacheck.PropFromFun.apply(Prop.scala:22)
[error] org.scalacheck.Test$.org$scalacheck$Test$$workerFun$1(Test.scala:294)
[error] org.scalacheck.Test$$anonfun$3.apply(Test.scala:323)
[error] org.scalacheck.Test$$anonfun$3.apply(Test.scala:323)
[error] org.scalacheck.Platform$.runWorkers(Platform.scala:40)
[error] org.scalacheck.Test$.check(Test.scala:323)
[error] com.handy.pipeline.jobs.StripeExportSpec.check(StripeExportSpec.scala:14)
This is a bug in specs2 which occurs when you throw AssertionErrors (or any kind of java.lang.Error in properties. This is fixed in 3.8.4-20160905063548-8470e96.
Also, since you are using a specification you don't have to use ScalaCheck Properties. You can write:
"dayIntervals" >> {
"aligns start to first parameter" >> Prop.forAll(dayEpochs) { x: (Long,Long) =>
val (a, b) = x
val result = dayIntervals(a, b)
result.head._1 === a
}
// another way of using generators
"aligns end correctly to 24 hours after b" >> prop { x: (Long,Long) =>
val (a, b) = x
val result = dayIntervals(a, b)
result.last._2 === b+twentyFourHours
}.setGen(dayEpochs)
}
val dayEpochs = for {
n <- Gen.choose(1l, 500l)
m <- Gen.choose(n, 500l)
} yield (n*twentyFourHours,m*twentyFourHours)

How can I use Scala macros to create an object?

I am trying to create a Scala macro that will generate an object - something like
object SomeEnum {
sealed abstract class Enum(name: String)
case object Option1 extends Enum("option1")
case object Option2 extends Enum("option2")
private val elements: Seq[Enum] = Seq(Option1, Option2)
def apply(code: String): Enum = {
...
}
}
I thought I might be able to create a macro createEnum, so I could just put
createEnum("SomeEnum", "Option1", "Option2") into my code and have it generate. Seems like it's calling out for a macro.
But I must not be understanding macros. I am using Scala 2.11.6, and just to try to get something working, I created the following:
object createEnumObj {
def createEnumImpl(c: scala.reflect.macros.whitebox.Context)(ename: c.Expr[String]): c.universe.ModuleDef = {
import c.universe._
val Literal(Constant(s_ename: String)) = ename.tree
val oname = TermName(s_ename)
val barLine = q"val bar: Int = 5"
q"object $oname { $barLine }"
}
def createEnum(ename: String): Unit = macro createEnumImpl
}
This is in a separate project - everything seems to be compiling for it OK.
If I stick a call to createEnumObj.createEnum into some source and try to compile that, I get a billion lines (give or take a few) of exception output, which seems to repeat something like this:
[error] (main/compile:compile) java.lang.AssertionError: assertion failed:
[error] object foo extends scala.AnyRef {
[error] def <init>() = {
[error] super.<init>();
[error] ()
[error] };
[error] val bar: Int = 5
[error] }
[error] while compiling: /Users/bob/ICL/ironcore-id/src/main/scala/package.scala
[error] during phase: typer
[error] library version: version 2.11.6
[error] compiler version: version 2.11.6
[error] reconstructed args: -Xfuture ...
error]
[error] last tree to typer: term foo
[error] tree position: line 8 of /Users/bob/ICL/ironcore-id/src/main/scala/package.scala
[error] symbol: <none>
[error] symbol definition: <none> (a NoSymbol)
[error] symbol package: <none>
[error] symbol owners:
[error] call site: <none> in <none>
[error]
[error] == Source file context for tree position ==
[error]
[error] 5 type DateTime = Int
[error] 6
[error] 7 createEnumObj.createEnum("foo")
[error] 8
[error] 9 }
[error] Total time: 2 s, completed Jun 18, 2015 2:46:05 PM
What I am trying to do doesn't seem too dissimilar to this question, but I'm obviously missing something. Any ideas about how to accomplish this would be gratefully accepted.
Thanks,
Bob