Skip to content

Presence of opaque type causes erased class instance to not be a pure expression #24990

@mrdziuban

Description

@mrdziuban

Compiler version

3.7.4, 3.8.0, and 3.8.1-RC1

Minimized code

//> using scala 3.8.0
//> using options -language:experimental.erasedDefinitions -explain

object test {
  opaque type Foo = Int

  class Bar[A] extends compiletime.Erased
  object Bar { inline given inst[A]: Bar[A] = new Bar[A] }
}

def takesBar[A](a: A)(using b: test.Bar[A]): A = a

val _ = takesBar(1)

Output

-- [E217] Type Error: ----------------------------------------------------------
10 |val _ = takesBar(1)
   |                   ^
   |  implicit argument to an erased parameter fails to be a pure expression
   |----------------------------------------------------------------------------
   | Explanation (enabled by `-explain`)
   |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   | The implicit argument to an erased parameter must be a pure expression, but I found:
   |
   |   {
   |   val $proxy1: test.type{type Foo = Int} =
   |     test.$asInstanceOf[test.type{type Foo = Int}]
   |   val test$_this: ($proxy1 : test.type{type Foo = Int}) = $proxy1
   |   new test$_this.Bar[Int]():test$_this.Bar[Int]
   | }
   |
   | This expression is not classified to be pure.
   | A pure expression is an expression that is clearly side-effect free and terminating.
   |           |Some examples of pure expressions are:
   |           |  - literals,
   |           |  - references to values,
   |           |  - side-effect-free instance creations,
   |           |  - applications of inline functions to pure arguments.

Expectation

The creation of Bar[Int] is a pure expression. It looks like the compiler is casting test.type to an instance of test.type { type Foo = Int }, and my guess is it's because Bar is defined in the same scope as Foo, and so therefore should see it as an Int...?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions