Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression in recursive pickling of abstract type members #15174

Closed
WojciechMazur opened this issue May 12, 2022 · 3 comments · Fixed by #15229
Closed

Regression in recursive pickling of abstract type members #15174

WojciechMazur opened this issue May 12, 2022 · 3 comments · Fixed by #15229
Assignees
Labels
area:pickling itype:bug regression This worked in a previous version but doesn't anymore
Milestone

Comments

@WojciechMazur
Copy link
Contributor

WojciechMazur commented May 12, 2022

It seems that currently compiler is more strict and does not handle well recursive/lazy references to type classes. In case Codec#AvroType is not an abstract type member the snippet would compile.

Based on https://github.com/fd4s/vulcan/blob/aa857bab732b4f8b52e56473b0626b5403eef42d/modules/core/src/test/scala/vulcan/CodecSpec.scala#L1657-L1670

Compiler version

3.1.2, works with 3.1.1

First bad commit ae1b00d

Minimized code

//> using scala "3.1.2"
// //> using scala "3.1.1" // Last stable working version

trait Error
sealed abstract class Codec[A] {
  type AvroType
  def encode(a: A): Either[Error, AvroType]
  def decode(value: Any): Either[Error, A]
}

object Codec {
  type Aux[AvroType0, A] = Codec[A] {
    type AvroType = AvroType0
  }

  final def instance[AvroType0, A](
      encode: A => Either[Error, AvroType0],
      decode: Any => Either[Error, A]
  ): Codec.Aux[AvroType0, A]  = ???

  implicit final def option[A](implicit codec: Codec[A]): Codec[Option[A]] = ???
  given Codec.Aux[Int, Int] = ???
}


@main def test() = {
  implicit val codec: Codec[Option[Int]] =
    Codec.instance(
      Codec.option[Int].encode,
      Codec.option[Int].decode
    )
}

Output

[error] ./test.scala:29:7: pickling reference to as yet undefined ($1$ : Codec[Option[Int]]) with symbol value $1$
[error]       Codec.option[Int].encode,
[error]       ^
Error compiling project (Scala 3.1.2, JVM)

Expectation

The snippet should compile like in the 3.1.1

@WojciechMazur WojciechMazur added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 12, 2022
@prolativ prolativ added area:pickling regression This worked in a previous version but doesn't anymore and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 13, 2022
@Kordyjan Kordyjan added this to the 3.1.3 milestone May 16, 2022
@nicolasstucki
Copy link
Contributor

Started failing in 3.1.2-RC1-bin-20211217-b3ab102-NIGHTLY

@nicolasstucki
Copy link
Contributor

First bad commit ae1b00d

@odersky
Copy link
Contributor

odersky commented May 18, 2022

When turning the error into an assertion failure, I see:

error when pickling tree Codec.instance[$1$.AvroType, Option[Int]](
  {
    val $1$: Codec[Option[Int]] = Codec.option[Int](Codec.given_Aux_Int_Int)
    {
      def $anonfun(a: Option[Int]): Either[Error, $1$.AvroType] = $1$.encode(a)
      closure($anonfun)
    }
  }
, 
  {
    val $2$: Codec[Option[Int]] = Codec.option[Int](Codec.given_Aux_Int_Int)
    {
      def $anonfun(value: Any): Either[Error, Option[Int]] = $2$.decode(value)
      closure($anonfun)
    }
  }
)

So something is clearly fishy here: We pass an argument $1$.AvroType to Codec.instance, but $1$ is only defined
in the nested block. Looks like a failure in avoidance.

Maybe the level logic for type variables should catch this? /cc @smarter

smarter added a commit to dotty-staging/dotty that referenced this issue May 18, 2022
We need to manually increase the nestingLevel of symbols created by
EtaExpansion#lift to compensate for the fact that they will end up in a block.

Fixes scala#15174.
smarter added a commit to smarter/dotty that referenced this issue May 19, 2022
We need to manually increase the nestingLevel of symbols created by
EtaExpansion#lift to compensate for the fact that they will end up in a block.

Fixes scala#15174.
bishabosha pushed a commit to dotty-staging/dotty that referenced this issue May 20, 2022
We need to manually increase the nestingLevel of symbols created by
EtaExpansion#lift to compensate for the fact that they will end up in a block.

Fixes scala#15174.
bishabosha pushed a commit to dotty-staging/dotty that referenced this issue Oct 18, 2022
We need to manually increase the nestingLevel of symbols created by
EtaExpansion#lift to compensate for the fact that they will end up in a block.

Fixes scala#15174.
@Kordyjan Kordyjan modified the milestones: 3.1.3, 3.2.0 Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:pickling itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants