E142: Skolem in Inferred
Note: This error code was made inactive in Scala 3.8.1. The behavior was changed to throw a TypeError earlier in the compilation process, preventing the generation of invalid trees.
This error occurred when the compiler attempted to generate a given instance that contained a reference to a skolem type. Skolem types are placeholder types used internally by the compiler during type inference that cannot be directly referenced in generated code.
According to the commit that changed this behavior: "Previously, the valueOf inline call succeeded (because the ValueOf synthesizer calls tpd.ref which calls tpd.singleton), leading to an invalid tree which crashed in the backend with: 'assertion failed: Cannot create ClassBType from NoSymbol'. Fixed by throwing a TypeError from tpd.singleton."
The error message indicated that implicit search found a solution, but the solution contained a part that referred to a skolem type which could not be materialized into actual code.
Example
trait QC:
object tasty:
type Tree
extension (tree: Tree)
def pos: Tree = ???
def test =
given [T]: QC = ???
def unseal(using qctx: QC): qctx.tasty.Tree = ???
unseal.pos
Error
-- [E142] Type Error: example.scala:10:2 ---------------------------------------
10 | unseal.pos
| ^^^^^^
|Failure to generate given instance for type ?{ pos: ? } from argument of type ?1.tasty.Tree)
|
|I found: <skolem>.tasty.pos(unseal(given_QC[Any]))
|But the part corresponding to `<skolem>` is not a reference that can be generated.
|This might be because resolution yielded as given instance a function that is not
|known to be total and side-effect free.
|
|where: ?1 is an unknown value of type QC
|----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| The part of given resolution that corresponds to `<skolem>` produced a term that
| is not a stable reference. Therefore a given instance could not be generated.
|
| To trouble-shoot the problem, try to supply an explicit expression instead of
| relying on implicit search at this point.
----------------------------------------------------------------------------
Note: In Scala 3.8.1+, this error was changed to throw a TypeError earlier in compilation, resulting in error E008 instead.
Solution
The key to solving this error is to avoid creating skolem types by making the context parameter explicit and stable.
trait QC:
object tasty:
type Tree
extension (tree: Tree)
def pos: Tree = ???
// Solution 1: Use an explicit named given instead of polymorphic given
def test =
given qc: QC = ??? // Named given, not [T]: QC
def unseal(using qctx: QC): qctx.tasty.Tree = ???
val tree = unseal(using qc)
qc.tasty.pos(tree) // Call extension method explicitly with stable context
trait QC:
object tasty:
type Tree
extension (tree: Tree)
def pos: Tree = ???
// Solution 2: Store result with explicit type annotation
def test =
given qc: QC = ???
val tree: qc.tasty.Tree = {
def unseal(using qctx: QC): qctx.tasty.Tree = ???
unseal
}
tree.pos // Now the type is stable
trait QC:
object tasty:
type Tree
extension (tree: Tree)
def pos: Tree = ???
// Solution 3: Make the context parameter explicit in the function signature
def test(using qc: QC) = // Explicit context parameter
def unseal(using qctx: QC): qctx.tasty.Tree = ???
unseal.pos // Works because qc is stable