Skip to content

Difference in type resolution between enum and sealed trait + object #23558

@WojciechMazur

Description

@WojciechMazur

Based on OpenCB failure in tofu-tf/tofu after recent code additions - build logs

Compiler version

Since 3.4.1 - bisect points to #19096
Compiles until 3.4.0

Minimized code

trait Loggable[T]
object Loggable:
  def derived[T]: Loggable[T] = ???

trait EnumLoggable[T] extends Loggable[T]
object EnumLoggable:
  def derived[T]: EnumLoggable[T] = ???

sealed trait Trait derives EnumLoggable
object Trait:
  case object A extends Trait
  case object B extends Trait 
  case object C extends Trait 

enum Enum derives EnumLoggable:
  case A, B, C

final case class Container[A, B, C](a: A, b: B, c: C) derives Loggable

@main def Test = 
  def log[A: Loggable](a: A) = ???
  
  val works = log(Container(Enum.A, Enum.B, Enum.C))
  val fails = log(Container(Trait.A, Trait.B, Trait.C))

Output

In case of enum the type is widened to enum Enum thus provides the required implicit instance.
However, in case of case object it's narrowed to the exact type, eg. Trait.A which does not have an implicit available.

[error] ./example.scala:24:56
[error] No given instance of type Loggable[Container[Trait.A.type, Trait.B.type, Trait.C.type]] was found for a context parameter of method log.
[error] I found:
[error] 
[error]     Container.derived$Loggable[Trait.A.type, Trait.B.type, Trait.C.type](
[error]       /* missing */summon[Loggable[Trait.A.type]], ???, ???)
[error] 
[error] But no implicit values were found that match type Loggable[Trait.A.type].
[error]   val fails = log(Container(Trait.A, Trait.B, Trait.C))
[error]                                                        ^

Expectation

To decide if current behaviour is correct or can we improve the current inference / implicit resolution

Issue explicitly not marked as regression - it seems behaviour makes sense as enum does not create new, more specific types, but rather creates new instances of the enum type.
However, it might be confusing for users migrating toward next LTS series.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions