scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.81k stars 1.05k forks source link

In order to activate givens, I cannot use import *. #21317

Closed DavidPerezIngeniero closed 1 month ago

DavidPerezIngeniero commented 1 month ago

Compiler version

Minimized code

This code isn't minimized, but I've included the relevant parts.

File Privilegio.scala:

object UserPrivilegesEncoderDecoder {

  given Decoder[Privilegio] = deriveDecoder[Privilegio]
  given Encoder[Privilegio] = deriveEncoder[Privilegio]

  given Encoder.AsObject[Usuario] = deriveEncoder[Usuario]
  given Decoder[Usuario] = deriveDecoder[Usuario]

  given Encoder.AsObject[EntityId] = deriveEncoder[EntityId]
  given Decoder[EntityId] = deriveDecoder[EntityId]

  given Encoder.AsObject[EntityPrivilege] = deriveEncoder[EntityPrivilege]
  given Decoder[EntityPrivilege] = deriveDecoder[EntityPrivilege]

  given Encoder.AsObject[Privileges] = deriveEncoder[Privileges]
  given Decoder[Privileges] = deriveDecoder[Privileges]

  given upd: Decoder[UserPrivileges] = deriveDecoder[UserPrivileges]
  given upe: Encoder[UserPrivileges] = deriveEncoder[UserPrivileges]
}

File DefaultSerializer.scala:

class DefaultJsonSerializer[T: Encoder: Decoder] extends RedisCacheValueSerializer[T]{
  override def serialize(value: T): OperationResult[String] =
    OperationResult(value.asJson.noSpaces)

  override def deserialize(contenido: String, cacheName: String, clave: String): OperationResult[T] = {
    decode[T](contenido) match{
      case Right(value) => OperationResult(value)
      case Left(error) => SystemFailure(new Exception(s"Error leyendo de redis para cache $cacheName: ${error.getMessage}. Clave: $clave. Contenido: $contenido"))
    }
  }
}

File CachePrivilegiosPorEntidad.scala:


import fcc.vision.permisos.UserPrivilegesEncoderDecoder.*

class CachePrivilegiosPorEntidad(redisPool: RedisPool)
  extends CacheVisionRedis[PrivilegiosPorEntidadKey, UserPrivileges, CachePermisosContext](
    CachePrivilegiosPorEntidad.name,
    new InvalidadorCachePrivilegiosPorEntidad(CachePrivilegiosPorEntidad.name),
    new CacheRedisActions[UserPrivileges](new DefaultJsonSerializer, redisPool, CachePrivilegiosPorEntidad.name)
  ){
  override protected val obtencionCache = new ObtencionPrivilegiosPorEntidad

  override def invalida(predicado: (PrivilegiosPorEntidadKey, UserPrivileges) => Boolean): Unit = ???
}

Output

Error message from the compiler:

    No given instance of type io.circe.Encoder[fcc.vision.permisos.UserPrivileges] was found for a context parameter of constructor DefaultJsonSerializer in class DefaultJsonSerializer.
    I found:

    io.circe.Encoder.importedEncoder[fcc.vision.permisos.UserPrivileges](
      /* missing */
        summon[
          io.circe.export.Exported[
            io.circe.Encoder[fcc.vision.permisos.UserPrivileges]]
        ]
    )

the error is located in iCachePrivilegiosPorEntidad in new DefaultJsonSerializer

Expectation

In order to activate givens, I can use import MyObject.*

Workaround

In the CachePrivilegiosPorEntidad.scala file, I 've change this line:

import fcc.vision.permisos.UserPrivilegesEncoderDecoder.*

by this other one:

import fcc.vision.permisos.UserPrivilegesEncoderDecoder.{upd, upe}

import fcc.vision.permisos.UserPrivilegesEncoderDecoder.{upd, upe}

WojciechMazur commented 1 month ago

I belive it works as expected https://docs.scala-lang.org/scala3/reference/contextual/given-imports.html Using import xxx.{*, given} would import both normal symbols and given instances

odersky commented 1 month ago

Yes, this works as expected.

DavidPerezIngeniero commented 1 month ago

Sorry, then it is a lack of knowledge of how to import givens. I'm just migrating to Scala 3.