Skip to content
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

Scala 2.12.0-RC2 #1415

Merged
merged 20 commits into from
Oct 25, 2016
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ git:
depth: 9999

scala:
- 2.10.6
- 2.11.8
- 2.10.6
- 2.11.8

jdk:
- oraclejdk7

matrix:
include:
- scala: 2.12.0-RC2
jdk: oraclejdk8

before_install:
- export PATH=${PATH}:./vendor/bundle
Expand Down
111 changes: 71 additions & 40 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
import com.typesafe.sbt.SbtGhPages.GhPagesKeys._
import sbtunidoc.Plugin.UnidocKeys._
import ReleaseTransformations._
import ScoverageSbtPlugin._
import scala.xml.transform.{RewriteRule, RuleTransformer}
import org.scalajs.sbtplugin.cross.CrossProject

lazy val botBuild = settingKey[Boolean]("Build by TravisCI instead of local dev environment")

lazy val scoverageSettings = Seq(
ScoverageKeys.coverageMinimum := 60,
ScoverageKeys.coverageFailOnMinimum := false,
ScoverageKeys.coverageHighlighting := scalaBinaryVersion.value != "2.10",
ScoverageKeys.coverageExcludedPackages := "cats\\.bench\\..*",
// don't include scoverage as a dependency in the pom
// see issue #980
// this code was copied from https://github.com/mongodb/mongo-spark
pomPostProcess := { (node: xml.Node) =>
new RuleTransformer(
new RewriteRule {
override def transform(node: xml.Node): Seq[xml.Node] = node match {
case e: xml.Elem
if e.label == "dependency" && e.child.exists(child => child.label == "groupId" && child.text == "org.scoverage") => Nil
case _ => Seq(node)

}

}).transform(node).head
}
coverageMinimum := 60,
coverageFailOnMinimum := false,
coverageHighlighting := scalaBinaryVersion.value != "2.10"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per gitter, I would expect that this is no longer required

)

lazy val buildSettings = Seq(
organization := "org.typelevel",
scalaVersion := "2.11.8",
crossScalaVersions := Seq("2.10.6", "2.11.8")
crossScalaVersions := Seq("2.10.6", "2.11.8", "2.12.0-RC2")
)

lazy val catsDoctestSettings = Seq(
Expand All @@ -46,7 +30,7 @@ lazy val kernelSettings = Seq(
Resolver.sonatypeRepo("snapshots")),
parallelExecution in Test := false,
scalacOptions in (Compile, doc) := (scalacOptions in (Compile, doc)).value.filter(_ != "-Xfatal-warnings")
) ++ warnUnusedImport
) ++ warnUnusedImport ++ update2_12

lazy val commonSettings = Seq(
incOptions := incOptions.value.withLogRecompileOnMacro(false),
Expand All @@ -57,17 +41,17 @@ lazy val commonSettings = Seq(
Resolver.sonatypeRepo("snapshots")
),
libraryDependencies ++= Seq(
"com.github.mpilquist" %%% "simulacrum" % "0.8.0",
"org.typelevel" %%% "machinist" % "0.4.1",
"com.github.mpilquist" %%% "simulacrum" % "0.10.0",
"org.typelevel" %%% "machinist" % "0.6.0",
compilerPlugin("org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full),
compilerPlugin("org.spire-math" %% "kind-projector" % "0.9.0")
compilerPlugin("org.spire-math" %% "kind-projector" % "0.9.2")
),
fork in test := true,
parallelExecution in Test := false,
scalacOptions in (Compile, doc) := (scalacOptions in (Compile, doc)).value.filter(_ != "-Xfatal-warnings"),
// workaround for https://github.com/scalastyle/scalastyle-sbt-plugin/issues/47
(scalastyleSources in Compile) <++= unmanagedSourceDirectories in Compile
) ++ warnUnusedImport
scalastyleSources in Compile ++= (unmanagedSourceDirectories in Compile).value
) ++ warnUnusedImport ++ update2_12

