-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Description
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...?