From 51e83e7ea4064bbce2fd928fff2973c39d1f6876 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 16 Mar 2015 23:31:14 +0000 Subject: [PATCH 1/8] Fix temp variable names for +=/++= macros. --- .../src/main/scala/sbt/std/TaskMacro.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/main/settings/src/main/scala/sbt/std/TaskMacro.scala b/main/settings/src/main/scala/sbt/std/TaskMacro.scala index 51f6ed028..b487f28d5 100644 --- a/main/settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main/settings/src/main/scala/sbt/std/TaskMacro.scala @@ -136,29 +136,29 @@ object TaskMacro { def taskAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[Task[T]]] = { val init = taskMacroImpl[U](c)(v) - val assign = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName) - c.Expr[Setting[Task[T]]](assign) + val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName) + c.Expr[Setting[Task[T]]](append) } /** Implementation of += macro for settings. */ def settingAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[T]] = { val init = SettingMacro.settingMacroImpl[U](c)(v) - val assign = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName) - c.Expr[Setting[T]](assign) + val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName) + c.Expr[Setting[T]](append) } /** Implementation of ++= macro for tasks. */ def taskAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[Task[T]]] = { val init = taskMacroImpl[U](c)(vs) - val assign = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName) - c.Expr[Setting[Task[T]]](assign) + val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName) + c.Expr[Setting[Task[T]]](append) } /** Implementation of ++= macro for settings. */ def settingAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[T]] = { val init = SettingMacro.settingMacroImpl[U](c)(vs) - val assign = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName) - c.Expr[Setting[T]](assign) + val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName) + c.Expr[Setting[T]](append) } private[this] def appendMacroImpl(c: Context)(init: c.Tree, append: c.Tree)(newName: String): c.Tree = From 17a1179e5b0c079548e84b493825a8eec77e40b2 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 16 Mar 2015 23:42:14 +0000 Subject: [PATCH 2/8] Add -= & --= for setings & keys, dual of += & ++=. --- main/settings/src/main/scala/sbt/Remove.scala | 20 ++++++++++ .../src/main/scala/sbt/Structure.scala | 15 ++++++- .../src/main/scala/sbt/std/TaskMacro.scala | 40 +++++++++++++++++++ notes/0.13.8.markdown | 2 + sbt/src/sbt-test/project/remove/build.sbt | 24 +++++++++++ sbt/src/sbt-test/project/remove/test | 1 + 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 main/settings/src/main/scala/sbt/Remove.scala create mode 100644 sbt/src/sbt-test/project/remove/build.sbt create mode 100644 sbt/src/sbt-test/project/remove/test diff --git a/main/settings/src/main/scala/sbt/Remove.scala b/main/settings/src/main/scala/sbt/Remove.scala new file mode 100644 index 000000000..6a555d34a --- /dev/null +++ b/main/settings/src/main/scala/sbt/Remove.scala @@ -0,0 +1,20 @@ +package sbt + +import scala.annotation.implicitNotFound + +object Remove { + @implicitNotFound(msg = "No implicit for Remove.Value[${A}, ${B}] found,\n so ${B} cannot be remove from ${A}") + trait Value[A, B] extends Any { + def removeValue(a: A, b: B): A + } + @implicitNotFound(msg = "No implicit for Remove.Values[${A}, ${B}] found,\n so ${B} cannot be remove from ${A}") + trait Values[A, -B] extends Any { + def removeValues(a: A, b: B): A + } + sealed trait Sequence[A, -B, T] extends Value[A, T] with Values[A, B] + + implicit def removeSeq[T, V <: T] = new Sequence[Seq[T], Seq[V], V] { + def removeValue(a: Seq[T], b: V): Seq[T] = a filterNot b.== + def removeValues(a: Seq[T], b: Seq[V]): Seq[T] = a diff b + } +} diff --git a/main/settings/src/main/scala/sbt/Structure.scala b/main/settings/src/main/scala/sbt/Structure.scala index 153f48e7c..4b378f229 100644 --- a/main/settings/src/main/scala/sbt/Structure.scala +++ b/main/settings/src/main/scala/sbt/Structure.scala @@ -42,13 +42,19 @@ sealed abstract class SettingKey[T] extends ScopedTaskable[T] with KeyedInitiali final def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[T] = macro std.TaskMacro.settingAppendNImpl[T, U] final def <+=[V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] = macro std.TaskMacro.settingAppend1Position[T, V] final def <++=[V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] = macro std.TaskMacro.settingAppendNPosition[T, V] + final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[T] = macro std.TaskMacro.settingRemove1Impl[T, U] + final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[T] = macro std.TaskMacro.settingRemoveNImpl[T, U] final def ~=(f: T => T): Setting[T] = macro std.TaskMacro.settingTransformPosition[T] - final def transform(f: T => T, source: SourcePosition): Setting[T] = set(scopedKey(f), source) final def append1[V](v: Initialize[V], source: SourcePosition)(implicit a: Append.Value[T, V]): Setting[T] = make(v, source)(a.appendValue) final def appendN[V](vs: Initialize[V], source: SourcePosition)(implicit a: Append.Values[T, V]): Setting[T] = make(vs, source)(a.appendValues) - protected[this] def make[S](other: Initialize[S], source: SourcePosition)(f: (T, S) => T): Setting[T] = this.set((this, other)(f), source) + final def remove1[V](v: Initialize[V], source: SourcePosition)(implicit r: Remove.Value[T, V]): Setting[T] = make(v, source)(r.removeValue) + final def removeN[V](vs: Initialize[V], source: SourcePosition)(implicit r: Remove.Values[T, V]): Setting[T] = make(vs, source)(r.removeValues) + + final def transform(f: T => T, source: SourcePosition): Setting[T] = set(scopedKey(f), source) + + protected[this] def make[S](other: Initialize[S], source: SourcePosition)(f: (T, S) => T): Setting[T] = set((this, other)(f), source) } /** @@ -67,10 +73,15 @@ sealed abstract class TaskKey[T] extends ScopedTaskable[T] with KeyedInitialize[ def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskAppendNImpl[T, U] def <+=[V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] = macro std.TaskMacro.taskAppend1Position[T, V] def <++=[V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] = macro std.TaskMacro.taskAppendNPosition[T, V] + final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskRemove1Impl[T, U] + final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskRemoveNImpl[T, U] def append1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit a: Append.Value[T, V]): Setting[Task[T]] = make(v, source)(a.appendValue) def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit a: Append.Values[T, V]): Setting[Task[T]] = make(vs, source)(a.appendValues) + def remove1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit r: Remove.Value[T, V]): Setting[Task[T]] = make(v, source)(r.removeValue) + def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit r: Remove.Values[T, V]): Setting[Task[T]] = make(vs, source)(r.removeValues) + private[this] def make[S](other: Initialize[Task[S]], source: SourcePosition)(f: (T, S) => T): Setting[Task[T]] = set((this, other) { (a, b) => (a, b) map f.tupled }, source) } diff --git a/main/settings/src/main/scala/sbt/std/TaskMacro.scala b/main/settings/src/main/scala/sbt/std/TaskMacro.scala index b487f28d5..770eea263 100644 --- a/main/settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main/settings/src/main/scala/sbt/std/TaskMacro.scala @@ -67,6 +67,8 @@ object TaskMacro { final val AssignInitName = "set" final val Append1InitName = "append1" final val AppendNInitName = "appendN" + final val Remove1InitName = "remove1" + final val RemoveNInitName = "removeN" final val TransformInitName = "transform" final val InputTaskCreateDynName = "createDyn" final val InputTaskCreateFreeName = "createFree" @@ -161,6 +163,35 @@ object TaskMacro { c.Expr[Setting[T]](append) } + /** Implementation of -= macro for tasks. */ + def taskRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[Task[T]]] = + { + val init = taskMacroImpl[U](c)(v) + val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName) + c.Expr[Setting[Task[T]]](remove) + } + /** Implementation of -= macro for settings. */ + def settingRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[T]] = + { + val init = SettingMacro.settingMacroImpl[U](c)(v) + val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName) + c.Expr[Setting[T]](remove) + } + /** Implementation of --= macro for tasks. */ + def taskRemoveNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(r: c.Expr[Remove.Values[T, U]]): c.Expr[Setting[Task[T]]] = + { + val init = taskMacroImpl[U](c)(vs) + val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName) + c.Expr[Setting[Task[T]]](remove) + } + /** Implementation of --= macro for settings. */ + def settingRemoveNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(r: c.Expr[Remove.Values[T, U]]): c.Expr[Setting[T]] = + { + val init = SettingMacro.settingMacroImpl[U](c)(vs) + val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName) + c.Expr[Setting[T]](remove) + } + private[this] def appendMacroImpl(c: Context)(init: c.Tree, append: c.Tree)(newName: String): c.Tree = { import c.universe.{ Apply, ApplyTag, newTermName, Select, SelectTag, TypeApply, TypeApplyTag } @@ -170,6 +201,15 @@ object TaskMacro { case x => ContextUtil.unexpectedTree(x) } } + private[this] def removeMacroImpl(c: Context)(init: c.Tree, remove: c.Tree)(newName: String): c.Tree = + { + import c.universe.{ Apply, ApplyTag, newTermName, Select, SelectTag, TypeApply, TypeApplyTag } + c.macroApplication match { + case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), r) => + Apply(Apply(TypeApply(Select(preT, newTermName(newName).encodedName), targs), init :: sourcePosition(c).tree :: Nil), r) + case x => ContextUtil.unexpectedTree(x) + } + } private[this] def transformMacroImpl(c: Context)(init: c.Tree)(newName: String): c.Tree = { import c.universe.{ Apply, ApplyTag, newTermName, Select, SelectTag } diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index 5386f3a79..e659d5776 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -52,6 +52,7 @@ [1881]: https://github.com/sbt/sbt/issues/1881 [1899]: https://github.com/sbt/sbt/pull/1899 [1902]: https://github.com/sbt/sbt/pull/1902 + [1922]: https://github.com/sbt/sbt/pull/1922 ### Changes with compatibility implications @@ -70,6 +71,7 @@ - Better abstration to track new kinds of dependencies for incremental compiler. [#1340][1340] by [@Duhemm][@Duhemm] - Source dependency uses `--depth 1` for git clone. [#1787][1787] by [@xuwei-k][@xuwei-k] - Facilitate nicer ways of declaring project settings. See below. [#1902][1902] by [@dwijnand][@dwijnand] +- Add `-=` and `--=` for setings and keys, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] ### Fixes diff --git a/sbt/src/sbt-test/project/remove/build.sbt b/sbt/src/sbt-test/project/remove/build.sbt new file mode 100644 index 000000000..0b967394c --- /dev/null +++ b/sbt/src/sbt-test/project/remove/build.sbt @@ -0,0 +1,24 @@ +val intsTask = taskKey[Seq[Int]]("A seq of ints task") +val intsSetting = settingKey[Seq[Int]]("A seq of ints setting") +val intsFromScalaV = settingKey[Seq[Int]]("a seq of ints from scalaVersion") + +scalaVersion := "2.11.6" + +intsTask := Seq(1, 2, 3, 4, 5) +intsTask -= 3 +intsTask --= Seq(1, 2) + +intsSetting := Seq(1, 2, 3, 4, 5) +intsSetting -= 3 +intsSetting --= Seq(1, 2) + +intsFromScalaV := Seq(1, 2, 3, 4, 5) +intsFromScalaV -= { if (scalaVersion.value == "2.11.6") 3 else 5 } +intsFromScalaV --= { if (scalaVersion.value == "2.11.6") Seq(1, 2) else Seq(4) } + +val check = taskKey[Unit]("Runs the check") +check := { + assert(intsTask.value == Seq(4, 5), s"intsTask should be Seq(4, 5) but is ${intsTask.value}") + assert(intsSetting.value == Seq(4, 5), s"intsSetting should be Seq(4, 5) but is ${intsSetting.value}") + assert(intsFromScalaV.value == Seq(4, 5), s"intsFromScalaV should be Seq(4, 5) but is ${intsFromScalaV.value}") +} diff --git a/sbt/src/sbt-test/project/remove/test b/sbt/src/sbt-test/project/remove/test new file mode 100644 index 000000000..15675b169 --- /dev/null +++ b/sbt/src/sbt-test/project/remove/test @@ -0,0 +1 @@ +> check From a4b6d07efa86e043533746f635c696c763b4ee57 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 16 Mar 2015 23:50:46 +0000 Subject: [PATCH 3/8] Fix a typo in notes. --- notes/0.13.8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index e659d5776..193b9a04d 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -71,7 +71,7 @@ - Better abstration to track new kinds of dependencies for incremental compiler. [#1340][1340] by [@Duhemm][@Duhemm] - Source dependency uses `--depth 1` for git clone. [#1787][1787] by [@xuwei-k][@xuwei-k] - Facilitate nicer ways of declaring project settings. See below. [#1902][1902] by [@dwijnand][@dwijnand] -- Add `-=` and `--=` for setings and keys, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] +- Add `-=` and `--=` for settings and keys, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] ### Fixes From 72ee03ef1363ac4e534602675d6ff611903bc1cb Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 16 Mar 2015 23:53:18 +0000 Subject: [PATCH 4/8] Fix another(..) typo in notes. --- notes/0.13.8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index 193b9a04d..b3bc5e650 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -71,7 +71,7 @@ - Better abstration to track new kinds of dependencies for incremental compiler. [#1340][1340] by [@Duhemm][@Duhemm] - Source dependency uses `--depth 1` for git clone. [#1787][1787] by [@xuwei-k][@xuwei-k] - Facilitate nicer ways of declaring project settings. See below. [#1902][1902] by [@dwijnand][@dwijnand] -- Add `-=` and `--=` for settings and keys, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] +- Add `-=` and `--=` for settings and tasks, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] ### Fixes From ae193d568f8d42594268b4c36311e818d01e69ed Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 17 Mar 2015 09:44:29 +0000 Subject: [PATCH 5/8] Move adding -=/--= notes to 0.13.9. --- notes/0.13.8.markdown | 2 -- notes/0.13.9.markdown | 11 +++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 notes/0.13.9.markdown diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index b3bc5e650..5386f3a79 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -52,7 +52,6 @@ [1881]: https://github.com/sbt/sbt/issues/1881 [1899]: https://github.com/sbt/sbt/pull/1899 [1902]: https://github.com/sbt/sbt/pull/1902 - [1922]: https://github.com/sbt/sbt/pull/1922 ### Changes with compatibility implications @@ -71,7 +70,6 @@ - Better abstration to track new kinds of dependencies for incremental compiler. [#1340][1340] by [@Duhemm][@Duhemm] - Source dependency uses `--depth 1` for git clone. [#1787][1787] by [@xuwei-k][@xuwei-k] - Facilitate nicer ways of declaring project settings. See below. [#1902][1902] by [@dwijnand][@dwijnand] -- Add `-=` and `--=` for settings and tasks, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] ### Fixes diff --git a/notes/0.13.9.markdown b/notes/0.13.9.markdown new file mode 100644 index 000000000..9e2e4810a --- /dev/null +++ b/notes/0.13.9.markdown @@ -0,0 +1,11 @@ + + [@dwijnand]: http://github.com/dwijnand + [1922]: https://github.com/sbt/sbt/pull/1922 + +### Fixes with compatibility implications + +### Improvements + +- Add `-=` and `--=` for settings and tasks, dual of `+=` and `++=`. [#1922][1922] by [@dwijnand][@dwijnand] + +### Bug fixes From 1db6f7f3164c7a86d7ab9fa647d38c8cda600feb Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 20 Mar 2015 16:12:20 +0000 Subject: [PATCH 6/8] s/remove/removed/ --- main/settings/src/main/scala/sbt/Remove.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/settings/src/main/scala/sbt/Remove.scala b/main/settings/src/main/scala/sbt/Remove.scala index 6a555d34a..83184a056 100644 --- a/main/settings/src/main/scala/sbt/Remove.scala +++ b/main/settings/src/main/scala/sbt/Remove.scala @@ -3,11 +3,11 @@ package sbt import scala.annotation.implicitNotFound object Remove { - @implicitNotFound(msg = "No implicit for Remove.Value[${A}, ${B}] found,\n so ${B} cannot be remove from ${A}") + @implicitNotFound(msg = "No implicit for Remove.Value[${A}, ${B}] found,\n so ${B} cannot be removed from ${A}") trait Value[A, B] extends Any { def removeValue(a: A, b: B): A } - @implicitNotFound(msg = "No implicit for Remove.Values[${A}, ${B}] found,\n so ${B} cannot be remove from ${A}") + @implicitNotFound(msg = "No implicit for Remove.Values[${A}, ${B}] found,\n so ${B} cannot be removed from ${A}") trait Values[A, -B] extends Any { def removeValues(a: A, b: B): A } From 18c7a5c2268bd51a5d23a3d518b3cf15aeedb103 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 20 Mar 2015 16:34:13 +0000 Subject: [PATCH 7/8] MAke Task's remove1/removeN final. --- main/settings/src/main/scala/sbt/Structure.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/settings/src/main/scala/sbt/Structure.scala b/main/settings/src/main/scala/sbt/Structure.scala index 4b378f229..56e08e2d2 100644 --- a/main/settings/src/main/scala/sbt/Structure.scala +++ b/main/settings/src/main/scala/sbt/Structure.scala @@ -79,8 +79,8 @@ sealed abstract class TaskKey[T] extends ScopedTaskable[T] with KeyedInitialize[ def append1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit a: Append.Value[T, V]): Setting[Task[T]] = make(v, source)(a.appendValue) def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit a: Append.Values[T, V]): Setting[Task[T]] = make(vs, source)(a.appendValues) - def remove1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit r: Remove.Value[T, V]): Setting[Task[T]] = make(v, source)(r.removeValue) - def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit r: Remove.Values[T, V]): Setting[Task[T]] = make(vs, source)(r.removeValues) + final def remove1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit r: Remove.Value[T, V]): Setting[Task[T]] = make(v, source)(r.removeValue) + final def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit r: Remove.Values[T, V]): Setting[Task[T]] = make(vs, source)(r.removeValues) private[this] def make[S](other: Initialize[Task[S]], source: SourcePosition)(f: (T, S) => T): Setting[Task[T]] = set((this, other) { (a, b) => (a, b) map f.tupled }, source) From a4d2e04532c8e80b4b57466cafcca90d34ebf709 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 23 Mar 2015 22:29:57 +0000 Subject: [PATCH 8/8] Add explicit return type for implicit removeSeq. --- main/settings/src/main/scala/sbt/Remove.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/settings/src/main/scala/sbt/Remove.scala b/main/settings/src/main/scala/sbt/Remove.scala index 83184a056..a08093126 100644 --- a/main/settings/src/main/scala/sbt/Remove.scala +++ b/main/settings/src/main/scala/sbt/Remove.scala @@ -13,7 +13,7 @@ object Remove { } sealed trait Sequence[A, -B, T] extends Value[A, T] with Values[A, B] - implicit def removeSeq[T, V <: T] = new Sequence[Seq[T], Seq[V], V] { + implicit def removeSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] = new Sequence[Seq[T], Seq[V], V] { def removeValue(a: Seq[T], b: V): Seq[T] = a filterNot b.== def removeValues(a: Seq[T], b: Seq[V]): Seq[T] = a diff b }