Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
scala: [2.13.17, 3.3.5, 3.6.4]
scala: [2.13.17, 3.3.7, 3.6.4]
java: [temurin@8, temurin@11, temurin@17, temurin@21]
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -78,5 +78,5 @@ jobs:
run: sbt '++ ${{ matrix.scala }}' mimaReportBinaryIssues

- name: Build docs
if: matrix.java == 'temurin@8' && matrix.scala == '3.3.5'
if: matrix.java == 'temurin@8' && matrix.scala == '3.3.7'
run: sbt '++ ${{ matrix.scala }}' docs/mdoc
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import formless._
Global / onChangedBuildSource := ReloadOnSourceChanges

lazy val scala213 = "2.13.17"
lazy val scala3 = "3.3.5"
lazy val scala3 = "3.3.7"
lazy val scala3_6 = "3.6.4"

ThisBuild / crossScalaVersions := Seq(scala213, scala3, scala3_6)
Expand Down Expand Up @@ -60,6 +60,7 @@ lazy val baseSettings = Seq(
"-language:experimental.macros",
"-language:implicitConversions"
),
Test / scalacOptions -= "-Wunused:nowarn",
licenses += License.Apache2,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ trait CombinationsLP {

object Combinations extends CombinationsLP {
inline def apply[N, L](using c: Combinations[N, L]): Combinations.Aux[N, L, c.Out] = c
inline def apply[N, L](n: N, l: L)(using c: Combinations[N, L]): c.Out = c(l)
inline def apply[N, L](@annotation.nowarn("msg=unused") n: N, @annotation.nowarn("msg=unused") l: L)(
using c: Combinations[N, L],
): c.Out = c(l)

given combination0[L]: Combinations.Aux[0, L, HNil :: HNil] =
new Combinations[0, L] {
Expand Down
8 changes: 4 additions & 4 deletions core/shared/src/main/scala-3/formless/hlist/HListOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ final class HListOps[L <: HList](private val l: L) extends AnyVal {

// TODO - this doesn't work well because e.g. `0 :: HNil` is typed as `Int :: HNil`
// instead of a preserving the singleton type of `0 :: HNil`
final def selectMany[Ids <: HList](ids: Ids)(using s: SelectMany[L, Ids]): s.Out = s(l)
final def selectMany[Ids <: HList](@annotation.nowarn("msg=unused") ids: Ids)(using s: SelectMany[L, Ids]): s.Out = s(l)

/**
* Returns the elements of this `HList` specified by the range of ids in [A,B[
Expand Down Expand Up @@ -312,7 +312,7 @@ final class HListOps[L <: HList](private val l: L) extends AnyVal {
* Permutes this `HList` into the same order as the supplied `HList` with the same element types. Available only if
* both `HList`s have elements of the same types.
*/
final def align[M <: HList](m: M)(using a: Align[L, M]): M = a(l)
final def align[M <: HList](@annotation.nowarn("msg=unused") m: M)(using a: Align[L, M]): M = a(l)

/**
* Reverses this `HList`.
Expand Down Expand Up @@ -417,7 +417,7 @@ final class HListOps[L <: HList](private val l: L) extends AnyVal {
* Doesn't require this to be the same length as its `HList` argument, but does require evidence that its
* `Poly2` argument is defined at their intersection.
*/
final def zipWith[R <: HList, P <: Poly2](r: R)(p: P)(using z: ZipWith[L, R, P]): z.Out = z(l, r)
final def zipWith[R <: HList, P <: Poly2](r: R)(@annotation.nowarn("msg=unused") p: P)(using z: ZipWith[L, R, P]): z.Out = z(l, r)

/**
* Zips this `HList` with its element indices, resulting in a `HList` of `HList`s of the form
Expand Down Expand Up @@ -528,7 +528,7 @@ final class HListOps[L <: HList](private val l: L) extends AnyVal {
/**
* Converts this `HList` of values into a record with the provided keys.
*/
final def zipWithKeys[K <: HList](keys: K)(using z: ZipWithKeys[K, L]): z.Out = z(l)
final def zipWithKeys[K <: HList](@annotation.nowarn("msg=unused") keys: K)(using z: ZipWithKeys[K, L]): z.Out = z(l)

/**
* Converts this `HList` of values into a record with given keys. A type argument must be provided.
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala-3/formless/hlist/LiftAll.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object LiftAll {
type Aux[F[_], T, O] = LiftAll[F, T] { type Out = O }

final class Curried[F[_]](private val dummy: Boolean = false) extends AnyVal {
final def apply[In](in: In)(using l: LiftAll[F, In]): LiftAll.Aux[F, In, l.Out] = l
final def apply[In](@annotation.nowarn("msg=unused") in: In)(using l: LiftAll[F, In]): LiftAll.Aux[F, In, l.Out] = l
}

def apply[F[_]]: Curried[F] = new Curried[F]
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala-3/formless/hlist/MapCons.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ object MapCons {
inline def apply[A, M](using m: MapCons[A, M]): MapCons.Aux[A, M, m.Out] = m

given mapConsHList[A, M <: HList](
using ev: LiftAll[[a] =>> a <:< HList, M],
using @annotation.nowarn("msg=unused") ev: LiftAll[[a] =>> a <:< HList, M],
): MapCons.Aux[A, M, MapConsT[A, M]] =
new MapCons[A, M] {
type Out = MapConsT[A, M]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ import formless.hlist.Poly1
*/
trait FieldPoly extends Poly1 {
final def atField[V]: [K <: Singleton] => K => [O] => (V => O) => Case.Aux[K ->> V, K ->> O] =
[K <: Singleton] => (k: K) => [O] => (f: V => O) => at[K ->> V](kv => label[K](f(kv)))
[K <: Singleton] => (_: K) => [O] => (f: V => O) => at[K ->> V](kv => label[K](f(kv)))
}
19 changes: 11 additions & 8 deletions core/shared/src/main/scala-3/formless/record/RecordOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@ final class FormlessRecordOps[T <: HList](private val t: T) extends AnyVal {
* Returns the value associated with the singleton typed key k. Only available if this record has a field with
* with keyType equal to the singleton type K.
*/
final def get[K <: Singleton](k: K)(using s: Selector[T, K]): s.Out = s(t)
final def get[K <: Singleton](@annotation.nowarn("msg=unused") k: K)(using s: Selector[T, K]): s.Out = s(t)

/**
* Returns the value associated with the singleton typed key k. Only available if this record has a field with
* with keyType equal to the singleton type K.
*/
final def apply[K <: Singleton](k: K)(using s: Selector[T, K]): s.Out = s(t)
final def apply[K <: Singleton](@annotation.nowarn("msg=unused") k: K)(using s: Selector[T, K]): s.Out = s(t)

/**
* Returns the value associated with the singleton typed key k. Only available if this record has a field with
* with keyType equal to the singleton type K.
*/
final def fieldAt[K <: Singleton](k: K)(using s: Selector[T, K]): K ->> s.Out = label[K](s(t))
final def fieldAt[K <: Singleton](@annotation.nowarn("msg=unused") k: K)(using s: Selector[T, K]): K ->> s.Out = label[K](s(t))

/**
* Updates or adds to this record a field with key k. The new field has a value of type V. Only available if this
* record has a field with keyType equal to the singleton type K.
*/
final def updated[K <: Singleton, V](k: K, v: V)(using u: Updater[T, K ->> V]): u.Out = u(t, label[K](v))
final def updated[K <: Singleton, V](@annotation.nowarn("msg=unused") k: K, v: V)(using u: Updater[T, K ->> V]): u.Out = u(t, label[K](v))

/**
* Replaces the value of field k with a value of the same type. Only available if this record has a field with
* keyType equal to the singleton type K and valueType equal to V.
*/
final def replace[K <: Singleton, V](k: K, v: V)(
final def replace[K <: Singleton, V](@annotation.nowarn("msg=unused") k: K, v: V)(
using s: Selector.Aux[T, K, V],
u: Updater[T, K ->> V],
): u.Out = u(t, label[K](v))
Expand All @@ -46,7 +46,7 @@ final class FormlessRecordOps[T <: HList](private val t: T) extends AnyVal {
* Remove the field associated with the singleton typed key k, returning both the corresponding value and the updated
* record. Only available if this record has a field with keyType equal to the singleton type K.
*/
final def remove[K <: Singleton](k: K)(using r: Remover[T, K]): r.Out = r(t)
final def remove[K <: Singleton](@annotation.nowarn("msg=unused") k: K)(using r: Remover[T, K]): r.Out = r(t)

/**
* Updates or adds to this record a field of type F.
Expand All @@ -57,7 +57,7 @@ final class FormlessRecordOps[T <: HList](private val t: T) extends AnyVal {
* Remove the field associated with the singleton typed key k, returning the updated record. Only available if this
* record has a field with keyType equal to the singleton type K.
*/
final def -[K <: Singleton, R, V, O](k: K)(using r: Remover.Aux[T, K, R], ev: R <:< (V, O)): O = r(t)._2
final def -[K <: Singleton, R, V, O](@annotation.nowarn("msg=unused") k: K)(using r: Remover.Aux[T, K, R], ev: R <:< (V, O)): O = r(t)._2

/**
* Returns the union of this record and another record.
Expand All @@ -80,7 +80,10 @@ final class FormlessRecordOps[T <: HList](private val t: T) extends AnyVal {
* Rename the field associated with the singleton typed key oldKey. Only available if this
* record has a field with keyType equal to the singleton type K1.
*/
final def renameField[K1 <: Singleton, K2 <: Singleton](oldKey: K1, newKey: K2)(using r: Renamer[T, K1, K2]): r.Out = r(t)
final def renameField[K1 <: Singleton, K2 <: Singleton](
@annotation.nowarn("msg=unused") oldKey: K1,
@annotation.nowarn("msg=unused") newKey: K2,
)(using r: Renamer[T, K1, K2]): r.Out = r(t)

/**
* Returns the keys of this record as a `HList` of singleton typed values.
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala-3/formless/record/Remover.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object Remover {
type Aux[T, K, O] = Remover[T, K] { type Out = O }

inline def apply[T, K](using r: Remover[T, K]): Remover.Aux[T, K, r.Out] = r
inline def apply[T, K](t: T, k: K)(using r: Remover[T, K]): r.Out = r(t)
inline def apply[T, K](t: T, @annotation.nowarn("msg=unused") k: K)(using r: Remover[T, K]): r.Out = r(t)

given removerInst[T <: HList, K](
using f: FindField[T, K ->> Any, <:<]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ trait HListTestsCompat { self: HListTests =>
assert(!ununified2.isDefined)
typed[Option[APBP]](ununified2)

def getUnifier[L <: HList, Out <: HList](l: L)(using u: Unifier.Aux[L, Out]) = u
def getUnifier[L <: HList, Out <: HList](@annotation.nowarn("msg=unused") l: L)(using u: Unifier.Aux[L, Out]) = u

val u2 = getUnifier(a :: HNil)
typed[Unifier.Aux[Apple :: HNil, Apple :: HNil]](u2)
Expand Down
1 change: 0 additions & 1 deletion core/shared/src/test/scala-3/formless/test/illTyped.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ import scala.compiletime.testing.typeChecks
*/
object illTyped {
inline def apply(code: String)(using loc: Location): Unit = assert(!typeChecks(code))
inline def apply(code: String, expected: String)(using loc: Location): Unit = apply(code)
}
4 changes: 3 additions & 1 deletion core/shared/src/test/scala/formless/hlist/HListTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,9 @@ class HListTests extends FunSuite with HListTestsCompat {
{
// must compile without requiring an implicit ReversePrepend
def reversePrependWithHNil[L <: HList](list: L) = HNil reverse_::: list
def reversePrependToHNil[L <: HList: Reverse](list: L) = list reverse_::: HNil
def reversePrependToHNil[L <: HList](list: L)(
implicit @annotation.nowarn("msg=unused") r: Reverse[L],
) = list reverse_::: HNil
val r4 = reversePrependWithHNil(ap)
assertTypedEquals[AP](ap, r4)
val r5 = reversePrependToHNil(ap)
Expand Down
Loading