effekt icon indicating copy to clipboard operation
effekt copied to clipboard

Misleading error "recursive functions need annotated return types"

Open jiribenes opened this issue 11 months ago • 4 comments

Here's the whole error: notice that the real problem is that the actual return type doesn't match the expected return type --- this has nothing to do with recursive / forward-declared functions! Screenshot 2024-03-22 at 16 53 41

Interestingly, it goes away if we try just functions with numbers. 🤔

Repro:

def foo(): Unit = {
  val x = Nil[Int]()
  head(x)
}

Originally reported by @mlutze

jiribenes avatar Mar 22 '24 15:03 jiribenes

Fascinatingly, the error doesn't go away if I annotate the return type as Int:

def foo(): Int = {
  val x = Nil[Int]()
  head(x)
}

So this is an actual bug, not just a bad error message -- is it perhaps a "unhandled effect" error? 🤔

jiribenes avatar Mar 22 '24 16:03 jiribenes

As @marvinborner noted, this issue is fixed by handling the Exception effect. The following code doesn't report the error anymore:

def foo(): Int = {
  val x = Nil[Int]()
  try {
    head(x)
  } with Exception[EmptyList] {
    def raise(exception: EmptyList, msg: String) = {
      println(msg); 0
    }
  }
}

jiribenes avatar Mar 22 '24 16:03 jiribenes

The issue is also fixed by annotating the Exception effect:

def foo(): Int / Exception[EmptyList] = {
  //             ^^^^^^^^^^^^^^^^^^^^
  val x = Nil[Int]()
  head(x)
}

jiribenes avatar Mar 26 '24 15:03 jiribenes

Strangely it does report the correct error in the following case:

def myHead[A](l: List[A]) = head(l)

def foo(): Unit = {
  val x = Nil[Int]()
  myHead(x)
}

b-studios avatar Mar 26 '24 15:03 b-studios