Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undefined: ...proxy... errors when inlining opaque types #22359

Open
jchyb opened this issue Jan 13, 2025 · 1 comment · May be fixed by #22381
Open

undefined: ...proxy... errors when inlining opaque types #22359

jchyb opened this issue Jan 13, 2025 · 1 comment · May be fixed by #22381

Comments

@jchyb
Copy link
Contributor

jchyb commented Jan 13, 2025

Compiler version

main

Minimized code

opaque type NT[N <: Tuple, V <: Tuple] = V
opaque type System = NT[Tuple1["wires"], Tuple1[Any]]

extension [N <: Tuple, V <: Tuple] (x: NT[N, V]) {
  inline def apply(n: Int): Any =
    x.productElement(n)
}

extension (system: System) {
  inline def foo =
    system.apply(0)
}

val simulation: System = ???
val _ = simulation.foo

Output

-- Error: X1.scala:11:4 --------------------------------------------------------
11 |    system.apply(0)
   |    ^^^^^^^^^^^^
   |undefined: system$proxy1.apply # -1: TermRef(TermRef(NoPrefix,val system$proxy1),apply) at inlining

Expectation

no error

notes

Initially submitted in connection to NamedTuples: #22324 (fixed for NamedTuples only)

@jchyb jchyb added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 13, 2025
@jchyb jchyb self-assigned this Jan 13, 2025
@jchyb jchyb added area:inline area:opaque-types and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 13, 2025
@jchyb
Copy link
Contributor Author

jchyb commented Jan 13, 2025

Splitting the owners for the opaque types in the minimisation gives us a slightly different error (also incorrect):

object Obj2:
  opaque type NT[N <: Tuple, V <: Tuple] = V

  extension [N <: Tuple, V <: Tuple] (x: NT[N, V]) {
    inline def apply(n: Int): Any =
      x.productElement(n)
  }

object Obj:
  opaque type System = Obj2.NT[Tuple1["wires"], Tuple1[Any]]

  extension (system: System) {
    inline def foo = system.apply(0)
  }
import Obj._
val simulation: System = ???
val _ = simulation.foo
-- [E050] Type Error: X1.scala:17:19 -------------------------------------------
17 |val _ = simulation.foo
   |        ^^^^^^^^^^^^^^
   |        expression does not take parameters
   |----------------------------------------------------------------------------
   |Inline stack trace
   |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   |This location contains code that was inlined from X1.scala:6
 6 |      x.productElement(n)
   |      ^^^^^^^^^^^^^^^^
   |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   |This location contains code that was inlined from X1.scala:6
13 |    inline def foo = system.apply(0)
   |                     ^^^^^^^^^^^^^^^
    ----------------------------------------------------------------------------
   |
   | longer explanation available when compiling with `-explain`

We can see that slightly incorrect bindings are generated:

      val $proxy1:
        Obj.type{type System = Obj2.NT[Tuple1[("wires" : String)], Tuple1[Any]]}
         =
        Obj.$asInstanceOf[
          
            Obj.type{
              type System = Obj2.NT[Tuple1[("wires" : String)], Tuple1[Any]]}
          
        ]
      val system$proxy1: (simulation : Obj.System) & $proxy1.System =
        simulation.$asInstanceOf[(simulation : Obj.System) & $proxy1.System]
      system$proxy1.productElement(0):Any:Any

with a reference to Obj.NT, which is an opaque type, for which proxies are not generated. I imagine it should generate something like this:

      val $proxy0: Obj2.type{type NT[N <: Tuple, V <: Tuple] = V} = Obj2.asInstanceOf[Obj2.type{type NT[N <: Tuple, V <: Tuple] = V}]
      val $proxy1:
        Obj.type{type System = $proxy0.NT[Tuple1[("wires" : String)], Tuple1[Any]]}
         =
        Obj.$asInstanceOf[
          
            Obj.type{
              type System = $proxy0.NT[Tuple1[("wires" : String)], Tuple1[Any]]}
          
        ]
      val system$proxy1: (simulation : Obj.System) & $proxy1.System =
        simulation.$asInstanceOf[(simulation : Obj.System) & $proxy1.System]
      system$proxy1.productElement(0):Any:Any

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant