Skip to content

Infinite recursion when matching a function in an enum case with the same name as a method of that enum #19641

Closed
@kyouko-taiga

Description

@kyouko-taiga

Compiler version

3.3.1

Minimized code

type DiagnosticConsturctor = (Int) => DiagnosticSet

final class Diagnostic

final class DiagnosticSet(elements: List[Diagnostic] = List())

enum Result:
  case Success extends Result
  case Failure(diagnose: DiagnosticConsturctor) extends Result
  def diagnose(n: Int): DiagnosticSet =
    this match
      case Success => DiagnosticSet()
      case Failure(d) => d(n)

@main def drive(): Unit =
  val r : Result = Result.Failure((n) => DiagnosticSet(List(Diagnostic())))
  r.diagnose(1)

Output

Stack overflow

Expectation

The program should run to completion.

My understanding of the issue is that the compiler resolves d to the method defined as member of Result rather than the case value of Failure. The stack trace is very confusing, though, as it reports a ping pong between the call in the match expression and the definition of the Failure case.

Note that a compile-time error is produced if the domain of diagnose is empty:

type DiagnosticConsturctor = () => DiagnosticSet

enum Result:
  case Success extends Result
  case Failure(diagnose: DiagnosticConsturctor) extends Result
  def diagnose(): DiagnosticSet = ???

In this case, the compiler complains that:

overriding method diagnose in class Result of type (): DiagnosticSet; value diagnose of type DiagnosticConsturctor needs override modifier

The reported issue can be fixed by renaming either the case value or the method.

Although this reproducer shows bad class design in Scala (buggy behavior aside), it is representative of a very reasonable setup for developers coming from Swift. Hence it might serve as a reference in the future to remember how Swift users can get intro trouble.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions