Skip to content

Inconsistent results with function arguments and significant indentation #18345

Closed
@JD557

Description

@JD557

Compiler version

3.3.0

Minimized code

Assuming the following definitions:

extension (vec: Seq[Int])
  def iterate[T](body: (() => Int) => T): T =
    val iterator = vec.iterator
    body(() => iterator.nextOption().getOrElse(0))

def withSequence[T](n: Int)(body: Seq[Int] => T): T =
  body((0 to n))

This code works fine with the old style:

withSequence(2) {
  _.iterate { next =>
    next() + next() + next() + next()
  }
}

But converting it to significant indentation fails with cryptic problems

Output

Example 1

withSequence(2): _.iterate: next =>
  next() + next() + next() + next()

Fails with

; expected but . found

end of statement expected but '.' found

Found:    (Seq[Int] => Any) => Any
Required: 

Example 2

withSequence(2):
  _.iterate:
    next =>
      next() + next() + next() + next()

Fails with

indented definitions expected, _ found

Example 3

withSequence(2): x =>
  x.iterate:
    next =>
      next() + next() + next() + next()

Fails with

Recursive value $t needs type

Example 4

Surprisingly, the last two examples work fine when stored in a variable

val foo = withSequence(2): x =>
  x.iterate:
    next =>
      next() + next() + next() + next()

val bar = withSequence(2):
  _.iterate:
    next =>
      next() + next() + next() + next()

Expectation

I would expect at least examples 2 and 3 to behave the same when stored in a variable or not.

I would also argue that all examples should compile, although maybe I'm missing some precedence rules that would make some of them ambiguous.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions