Skip to content

Commit

Permalink
Merge pull request #10391 from som-snytt/issue/8465-dynamic-pos
Browse files Browse the repository at this point in the history
Avoid missing position in dynamic quasi Select
  • Loading branch information
som-snytt committed Jun 23, 2023
2 parents ecbfb07 + a3b6023 commit 3ce2b11
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4557,20 +4557,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ if matches(t) => Some((nme.selectDynamic, t))
case _ => t.children.flatMap(findSelection).headOption
}
findSelection(cxTree) map { case (opName, treeInfo.Applied(_, targs, _)) =>
findSelection(cxTree).map { case (opName, treeInfo.Applied(_, targs, _)) =>
val fun = atPos(wrappingPos(qual :: targs)) {
gen.mkTypeApply(Select(qual, opName) setPos qual.pos, targs)
}
if (opName == nme.updateDynamic) suppressMacroExpansion(fun) // scala/bug#7617
val nameStringLit = atPos(treeSelection.pos.withStart(treeSelection.pos.point).makeTransparent) {
Literal(Constant(name.decode))
val nameStringLit = {
val p = if (treeSelection.pos.isDefined) treeSelection.pos.withStart(treeSelection.pos.point).makeTransparent else treeSelection.pos
atPos(p) {
Literal(Constant(name.decode))
}
}
markDynamicRewrite {
atPos(wrappingPos(qual :: fun :: nameStringLit :: Nil)) {
Apply(fun, List(nameStringLit))
}
}
} getOrElse {
}.getOrElse {
// While there may be an error in the found tree itself, it should not be possible to *not find* it at all.
devWarning(s"Tree $tree not found in the context $cxTree while trying to do a dynamic application")
setError(tree)
Expand Down
18 changes: 18 additions & 0 deletions test/files/run/t8465.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

import scala.language.dynamics
import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox

class C extends Dynamic {
def selectDynamic(s: String) = 42
}

object Test extends App {
val c = new C
assert(c.foo == 42)

val toolbox = currentMirror.mkToolBox()
toolbox.typecheck(q"class C extends Dynamic { def selectDynamic(s: String) = ??? }; val c = new C; c.foo")
toolbox.typecheck(q"42 match { case i => 27 }") // check rewrite to case i @ _
}

0 comments on commit 3ce2b11

Please sign in to comment.