title: Slick Zip Join with HList Shape comes out as Tuple in runtime
body: <p>So I'm trying to implement a <code>zipHList</code> method which is like <code>Query.zip</code> but returns HLists instead of tuples. I start with the query shape:</p>
  
  <pre><code>implicit class QueryExt[+E, U, C[_]](query:Query[E, U, C]) {
    def zipHList[E2, U2, D[_]](q2: Query[E2, U2, D]): Query[HCons[E, HCons[E2, HNil]], HCons[U, HCons[U2, HNil]], C] = standardHListJoin(q2, JoinType.Zip)
  
    private[this] def standardHListJoin[E2, U2, D[_]](q2: Query[E2, U2, D], jt: JoinType) = {
      val leftGen, rightGen = new AnonSymbol
      val aliased1 = query.shaped.encodeRef(Ref(leftGen))
      val aliased2 = q2.shaped.encodeRef(Ref(rightGen))
      new BaseHListJoinQuery[E, E2, U, U2, C, E, E2](leftGen, rightGen, query.toNode, q2.toNode, jt,
        aliased1.zipHList(aliased2), aliased1.value, aliased2.value)
    }
  }
  </code></pre>
  
  <p>Then the supporting shapes:</p>
  
  <pre><code>implicit class ShapedValueExt[T, U](s: ShapedValue[T, U]) {
    def zipHList[T2, U2](s2: ShapedValue[T2, U2]) = new ShapedValue[HCons[T, HCons[T2, HNil]], HCons[U, HCons[U2, HNil]]]((s.value :: s2.value :: HNil), hconsShape(s.shape, hconsShape(s2.shape, hnilShape))) //Shape.tuple2Shape(s.shape, s2.shape)
  }
  
  final class BaseHListJoinQuery[+E1, +E2, U1, U2, C[_], +B1, +B2](leftGen: TermSymbol, rightGen: TermSymbol, left: Node, right: Node, jt: JoinType, base: ShapedValue[_ &lt;: HCons[E1, HCons[E2, HNil]], HCons[U1, HCons[U2, HNil]]], b1: B1, b2: B2)
    extends WrappingQuery[HCons[E1, HCons[E2, HNil]], HCons[U1, HCons[U2, HNil]], C](AJoin(leftGen, rightGen, left, right, jt, LiteralNode(true)), base) {
  }
  </code></pre>
  
  <p>Finally, the supporting <code>HList</code> shapes:</p>
  
  <pre><code>object HListShapeSupport {
    final class HListShape[Level &lt;: ShapeLevel, M &lt;: HList, U &lt;: HList : ClassTag, P &lt;: HList](val shapes: Seq[Shape[_, _, _, _]]) extends MappedScalaProductShape[Level, HList, M, U, P] {
      def buildValue(elems: IndexedSeq[Any]) = elems.foldRight(HNil: HList)(_ :: _)
      def copy(shapes: Seq[Shape[_ &lt;: ShapeLevel, _, _, _]]) = new HListShape(shapes)
    }
    implicit def hnilShape[Level &lt;: ShapeLevel] = new HListShape[Level, HNil.type, HNil.type, HNil.type](Nil)
    implicit def hconsShape[Level &lt;: ShapeLevel, M1, M2 &lt;: HList, U1, U2 &lt;: HList, P1, P2 &lt;: HList](implicit s1: Shape[_ &lt;: Level, M1, U1, P1], s2: HListShape[_ &lt;: Level, M2, U2, P2]) =
      new HListShape[Level, M1 :: M2, U1 :: U2, P1 :: P2](s1 +: s2.shapes)
  
    class HListCaseClassShape[P &lt;: Product, LiftedList, LiftedCaseClass &lt;: P, PlainList, PlainCaseClass &lt;: P](
         mapLifted: LiftedList =&gt; LiftedCaseClass, mapPlain: PlainList =&gt; PlainCaseClass)(
         implicit columnShapes: Shape[FlatShapeLevel, LiftedList, PlainList, LiftedList], classTag: ClassTag[PlainCaseClass])
      extends MappedScalaProductShape[FlatShapeLevel, P, LiftedCaseClass, PlainCaseClass, LiftedCaseClass] {
  
      val shapes = columnShapes.asInstanceOf[HListShape[_,_,_,_]].shapes
      override def toMapped(v: Any) = {
        val folded = v.asInstanceOf[Product].productIterator.foldRight(HNil: HList)(_ :: _)
        mapPlain(folded.asInstanceOf[PlainList])
      }
      def buildValue(elems: IndexedSeq[Any]) = {
        val list = elems.foldRight(HNil: HList)(_ :: _)
        mapLifted(list.asInstanceOf[LiftedList])
      }
      def copy(s: Seq[Shape[_ &lt;: ShapeLevel, _, _, _]]) = new HListCaseClassShape(mapLifted, mapPlain) { override val shapes = s }
    }
  }
  </code></pre>
  
  <p>Yet, when I try to run this, the following error occours:</p>
  
  <pre><code>val q = names.zipHList(names)
  val seq = Await.result(db.stream(q.result).foreach(println(_)), Duration.Inf)
  println(seq)
  // Exception in thread "main" java.lang.ClassCastException: scala.Tuple2 cannot be cast to slick.collection.heterogeneous.HCons
  // at com.examples.HListZip$$anonfun$2.apply(HListZip.scala:57)
  </code></pre>
  
  <p>Also, when I just try to get the result it is clear that it's actually a list of tuples.</p>
  
  <pre><code>val names = TableQuery[People].map(_.name)
  val q = names.zipHList(names)
  val seq = Await.result(db.run(q.result), Duration.Inf)
  println(seq)
  // Vector((Joe,Joe), (Jack,Jack), (Jill,Jill), (John,John), (Jim,Jim)]
  </code></pre>
  
  <p>What am I doing wrong? Why does it think the shape is a tuple and not an HList?</p>