lazy val tagName = Def.setting{
s"v${if (releaseUseGlobalVersion.value) (version in ThisBuild).value else version.value}"
Expand All @@ -84,8 +68,6 @@ lazy val commonJsSettings = Seq(
},
scalaJSStage in Global := FastOptStage,
parallelExecution := false,
// Using Rhino as jsEnv to build scala.js code can lead to OOM, switch to PhantomJS by default
scalaJSUseRhino := false,
requiresDOM := false,
jsEnv := NodeJSEnv().value,
// Only used for scala.js for now
Expand Down Expand Up @@ -115,15 +97,15 @@ lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ sc

lazy val scalaCheckVersion = "1.13.2"
lazy val scalaTestVersion = "3.0.0"
lazy val disciplineVersion = "0.6"
lazy val disciplineVersion = "0.7.1"

lazy val disciplineDependencies = Seq(
libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion,
libraryDependencies += "org.typelevel" %%% "discipline" % disciplineVersion)

lazy val testingDependencies = Seq(
libraryDependencies += "org.typelevel" %%% "catalysts-platform" % "0.0.2",
libraryDependencies += "org.typelevel" %%% "catalysts-macros" % "0.0.2" % "test",
libraryDependencies += "org.typelevel" %%% "catalysts-platform" % "0.0.4",
libraryDependencies += "org.typelevel" %%% "catalysts-macros" % "0.0.4" % "test",
libraryDependencies += "org.scalatest" %%% "scalatest" % scalaTestVersion % "test")


Expand Down Expand Up @@ -224,6 +206,7 @@ lazy val macros = crossProject.crossType(CrossType.Pure)
.settings(catsSettings:_*)
.jsSettings(commonJsSettings:_*)
.jvmSettings(commonJvmSettings:_*)
.jsSettings(coverageEnabled := false)
.settings(scalacOptions := scalacOptions.value.filter(_ != "-Xfatal-warnings"))

lazy val macrosJVM = macros.jvm
Expand All @@ -236,7 +219,7 @@ lazy val kernel = crossProject.crossType(CrossType.Pure)
.settings(buildSettings: _*)
.settings(publishSettings: _*)
.settings(scoverageSettings: _*)
.settings(sourceGenerators in Compile <+= (sourceManaged in Compile).map(KernelBoiler.gen))
.settings(sourceGenerators in Compile += (sourceManaged in Compile).map(KernelBoiler.gen).taskValue)
.settings(includeGeneratedSrc)
.jsSettings(commonJsSettings:_*)
.jvmSettings((commonJvmSettings ++ (mimaPreviousArtifacts := Set("org.typelevel" %% "cats-kernel" % "0.7.0"))):_*)
Expand All @@ -255,6 +238,7 @@ lazy val kernelLaws = crossProject.crossType(CrossType.Pure)
.settings(testingDependencies: _*)
.jsSettings(commonJsSettings:_*)
.jvmSettings(commonJvmSettings:_*)
.jsSettings(coverageEnabled := false)
.dependsOn(kernel)

lazy val kernelLawsJVM = kernelLaws.jvm
Expand All @@ -264,8 +248,10 @@ lazy val core = crossProject.crossType(CrossType.Pure)
.dependsOn(macros, kernel)
.settings(moduleName := "cats-core")
.settings(catsSettings:_*)
.settings(sourceGenerators in Compile <+= (sourceManaged in Compile).map(Boilerplate.gen))
.settings(sourceGenerators in Compile += (sourceManaged in Compile).map(Boilerplate.gen).taskValue)
.settings(includeGeneratedSrc)
.configureCross(disableScoverage210Jvm)
.configureCross(disableScoverage210Js)
.settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion % "test")
.jsSettings(commonJsSettings:_*)
.jvmSettings(commonJvmSettings:_*)
Expand All @@ -278,9 +264,10 @@ lazy val laws = crossProject.crossType(CrossType.Pure)
.settings(moduleName := "cats-laws")
.settings(catsSettings:_*)
.settings(disciplineDependencies:_*)
.settings(libraryDependencies ++= Seq("org.typelevel" %%% "catalysts-platform" % "0.0.2"))
.settings(libraryDependencies ++= Seq("org.typelevel" %%% "catalysts-platform" % "0.0.4"))
.jsSettings(commonJsSettings:_*)
.jvmSettings(commonJvmSettings:_*)
.jsSettings(coverageEnabled := false)

lazy val lawsJVM = laws.jvm
lazy val lawsJS = laws.js
Expand Down Expand Up @@ -309,13 +296,15 @@ lazy val testsJVM = tests.jvm
lazy val testsJS = tests.js

// bench is currently JVM-only

lazy val bench = project.dependsOn(macrosJVM, coreJVM, freeJVM, lawsJVM)
.settings(moduleName := "cats-bench")
.settings(catsSettings)
.settings(noPublishSettings)
.settings(commonJvmSettings)
.settings(coverageEnabled := false)
.settings(libraryDependencies ++= Seq(
"org.scalaz" %% "scalaz-core" % "7.2.5"))
"org.scalaz" %% "scalaz-core" % "7.2.6"))
.enablePlugins(JmhPlugin)

// cats-js is JS-only
Expand All @@ -324,6 +313,7 @@ lazy val js = project
.settings(moduleName := "cats-js")
.settings(catsSettings:_*)
.settings(commonJsSettings:_*)
.configure(disableScoverage210Js)
.enablePlugins(ScalaJSPlugin)


Expand Down Expand Up @@ -461,8 +451,8 @@ lazy val scalaMacroDependencies: Seq[Setting[_]] = Seq(
// in Scala 2.10, quasiquotes are provided by macro paradise
case Some((2, 10)) =>
Seq(
compilerPlugin("org.scalamacros" %% "paradise" % "2.0.1" cross CrossVersion.full),
"org.scalamacros" %% "quasiquotes" % "2.0.1" cross CrossVersion.binary
compilerPlugin("org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full),
"org.scalamacros" %% "quasiquotes" % "2.1.0" cross CrossVersion.binary
)
}
}
Expand All @@ -479,7 +469,6 @@ lazy val commonScalacOptions = Seq(
"-unchecked",
"-Xfatal-warnings",
"-Xlint",
"-Yinline-warnings",
"-Yno-adapted-args",
"-Ywarn-dead-code",
"-Ywarn-numeric-widen",
Expand Down Expand Up @@ -529,7 +518,7 @@ lazy val warnUnusedImport = Seq(
}
},
scalacOptions in (Compile, console) ~= {_.filterNot("-Ywarn-unused-import" == _)},
scalacOptions in (Test, console) <<= (scalacOptions in (Compile, console))
scalacOptions in (Test, console) := (scalacOptions in (Compile, console)).value
)

lazy val credentialSettings = Seq(
Expand All @@ -539,3 +528,45 @@ lazy val credentialSettings = Seq(
password <- Option(System.getenv().get("SONATYPE_PASSWORD"))
} yield Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", username, password)).toSeq
)

def disableScoverage210Js(crossProject: CrossProject) =
crossProject
.jsSettings(
coverageEnabled := {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 10)) => false
case _ => coverageEnabled.value
}
}
)

def disableScoverage210Js: Project ⇒ Project = p =>
p.settings(
coverageEnabled := {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 10)) => false
case _ => coverageEnabled.value
}
}
)

def disableScoverage210Jvm(crossProject: CrossProject) =
crossProject
.jvmSettings(
coverageEnabled := {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 10)) => false
case _ => coverageEnabled.value
}
}
)

lazy val update2_12 = Seq(
scalacOptions -= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 12)) => "-Yinline-warnings"
case _ => ""
}
}
)

7 changes: 5 additions & 2 deletions core/src/main/scala/cats/Eval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ sealed abstract class Eval[+A] extends Serializable { self =>
case c: Eval.Compute[A] =>
new Eval.Compute[B] {
type Start = c.Start
val start = c.start
val run = (s: c.Start) =>
// See https://issues.scala-lang.org/browse/SI-9931 for an explanation
// of why the type annotations are necessary in these two lines on
// Scala 2.12.0.
val start: () => Eval[Start] = c.start
val run: Start => Eval[B] = (s: c.Start) =>
new Eval.Compute[B] {
type Start = A
val start = () => c.run(s)
Expand Down
28 changes: 21 additions & 7 deletions docs/src/main/tut/datatypes/either.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,30 @@ object Service {
Let's say we have an application that wants to do database things, and then take database
values and do service things. Glancing at the types, it looks like `flatMap` will do it.

```tut:fail:silent
```scala
def doApp = Database.databaseThings().flatMap(Service.serviceThings)
```

This doesn't work! The reason this occurs is because the first type parameter in the two `Either`s are different -
`databaseThings()` can give us a `DatabaseError` whereas `serviceThings()` can give us a
`ServiceError`: two completely unrelated types. While `Either`'s type parameters are covariant,
the aforementioned syntax enrichment is invariant to avoid nasty variance issues like inferring
`Object`. Therefore, when the compiler sees `Either[E1, A1]` and an `Either[E2, A2]`, it
will simply reject the `flatMap` call.
If you're on Scala 2.12, this line will compile and work as expected, but if you're on an earlier
version of Scala it won't! This difference is related to the right-biasing of `Either` in Scala 2.12
that was mentioned above. In Scala 2.12 the `flatMap` we get here is a method on `Either` with this
signature:

```scala
def flatMap[AA >: A, Y](f: (B) => Either[AA, Y]): Either[AA, Y]
```

This `flatMap` is different from the ones you'll find on `List` or `Option`, for example, in that it
has two type parameters, with the extra `AA` parameter allowing us to `flatMap` into an `Either`
with a different type on the left side.

This behavior is consistent with the covariance of `Either`, and in some cases it can be convenient,
but it also makes it easy to run into nasty variance issues (such as `Object` being inferred as the
type of the left side, as it is in this case).

For this reason the `flatMap` provided by Cats's `Either` syntax (which is the one you'll get for
Scala 2.10 and 2.11) does not include this extra type parameter. Instead the left sides have to
match, which means our `doApp` definition above will not compile on versions of Scala before 2.12.

### Solution 1: Application-wide errors
So clearly in order for us to easily compose `Either` values, the left type parameter must be the same.
Expand Down
7 changes: 4 additions & 3 deletions kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.typelevel.discipline.{ Laws }
import org.typelevel.discipline.scalatest.Discipline
import org.scalacheck.{ Arbitrary, Cogen, Gen }
import Arbitrary.arbitrary
import org.scalactic.anyvals.{ PosInt, PosZInt }
import org.scalatest.FunSuite

import scala.util.Random
Expand All @@ -18,11 +19,11 @@ import scala.collection.immutable.BitSet
class LawTests extends FunSuite with Discipline {

// The scalacheck defaults (100,100) are too high for scala-js.
final val PropMaxSize = if (Platform.isJs) 10 else 100
final val PropMinSuccessful = if (Platform.isJs) 10 else 100
final val PropMaxSize: PosZInt = if (Platform.isJs) 10 else 100
final val PropMinSuccessful: PosInt = if (Platform.isJs) 10 else 100

implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
PropertyCheckConfig(maxSize = PropMaxSize, minSuccessful = PropMinSuccessful)
PropertyCheckConfiguration(minSuccessful = PropMinSuccessful, sizeRange = PropMaxSize)

implicit def orderLaws[A: Cogen: Eq: Arbitrary]: OrderLaws[A] = OrderLaws[A]
implicit def groupLaws[A: Cogen: Eq: Arbitrary]: GroupLaws[A] = GroupLaws[A]
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=0.13.12
sbt.version=0.13.13-RC3
10 changes: 5 additions & 5 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.3.3")
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.3")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.9")
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.11")
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.3")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.11")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.16")
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.2.0")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.0-RC2")
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.8.5")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.11")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.13")
addSbtPlugin("com.github.tkawachi" % "sbt-doctest" % "0.4.1")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1")
addSbtPlugin("com.fortysevendeg" % "sbt-microsites" % "0.2.6")
addSbtPlugin("com.fortysevendeg" % "sbt-microsites" % "0.2.7")
2 changes: 1 addition & 1 deletion tests/src/test/scala/cats/tests/CatsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ trait TestSettings extends Configuration with Matchers {

lazy val slowCheckConfiguration: PropertyCheckConfiguration =
if (Platform.isJvm) checkConfiguration
else PropertyCheckConfig(maxSize = 1, minSuccessful = 1)
else PropertyCheckConfiguration(minSuccessful = 1, sizeRange = 1)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/src/test/scala/cats/tests/NestedTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class NestedTests extends CatsSuite {
// Scalacheck to calm down a bit so we don't hit memory and test duration
// issues.
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
PropertyCheckConfig(maxSize = 5, minSuccessful = 20)
PropertyCheckConfiguration(minSuccessful = 20, sizeRange = 5)

implicit val iso = {
implicit val instance = ListWrapper.functor
Expand Down
2 changes: 1 addition & 1 deletion tests/src/test/scala/cats/tests/NonEmptyListTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import cats.laws.discipline.arbitrary._
class NonEmptyListTests extends CatsSuite {
// Lots of collections here.. telling ScalaCheck to calm down a bit
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
PropertyCheckConfig(maxSize = 5, minSuccessful = 20)
PropertyCheckConfiguration(minSuccessful = 20, sizeRange = 5)

checkAll("NonEmptyList[Int]", OrderLaws[NonEmptyList[Int]].order)

Expand Down
Loading