Skip to content

Commit

Permalink
Merge branch 'master' into hkt-id-selector
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 authored Mar 22, 2020
2 parents 2ea1885 + 462399b commit 8daef44
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 18 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jdk:

cache:
directories:
- $HOME/.cache/coursier
- $HOME/.ivy2/cache
- $HOME/.sbt

Expand Down
Empty file added :
Empty file.
2 changes: 1 addition & 1 deletion core/src/main/scala/shapeless/hlists.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final case class ::[+H, +T <: HList](head : H, tail : T) extends HList {
* @author Miles Sabin
*/
sealed trait HNil extends HList {
def ::[H](h : H) = shapeless.::(h, this)
def ::[H](h: H): H :: HNil = new ::(h, this)
override def toString = "HNil"
}

Expand Down
13 changes: 9 additions & 4 deletions core/src/main/scala/shapeless/hmap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ package shapeless
import poly._

/**
* Heterogenous map with type-level key/value associations that are fixed by an arbitrary
* relation `R`.
* Heterogeneous map with type-level key/value associations that are fixed by an arbitrary relation `R`.
*
* `HMap`s extend `Poly` and hence are also polymorphic function values with type-specific
* cases corresponding to the map's type-level key/value associations.
* `HMap`s extend `Poly` and hence are also polymorphic function values with type-specific cases
* corresponding to the map's type-level key/value associations.
*
* Note: keys and values are stored in erased form in an `HMap`.
* Therefore one should be careful when using parameterized types as keys, because it might lead to unsoundness.
* For a parameterized key type `K[T]` it is important that `T` is part of the `hashCode` / `equals` contract:
* - Good: `case class Key[T](id: T)` - `Key[Int](1)` and `Key[String]("1")` have different hash codes.
* - Bad: `case class Key[T](id: Int)` - `Key[Int](1)` and `Key[String](1)` have different types but the same hash code.
*/
class HMap[R[_, _]](underlying : Map[Any, Any] = Map.empty) extends Poly1 {
def get[K, V](k : K)(implicit ev : R[K, V]) : Option[V] = underlying.get(k).asInstanceOf[Option[V]]
Expand Down
9 changes: 2 additions & 7 deletions core/src/main/scala/shapeless/syntax/std/tuples.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,11 @@ package std

import shapeless.ops.hlist.ProductToHList

trait LowPriorityTuple {
implicit def productTupleOps[P <: Product](p: P): TupleOps[P] = new TupleOps(p)
}

object tuple extends LowPriorityTuple {
implicit def unitTupleOps(u: Unit): TupleOps[Unit] = new TupleOps(u)

object tuple {
// Duplicated here from shapeless.HList so that explicit imports of tuple._ don't
// clobber the conversion to HListOps.
implicit def hlistOps[L <: HList](l : L) : HListOps[L] = new HListOps(l)
implicit def productTupleOps[P: IsTuple](p: P): TupleOps[P] = new TupleOps(p)
}

final class TupleOps[T](t: T) extends Serializable {
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/scala/shapeless/test/typechecking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import scala.language.experimental.macros

import java.util.regex.Pattern

import scala.reflect.macros.{ whitebox, ParseException, TypecheckException }
import scala.reflect.macros.{ blackbox, ParseException, TypecheckException }

/**
* A utility which ensures that a code fragment does not typecheck.
Expand All @@ -34,7 +34,7 @@ object illTyped {
}

@macrocompat.bundle
class IllTypedMacros(val c: whitebox.Context) {
class IllTypedMacros(val c: blackbox.Context) {
import c.universe._

def applyImplNoExp(code: Tree): Tree = applyImpl(code, null)
Expand All @@ -55,7 +55,7 @@ class IllTypedMacros(val c: whitebox.Context) {
} catch {
case e: TypecheckException =>
val msg = e.getMessage
if((expected ne null) && !(expPat.matcher(msg)).matches)
if((expected ne null) && !expPat.matcher(msg).matches)
c.error(c.enclosingPosition, "Type-checking failed in an unexpected way.\n"+expMsg+"\nActual error: "+msg)
case e: ParseException =>
c.error(c.enclosingPosition, s"Parsing failed.\n${e.getMessage}")
Expand Down
7 changes: 7 additions & 0 deletions core/src/test/scala/shapeless/hlist.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3497,4 +3497,11 @@ class HListTests {
assertEquals((), (HNil: HNil).toProduct)
assertEquals(HNil, ().toHList)
}

@Test
def testAuxImplicits: Unit = {
the[SplitRight.Aux[String :: Int :: Boolean :: HNil, Int, String :: Int :: HNil, Boolean :: HNil]]
the[Grouper.Aux[Int :: String :: Boolean :: HNil, _2, _1, (Int, String) :: (String, Boolean) :: HNil]]
the[PaddedGrouper.Aux[Int :: String :: Boolean :: HNil, _2, _2, Long :: HNil, (Int, String) :: (Boolean, Long) :: HNil]]
}
}
16 changes: 16 additions & 0 deletions core/src/test/scala/shapeless/singletons.scala
Original file line number Diff line number Diff line change
Expand Up @@ -696,3 +696,19 @@ package UnrefineTest {
new Bar(Foo.from( LabelledGeneric[FooBar] )).modify(Symbol("y").narrow, (_: Int) * 2).keys
}
}

object VarArgsWitnessTest {
trait Base
class Dep[B <: Base with Singleton]
object instance extends Base
val dep = new Dep[instance.type]

def varargs[B <: Base with Singleton](el: Dep[B]*)(implicit w: Witness.Aux[B]): Unit = ()
def poly[B <: Base with Singleton](el1: Dep[B])(implicit w: Witness.Aux[B]): Unit = ()
def poly[B <: Base with Singleton](el1: Dep[B], el2: Dep[B])(implicit w: Witness.Aux[B]): Unit = ()

varargs(dep)
varargs(dep, dep)
poly(dep)
poly(dep, dep)
}
13 changes: 10 additions & 3 deletions core/src/test/scala/shapeless/tuples.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package shapeless

import org.junit.Test
import org.junit.Assert._

import shapeless.ops.tuple.IsComposite
import shapeless.test._
import testutil._

Expand Down Expand Up @@ -49,6 +49,7 @@ class TupleTests {
case class Pear() extends Fruit
case class Banana() extends Fruit

case class Foo(i: Int, s: String)
type PWS = Product with Serializable with Fruit

type YYYY = (Any, Any, Any, Any)
Expand Down Expand Up @@ -1462,8 +1463,7 @@ class TupleTests {

@Test
def testPropagation: Unit = {
def useHead[P <: Product](p: P)(implicit ic: ops.tuple.IsComposite[P]) = p.head

def useHead[P: IsTuple: IsComposite](p: P) = p.head
val h = useHead((23, "foo", true))
typed[Int](h)
}
Expand Down Expand Up @@ -1973,4 +1973,11 @@ class TupleTests {
(23, "foo").align[(String, String)]
""")
}

@Test
def testCompatibilityWithProductSyntax: Unit = {
import syntax.std.product._
assertEquals(List(2, "a"), Foo(2, "a").to[List])
assertEquals(List(2, "a"), (2, "a").to[List])
}
}

0 comments on commit 8daef44

Please # to comment.