Skip to content

Commit

Permalink
Add documentation and test for indirect summons
Browse files Browse the repository at this point in the history
  • Loading branch information
jchyb committed Jan 21, 2025
1 parent 6ad7c71 commit f95a0a6
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 0 deletions.
11 changes: 11 additions & 0 deletions library/src/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,17 @@ object Expr {
}
}

/** Find a given instance of type `T` in the current scope,
* while excluding certain symbols from the initial implicit search.
* Return `Some` containing the expression of the implicit or
* `None` if implicit resolution failed.
*
* @tparam T type of the implicit parameter
* @param ignored Symbols ignored during the initial implicit search
*
* @note if the found given requires additional search for other given instances,
* this additional search will NOT exclude the symbols from the `ignored` list.
*/
@scala.annotation.experimental def summonIgnoring[T](using Type[T])(using quotes: Quotes)(ignored: quotes.reflect.Symbol*): Option[Expr[T]] = {
import quotes.reflect._
Implicits.searchIgnoring(TypeRepr.of[T])(ignored*) match {
Expand Down
10 changes: 10 additions & 0 deletions library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3706,6 +3706,16 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
*/
def search(tpe: TypeRepr): ImplicitSearchResult

/** Find a given instance of type `T` in the current scope provided by the current enclosing splice,
* while excluding certain symbols from the initial implicit search.
* Return an `ImplicitSearchResult`.
*
* @param tpe type of the implicit parameter
* @param ignored Symbols ignored during the initial implicit search
*
* @note if an found given requires additional search for other given instances,
* this additional search will NOT exclude the symbols from the `ignored` list.
*/
@experimental def searchIgnoring(tpe: TypeRepr)(ignored: Symbol*): ImplicitSearchResult
}

Expand Down
3 changes: 3 additions & 0 deletions tests/run-macros/summonIgnoring-nonrecursive.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TC[C2] generated in macro using:
TC2[_] generated in macro using:
TC[C1] generated in macro
50 changes: 50 additions & 0 deletions tests/run-macros/summonIgnoring-nonrecursive/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//> using options -experimental
import scala.quoted._
class C1
trait TC[T] {
def print(): Unit
}

object TC {
implicit transparent inline def auto[T]: TC[T] = ${autoImpl[T]}
def autoImpl[T: Type](using Quotes): Expr[TC[T]] =
import quotes.reflect._
if (TypeRepr.of[T].typeSymbol == Symbol.classSymbol("C1")){
'{
new TC[T] {
def print() = {
println("TC[C1] generated in macro")
}
}
}
} else {
Expr.summonIgnoring[TC2[C1]](Symbol.classSymbol("TC").companionModule.methodMember("auto")*) match
case Some(a) =>
'{
new TC[T] {
def print(): Unit =
println(s"TC[${${Expr(TypeRepr.of[T].show)}}] generated in macro using:")
$a.print()
}
}
case None =>
'{
new TC[T]{
def print(): Unit =
println(s"TC[${${Expr(TypeRepr.of[T].show)}}] generated in macro without TC2[_]")
}
}
}
}

trait TC2[T] {
def print(): Unit
}

object TC2 {
implicit def auto2[T](using tc: TC[T]): TC2[T] = new TC2[T] {
def print(): Unit =
println(s"TC2[_] generated in macro using:")
tc.print()
}
}
6 changes: 6 additions & 0 deletions tests/run-macros/summonIgnoring-nonrecursive/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//> using options -experimental

@main def Test(): Unit = {
class C2
summon[TC[C2]].print()
}
3 changes: 3 additions & 0 deletions tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ val experimentalDefinitionInLibrary = Set(
// Added for 3.6.0, stabilize after feedback.
"scala.quoted.Quotes.reflectModule.SymbolModule.newBoundedType",
"scala.quoted.Quotes.reflectModule.SymbolModule.newTypeAlias",
// Added for 3.7.0, stabilise after feedback
"scala.quoted.Quotes.reflectModule.ImplicitsModule.searchIgnoring",
"scala.quoted.Expr.summonIgnoring",

// New feature: functions with erased parameters.
// Need erasedDefinitions enabled.
Expand Down

0 comments on commit f95a0a6

Please sign in to comment.