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

make forwarded generic types work #645

Closed
metagn opened this issue Feb 28, 2025 · 1 comment · Fixed by #754
Closed

make forwarded generic types work #645

metagn opened this issue Feb 28, 2025 · 1 comment · Fixed by #754
Assignees

Comments

@metagn
Copy link
Collaborator

metagn commented Feb 28, 2025

Has been alluded to in code comments but still opening an issue to track it

Using a structural generic type before its declaration doesn't work (common in cases like NodeObj[T] = ...; Node[T] = ref NodeObj[T]):

type
  Foo[T] = object
    x: Bar[T]
  Bar[T] = T

The reason is that in the SemcheckTopLevelSyms phase, typevars are not declared yet and they are not referenced in the preliminal AST of the type. Guessing the solution is:

  1. typevars are declared in SemcheckTopLevelSyms
  2. an untyped prepass or something similar captures the typevar symbols in the type AST in SemcheckTopLevelSyms rather than just taking the raw AST

Then since instantiating the type compiles the type expression, it will work even though the type AST is not originally fully typed. Though it depends on the untyped prepass outside of compat mode.

Another option might be to allow invocation types to have structural type implementations for cases like this but this is too niche of a case for invoke types to always have to consider. Also this would have to account for cases like Foo = Bar[int] where it has to resolve immediately and isn't delayed until generic instantiations.


Everything beyond this point is not necessary to fix to close this issue as they are not really encountered in Nim code but is context for choosing a solution.

Another case is that using a concrete nominal generic type before its declaration doesn't work:

type
  Foo = object
    x: Bar[int]
  Bar[T] = object

Again, the issue is that typevars are not declared yet, but I am not sure if attempting to compile untyped AST of nominal types is sound, though I don't see why it wouldn't be.

An edge case for untyped AST of nominal types (that was not possible in Nim code up to this point) would be:

type Foo[T] = object
  x: Bar[T]

proc foo[U](y: Foo[U]) =
  let a: U = y.x.field

type Bar[T] = object
  field: T

where foo has to know that Bar.field has type U. Even this case would probably be fine, since field expressions mostly use identifiers and not symbols in generic contexts, and we freshly instantiate generic field types since #592 so untyped field type expressions would be handled.

@metagn metagn self-assigned this Feb 28, 2025
@Araq
Copy link
Member

Araq commented Feb 28, 2025

If required, feel free to do the following:

  • Copy types into their own "dest" buffer.
  • Iterate over the type-specific token stream as often as required. ("Fixpoint iteration.")
  • Eliminate type aliases early, it's super annoying to have to always keep them in mind if I want to check x.typ == RefT in some backend pass. This includes generic aliases in the form of type A[T] = T.

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

Successfully merging a pull request may close this issue.

2 participants