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

adapt generic default parameters to recent generics changes #24065

Merged
merged 4 commits into from
Sep 6, 2024

Conversation

metagn
Copy link
Collaborator

@metagn metagn commented Sep 5, 2024

fixes #16700, fixes #20916, refs #24010

Fixes the instantiation issues for proc param default values encountered in #24010 by:

  1. semchecking generic default param values with inGenericContext for fix calls in generic bodies, delay typecheck when no overloads match #22029 and followups to apply (the bigger change in semtypes),
  2. rejecting explicit generic instantiations with unresolved generic types inside inGenericContext (sigmatch change),
  3. instantiating the default param values using prepareNode rather than an insufficient manual method (the bigger change in seminst).

This had an important side effect of references to other parameters not working since they would be resolved as a symbol belonging to the uninstantiated original generic proc rather than the later instantiated proc. There is a more radical way to fix this which is generating ident nodes with tyFromExpr in specifically this context, but instead we just count them as belonging to the same proc in hoistParamsUsedInDefault.

Other minor bugfixes:

  • To make the error message in t20883 make sense, we now give a "cannot instantiate" error when trying to instantiate a proc generic param with tyFromExpr.
  • Object constructors as default param values generated default values of private fields going through evalConstExpr more than once, but the VM doesn't mark the object fields as nfSkipFieldChecking which gives a "cannot access field" error. So the VM now marks object fields it generates as nfSkipFieldChecking. Not sure if this affects VM performance, don't see why it would.
  • The nkRecWhen changes in check constant conditions in generic when in objects #24042 didn't cover the case where all conditions are constantly false correctly, this is fixed with a minor change. This isn't needed for this PR now but I encountered it after forgetting to dec c.inGenericContext.

@metagn metagn marked this pull request as draft September 5, 2024 22:12
@metagn metagn changed the title test fixing default parameter instantiation adapt generic default parameters to recent generics changes Sep 6, 2024
@metagn metagn marked this pull request as ready for review September 6, 2024 00:30
@Araq Araq merged commit a93c5d7 into nim-lang:devel Sep 6, 2024
19 checks passed
Copy link
Contributor

github-actions bot commented Sep 6, 2024

Thanks for your hard work on this PR!
The lines below are statistics of the Nim compiler built from a93c5d7

Hint: mm: orc; opt: speed; options: -d:release
174133 lines; 9.094s; 655.23MiB peakmem

metagn added a commit to metagn/Nim that referenced this pull request Sep 6, 2024
Araq pushed a commit that referenced this pull request Sep 8, 2024
fixes CI, refs #24066, refs #24065

The combination of #24065 and #24066 caused a CI failure where a `when`
branch that was never compiled gave an undeclared identifier error. This
is because the `when` branch was being semchecked with `semGenericStmt`
without `withinMixin`, which is the flag `semgnrc` normally gives to
`when` branch bodies. To fix this, just pass the whole `when` stmt to
`semGenericStmt` rather than the individual blocks.

The alternative would be to just replace the calls to `semGenericStmt`
with a new proc that does the same thing, just with the flags
`{withinMixin}`.
Araq pushed a commit that referenced this pull request Sep 11, 2024
fixes #23506

#24065 broke compilation of template parameter default values that
depended on other template parameters. But this was never implemented
anyway, actually attempting to use those default values breaks the
compiler as in #23506. So these are now implemented as well as fixing
the regression.

First, if a default value expression uses any unresolved arguments
(generic or normal template parameters) in a template header, we leave
it untyped, instead of applying the generic typechecking (fixing the
regression). Then, just before the body of the template is about to be
explored, the default value expressions are handled in the same manner
as the body as well. This captures symbols including the parameters, so
the expression is checked again if it contains a parameter symbol, and
marked with `nfDefaultRefsParam` if it does (as an optimization to not
check it later).

Then when the template is being evaluated, when substituting a
parameter, if we try to substitute with a node marked
`nfDefaultRefsParam`, we also evaluate it as we would the template body
instead of passing it as just a copy (the reason why it never worked
before). This way we save time if a default value doesn't refer to
another parameter and could just be copied regardless.
Araq pushed a commit that referenced this pull request Sep 27, 2024
fixes #12942, fixes #19118

This is the exact same as #20735 but maybe the situation has improved
after #24065.
Araq pushed a commit that referenced this pull request Nov 6, 2024
fixes issue described in https://forum.nim-lang.org/t/12579

In #24065 explicit generic parameter matching was made to fail matches
on arguments with unresolved types in generic contexts (the sigmatch
diff, following #24010), similar to what is done for regular calls since
#22029. However unlike regular calls, a failed match in a generic
context for a standalone explicit generic instantiation did not convert
the expression into one with `tyFromExpr` type, which means it would
error immediately given any unresolved parameter. This is now done to
fix the issue.

For explicit generic instantiations on single non-overloaded symbols, a
successful match is still instantiated. For multiple overloads (i.e.
symchoice), if any of the overloads fail the match, the entire
expression is considered untyped and any instantiations are not used, so
as to not void overloads that would match later. This means even
symchoices without unresolved arguments aren't instantiated, which may
be too restrictive, but it could also be too lenient and we might need
to make symchoice instantiations always untyped. The behavior for
symchoice is not sound anyway given it causes #9997 so this is something
to consider for a redesign.

Diff follows #24276.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants