This macro allows for injecting orphan instances into implicit scope, as follows.
Given a typeclass org.foo.TC[A], and a separate module that wants to put instances of TC into TC's implicit scope,
place a low-priority implicit fundep materialization pointing to the macro method ExpandedScopeMacros#resolveFromScope.
Then, in the separate module, create a subclass of TC, e.g. com.bar.TC1[A]. It must have the same type parameters as TC
and directly extend TC with those type parameters. Place the would-be orphan instances/derivations into TC1's companion
object, making them instances of TC1 rather than TC.
Then, create a resource file in the separate module called META-INF/expanded-scopes/org.foo.TC (the fully qualified
class name of the original typeclass). In this file, there should be a line with the fully qualified name of each
such subclass of TC, i.e. com.bar.TC1.
When instances are searched for org.foo.TC[X], and no instances with higher priority are found, the fundep macro will
scan the classpath and find all such resource files, and for each subclass found it will attempt to resolve an implicit
for e.g. com.bar.TC1[X] and if successful will return that as an instance of org.foo.TC[X].
This allows modules to be created containing orphan instances of TC, while still placing them in implicit scope. This
is used, for example, to allow the polynote-spark-runtime module to define instances of polynote.runtime.ReprsOf
that are in implicit scope for ReprsOf, without making polynote-runtime depend on spark.
This macro allows for injecting orphan instances into implicit scope, as follows.
Given a typeclass org.foo.TC[A], and a separate module that wants to put instances of TC into TC's implicit scope, place a low-priority implicit fundep materialization pointing to the macro method ExpandedScopeMacros#resolveFromScope.
Then, in the separate module, create a subclass of TC, e.g. com.bar.TC1[A]. It must have the same type parameters as TC and directly extend TC with those type parameters. Place the would-be orphan instances/derivations into TC1's companion object, making them instances of TC1 rather than TC.
Then, create a resource file in the separate module called
META-INF/expanded-scopes/org.foo.TC
(the fully qualified class name of the original typeclass). In this file, there should be a line with the fully qualified name of each such subclass of TC, i.e.com.bar.TC1
.When instances are searched for org.foo.TC[X], and no instances with higher priority are found, the fundep macro will scan the classpath and find all such resource files, and for each subclass found it will attempt to resolve an implicit for e.g. com.bar.TC1[X] and if successful will return that as an instance of org.foo.TC[X].
This allows modules to be created containing orphan instances of TC, while still placing them in implicit scope. This is used, for example, to allow the polynote-spark-runtime module to define instances of polynote.runtime.ReprsOf that are in implicit scope for ReprsOf, without making polynote-runtime depend on spark.