Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f861016

Browse files
authored
Merge pull request #11105 from som-snytt/backport/13116
Backport missing interpolator skips unpositioned literal
2 parents 16165fa + e043e31 commit f861016

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5612,7 +5612,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
56125612
// testing pos works and may suffice
56135613
//openMacros exists (_.macroApplication.pos includes lit.pos)
56145614
// tests whether the lit belongs to the expandee of an open macro
5615-
openMacros exists (_.macroApplication.attachments.get[MacroExpansionAttachment] match {
5615+
!lit.pos.isDefined ||
5616+
openMacros.exists(_.macroApplication.attachments.get[MacroExpansionAttachment] match {
56165617
case Some(MacroExpansionAttachment(_, t: Tree)) => t exists (_ == lit)
56175618
case _ => false
56185619
})
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// scalac: -Werror -Xlint
2+
3+
import annotation._
4+
5+
package t8013 {
6+
7+
// unsuspecting user of perverse macro
8+
trait User {
9+
import Perverse._
10+
val foo = "bar"
11+
Console.println {
12+
p"Hello, $foo"
13+
}
14+
Console.println {
15+
p(s"Hello, $foo")
16+
}
17+
Console.println {
18+
"Hello, $foo"
19+
}: @nowarn
20+
}
21+
}
22+
23+
object Test extends App {
24+
new t8013.User {}
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
package t8013
3+
4+
// perverse macro to confuse Xlint
5+
6+
import scala.language.experimental.macros
7+
import scala.reflect.macros.blackbox.Context
8+
9+
object Perverse {
10+
11+
implicit class Impervolator(sc: StringContext) {
12+
def p(args: Any*): String = macro pImpl
13+
}
14+
// remarkably, the args are unused; notice the difficulty of adding a non-interpolator version
15+
def p(args: Any*): String = macro pImpl
16+
17+
// turn a nice interpolation into something that looks
18+
// nothing like an interpolation or anything we might
19+
// recognize, but which includes a "$id" in an apply.
20+
def pImpl(c: Context)(args: c.Expr[Any]*): c.Expr[String] = {
21+
import c.universe._
22+
val macroPos = c.macroApplication.pos
23+
val text = macroPos.source.lineToString(macroPos.line - 1) substring macroPos.column
24+
val tt = Literal(Constant(text))
25+
c.typecheck(tt)
26+
val tree = q"t8013.Perverse.pervert($tt)"
27+
c.Expr[String](tree)
28+
}
29+
30+
// identity doesn't seem very perverse in this context
31+
//def pervert(text: String): String = text
32+
def pervert(text: String): String = {
33+
Console println s"Perverting [$text]"
34+
text
35+
}
36+
}

0 commit comments

Comments
 (0)