Skip to content

Commit

Permalink
Merge pull request #8770 from dotty-staging/fix-#8745
Browse files Browse the repository at this point in the history
Fix #8745: Match Ident prefixes to find potential holes
  • Loading branch information
nicolasstucki committed Apr 23, 2020
2 parents 0db5976 + b903bd9 commit 102284b
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 4 deletions.
Expand Up @@ -306,6 +306,9 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
case _ => None
}

def Ref_term(tp: TermRef)(using ctx: Context): Ref =
withDefaultPos(tpd.ref(tp).asInstanceOf[tpd.RefTree])

def Ref_apply(sym: Symbol)(using ctx: Context): Ref = {
assert(sym.isTerm)
withDefaultPos(tpd.ref(sym).asInstanceOf[tpd.RefTree])
Expand Down
12 changes: 8 additions & 4 deletions library/src/scala/internal/quoted/Matcher.scala
Expand Up @@ -274,13 +274,17 @@ private[quoted] object Matcher {
case (scrutinee, Typed(expr2, _)) =>
scrutinee =?= expr2


/* Match selection */
case (Select(qual1, _), Select(qual2, _)) if scrutinee.symbol == pattern.symbol =>
qual1 =?= qual2
case (ref: Ref, Select(qual2, _)) if scrutinee.symbol == pattern.symbol || summon[Env].get(scrutinee.symbol).contains(pattern.symbol) =>
ref match
case Select(qual1, _) => qual1 =?= qual2
case ref: Ident =>
ref.tpe match
case TermRef(qual: TermRef, _) => Ref.term(qual) =?= qual2
case _ => matched

/* Match reference */
case (_: Ref, _: Ref) if scrutinee.symbol == pattern.symbol || summon[Env].get(scrutinee.symbol).contains(pattern.symbol) =>
case (_: Ref, _: Ident) if scrutinee.symbol == pattern.symbol || summon[Env].get(scrutinee.symbol).contains(pattern.symbol) =>
matched

/* Match application */
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/tasty/Reflection.scala
Expand Up @@ -673,6 +673,10 @@ class Reflection(private[scala] val internal: CompilerInterface) { self =>

object Ref {

/** A tree representing the same reference as the given type */
def term(tp: TermRef)(using ctx: Context): Ref =
internal.Ref_term(tp)

/** Create a reference tree from a symbol
*
* If `sym` refers to a class member `foo` in class `C`,
Expand Down
3 changes: 3 additions & 0 deletions library/src/scala/tasty/reflect/CompilerInterface.scala
Expand Up @@ -319,6 +319,9 @@ trait CompilerInterface {

def isInstanceOfRef(using ctx: Context): IsInstanceOf[Ref]

/** A tree representing the same reference as the given type */
def Ref_term(tp: TermRef)(using ctx: Context): Ref

def Ref_apply(sym: Symbol)(using ctx: Context): Ref

/** Tree representing a reference to definition with a given name */
Expand Down
16 changes: 16 additions & 0 deletions tests/run-macros/i8745/Macro_1.scala
@@ -0,0 +1,16 @@
import scala.quoted._

object Companion extends Trait
trait Trait {
def fun(first: String): String = "anything"
}

object Macro {
inline def mac(inline tree: String): String = ${ macImpl('tree) }
def macImpl(tree: Expr[String])(using qctx: QuoteContext): Expr[String] = {
tree match {
case vv @ '{ ($s: Trait).fun($arg) } => arg
case _ => Expr("not matched")
}
}
}
6 changes: 6 additions & 0 deletions tests/run-macros/i8745/Test_2.scala
@@ -0,0 +1,6 @@
import Macro._

@main def Test() = { //hello
import Companion._
mac(fun("blah"))
}
15 changes: 15 additions & 0 deletions tests/run-macros/i8745b/Macro_1.scala
@@ -0,0 +1,15 @@
import scala.quoted._

object Companion {
def fun(first: String): String = "anything"
}

object Macro {
inline def mac(inline tree: String): String = ${ macImpl('tree) }
def macImpl(tree: Expr[String])(using qctx: QuoteContext): Expr[String] = {
tree match {
case vv @ '{ ($s: Companion.type).fun($arg) } => arg
case _ => ???
}
}
}
6 changes: 6 additions & 0 deletions tests/run-macros/i8745b/Test_2.scala
@@ -0,0 +1,6 @@
import Macro._

@main def Test() = { //hello
import Companion._
mac(fun("blah"))
}

0 comments on commit 102284b

Please sign in to comment.