Skip to content

Undefined reference when typing dependent annotation #21595

Closed as not planned
Closed as not planned
@mbovel

Description

@mbovel

The following still fails:

class dummy(b: Boolean) extends annotation.StaticAnnotation

object Test:
  def foo(elem: Int, bla: Int @dummy(elem == 0)) = bla
-- Error: try/annn2.scala:9:37 -------------------------------------------------
  9 |  def foo(elem: Int, bla: Int @dummy(elem == 0)) = bla
    |                                     ^^^^^^^^^
    |          undefined: elem.== # -1: TermRef(TermParamRef(elem),==) at typer

The initial typing of the arguments work, but when we want to create the MethodType using fromSymbols we perform a substitution. We correctly substitute TermRef(NoPrefix, elem) by a TermParamRef representing the first parameter of the MethodType, the TypeMap goes back up one level, and creates new elem.== which can be done without forcing the underlying type of elem, but when we go back up one more level and create a new elem.==(0), the TypeAssigner for Apply forces the computation of the underlying type of elem.==, which in turn requires computing the underlying type of elem, where we get NoType because we're in the middle of computing paramInfos:

override def underlying(using Context): Type = {
// TODO: update paramInfos's type to nullable
val infos: List[Type] | Null = binder.paramInfos
if (infos == null) NoType // this can happen if the referenced generic type is not initialized yet

val paramInfos: List[Type] = paramInfosExp(this: @unchecked)

To avoid this issue it seems we'd need paramInfos to be filled progressively as we compute each parameter, so the second parameter can at least safely refer to the first one.

Originally posted by @smarter in #19957 (comment)

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