tpolecat / tut

doc/tutorial generator for scala
MIT License
579 stars 63 forks source link

Tut compilation inconsistent with Scala compiler, unable to locate implicits #169

Open alexflav23 opened 7 years ago

alexflav23 commented 7 years ago

I've been trying to integrate tut for phantom documentation, however I am experiencing strange behaviour with implicits. Placing implicits in a companion object doesn't seem to please tut, even if the regular compiler has no trouble with this.

The code in question is found below for reference, and works perfectly with the normal compiler, but fails in tut.


import com.outworkers.phantom.dsl._

import io.circe._
import io.circe.generic.semiauto._
import io.circe.parser._
import io.circe.syntax._

case class JsonRecord(
  prop1: String,
  prop2: String
)

object JsonRecord {

  implicit val jsonDecoder: Decoder[JsonRecord] = deriveDecoder[JsonRecord]
  implicit val jsonEncoder: Encoder[JsonRecord] = deriveEncoder[JsonRecord]

  implicit val jsonPrimitive: Primitive[JsonRecord] = {
    Primitive.json[JsonRecord](_.asJson.noSpaces)(decode[JsonRecord](_).right.get)
  }
}

case class JsonClass(
  id: UUID,
  name: String,
  json: JsonRecord,
  optionalJson : Option[JsonRecord],
  jsonList: List[JsonRecord],
  jsonSet: Set[JsonRecord]
)

abstract class JsonTable extends Table[JsonTable, JsonClass] {

  object id extends UUIDColumn with PartitionKey

  object name extends StringColumn

  object json extends JsonColumn[JsonRecord]

  object optionalJson extends OptionalJsonColumn[JsonRecord]

  object jsonList extends JsonListColumn[JsonRecord]

  object jsonSet extends JsonSetColumn[JsonRecord]
}

h4. Tut compilation

The above call to Primitive.json already outputs the implicit tut is unable to find in the below example. Even manually importing the companion object seems to have no effect whatsoever on the outcome.

[tut] *** Error reported at /Users/flavian/projects/oss/phantom/readme/src/main/tut/basics/json_columns.md:69
<console>:45: error: Cannot find primitive implementation for class JsonRecord
         object optionalJson extends OptionalJsonColumn[JsonRecord]
                                     ^
<console>:47: error: Cannot find primitive implementation for class JsonRecord
         object jsonList extends JsonListColumn[JsonRecord]
                                 ^
<console>:49: error: Cannot find primitive implementation for class JsonRecord
         object jsonSet extends JsonSetColumn[JsonRecord]

Is there a known limitation in compiling implicits and how can this be circumvented? It's causing tut to hang infinitely and block the SBT process without even completing with a build failure, so our CI winds up unresponsive for 20 minutes plus at a time.

ceedubs commented 6 years ago

I'm pretty late to seeing this, but I think that the issue here is just that the REPL takes one line at a time (unless you are in :paste mode, which tut doesn't use), so it doesn't actually end up treating object JsonRecord as the companion object for class JsonRecord, and therefore the members of object JsonRecord aren't in the implicit search for JsonRecord types. You should be able to get around this by wrapping your whole chunk of code in something silly like object Example { ... } so that it all gets processed by the REPL at once.