Skip to content

Multiple inlines make position data on reflect module trees inconsistent #21910

Open
@felher

Description

@felher

Compiler version

Tested on both 3.5.2 and 3.6.1

I tested on 3.6.1 as well because it already contains #21793

Main.scala

@main def hello(): Unit =
  Outer.outer:
    println("hi")

Outer.scala

object Outer:
  inline def outer(inline x: Any): Unit =
    Inner.pos(x)

Inner.scala

import scala.quoted.*

object Inner:
  inline def pos(inline x: Any): Unit =
    ${ posImpl('x) }

  def posImpl(x: Expr[Any])(using Quotes): Expr[Unit] =
    import quotes.reflect.*
    def printPos(p: Position): Unit =
      println(s"${p.start}..${p.end} of ${p.sourceFile.path} with length ${p.sourceFile.content.get.length}")

    printPos(x.asTerm.pos)
    printPos(x.asTerm.asInstanceOf[Inlined].body.pos)
    '{}

Output

70..71 of /tmp/down/inline-pos/src/main/scala/Main.scala with length 59
70..71 of /tmp/down/inline-pos/src/main/scala/Outer.scala with length 73

Expectation

Something different. The range for both cases is the x in Inner.pos(x) in Outer.scala, but the source file for the first one is Main.scala.

I thought maybe using inlining means that they are allowed to get inconsistent, but the docs on .start, .end clearly state that they are offsets in the source file and apply on the PositionModule states that "The range must be contained in the file."

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