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

prefer unambiguous captured symbols in symchoices #23104

Open
wants to merge 7 commits into
base: devel
Choose a base branch
from

Conversation

metagn
Copy link
Collaborator

@metagn metagn commented Dec 19, 2023

fixes #11184, fixes #15650, fixes (untested) #18785, cleans up after #20457, remainder of #22744 after split off from #23091

When a sym choice is being created, if the first symbol is not ambiguous in the current scope, mark it as nfPreferredSym. Then when a sym choice has to be resolved and type disambiguation etc. is not enough, if the first symbol is marked nfPreferredSym then use it.

This fixes the shortcoming of overloadable enums that required #20457 and allows us to implement #11184, now symbols that only have 1 overload in scope in generics/templates can still receive additional overloads in instantiation scope. However just generating an open sym choice with 1 element has issues:

  • The symbol false for example would have type None in generic contexts, which includes default parameter values in proc declarations (which call semGenericStmt), which means proc foo(param = false) would not be able to infer the type of param.
  • Adding a type to the symchoice requires skipping nfSem in semExpr and also makes the compiler not call semSym.
  • We generate way more symchoice nodes than before which may hinder performance.

The solution in this PR is to allow standalone sym nodes to also be annotated nfPreferredSym, which makes them act the same as a unary nkOpenSymChoice during symbol lookup.

@metagn metagn changed the title preferred syms (raw rip from #22744) preferred syms Dec 25, 2023
@metagn metagn changed the title preferred syms prefer unambiguous captured symbols in symchoices Dec 25, 2023
previously the compiler would not allow other overloads in the instantiation
context to be used, which was not the case for 0 or more than 1 overloads.
Now other overloads are allowed with a preference for the original overload
in cases of ambiguity. Some code might need to be changed to use `bind` to
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this can be breaking (required package PRs Nycto/DelaunayNim#5 and PMunch/nimlsp#168), we could make it experimental.

@metagn metagn marked this pull request as ready for review December 25, 2023 20:53
@Araq
Copy link
Member

Araq commented Jan 8, 2024

I don't like node flags in general, they always have quirky semantics (are they copied or not?) and are not part of the spec and not available in the macro system.

If there is a way to introduce new node kinds instead, it's what we should do.

@metagn
Copy link
Collaborator Author

metagn commented Jan 9, 2024

There are 2 chief obstacles for making this and nfOpenSym their own node kinds:

  1. Macros will have to acknowledge them. Gating behind experimental switch mitigates this. We could also just straight up pass them as nkSym to macros, but this is against the point of exposing their existence in the first place.
  2. The compiler needs to keep treating them as nkSym everywhere we don't explicitly treat the node flags. This wouldn't be an issue normally since they don't escape semchecking, but nkSym is special and expressly used for pre-semchecking behavior in a lot of places in the compiler.

This PR doesn't have the urgency that nfOpenSym did so it can wait for a bit to get the node kind working, but I will have to open a separate PR to see how far OpenSym can go as its own node kind.

Araq pushed a commit that referenced this pull request Aug 25, 2024
…le types in symchoices (#23997)

fixes #23898, supersedes #23966 and #23990

Since #20631 ambiguous type symbols in templates are rejected outright,
now we generate a symchoice for type nodes if they're ambiguous, a
generalization of what was done in #22375. This is done for generics as
well. Symchoices also handle type symbols better now, ensuring their
type is a `typedesc` type; this probably isn't necessary for everything
to work but it makes the logic more robust.

Similar to #23989, we have to prepare for the fact that ambiguous type
symbols behave differently than normal type symbols and either error
normally or relegate to other routine symbols if the symbol is being
called. Generating a symchoice emulates this behavior, `semExpr` will
find the type symbol first, but since the symchoice has other symbols,
it will count as an ambiguous type symbol.

I know it seems spammy to carry around an ambiguity flag everywhere, but
in the future when we have something like #23104 we could just always
generate a symchoice, and the symchoice itself would carry the info of
whether the first symbol was ambiguous. But this could harm compiler
performance/memory use, it might be better to generate it only when we
have to, which in the case of type symbols is only when they're
ambiguous.
narimiran pushed a commit that referenced this pull request Sep 16, 2024
…le types in symchoices (#23997)

fixes #23898, supersedes #23966 and #23990

Since #20631 ambiguous type symbols in templates are rejected outright,
now we generate a symchoice for type nodes if they're ambiguous, a
generalization of what was done in #22375. This is done for generics as
well. Symchoices also handle type symbols better now, ensuring their
type is a `typedesc` type; this probably isn't necessary for everything
to work but it makes the logic more robust.

Similar to #23989, we have to prepare for the fact that ambiguous type
symbols behave differently than normal type symbols and either error
normally or relegate to other routine symbols if the symbol is being
called. Generating a symchoice emulates this behavior, `semExpr` will
find the type symbol first, but since the symchoice has other symbols,
it will count as an ambiguous type symbol.

I know it seems spammy to carry around an ambiguity flag everywhere, but
in the future when we have something like #23104 we could just always
generate a symchoice, and the symchoice itself would carry the info of
whether the first symbol was ambiguous. But this could harm compiler
performance/memory use, it might be better to generate it only when we
have to, which in the case of type symbols is only when they're
ambiguous.

(cherry picked from commit 09dcff7)
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