E098: Failure To Eliminate Existential

This warning is emitted when a complex existential type from a Scala 2 classfile cannot be accurately mapped to a Scala 3 equivalent.

Existential types in their full generality are no longer supported in Scala 3. When reading Scala 2 classfiles that contain existential types, Scala 3 attempts to approximate them. Simple existentials (like List[T] forSome { type T }) are handled cleanly, but complex existential types where bound variables cannot be fully eliminated may trigger this warning.

This is a rare compatibility warning that most users will never encounter.


Example

This warning can only occur when loading classes compiled with Scala 2 that use complex existential types where the bound type variable appears in a position that prevents clean elimination:

// Scala 2 library code (compiled with Scala 2)
// Complex existential where T appears in multiple positions
class Container {
  def get: (T, List[T]) forSome { type T } = ???
}
scala2-existential
// Scala 3 code trying to use the Scala 2 library
val container = new Container()
val items = container.get  // Warning E098 may be emitted when loading Container.class

Error

-- [E098] Compatibility Warning: -----------------------------------------------
  |An existential type that came from a Scala-2 classfile for Container
  |cannot be mapped accurately to a Scala-3 equivalent.
  |original type    : List[T] forSome { type T }
  |reduces to       : List[?]
  |type used instead: List[Any]
  |This choice can cause follow-on type errors or hide type errors.
  |Proceed at own risk.

Solution

If you control the library, recompile it with Scala 3. Replace existential types with wildcards or type parameters If you don't control the library, be aware of potential type mismatches and use explicit type annotations where needed

// Instead of: List[T] forSome { type T } use wildcards or add type parameter
def get[T]: List[T] = ???
def getAny: List[?] = ???