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

ambiguous identifier resolution #23123

Merged
merged 12 commits into from
Jan 1, 2024
Merged

ambiguous identifier resolution #23123

merged 12 commits into from
Jan 1, 2024

Conversation

metagn
Copy link
Collaborator

@metagn metagn commented Dec 23, 2023

fixes #23002, fixes #22841, refs comments in #23097

When an identifier is ambiguous in scope (i.e. multiple imports contain symbols with the same name), attempt resolving it through type inference (by creating a symchoice). To do this efficiently, qualifiedLookUp had to be broken up so that semExpr can access the ambiguous candidates directly (now obtained directly via lookUpCandidates).

This fixes the linked issues, but an example like:

let on = 123

{.warning[ProveInit]: on.}

will still fail, since on is unambiguously the local let symbol here (this is also true for proc on but proc symbols generate symchoices anyway).

Type symbols are not considered to not confuse the type inference. This includes the change in sigmatch, up to this point symchoices with nonoverloadable symbols could be created, they just wouldn't be considered during disambiguation. Now every proper symbol except types are considered in disambiguation, so the correct symbols must be picked during the creation of the symchoice node. I remember there being a violating case of this in the compiler, but this was very likely fixed by excluding type symbols as CI seems to have found no issues.

The pure enum ambiguity test was disabled because ambiguous pure enums now behave like overloadable enums with this behavior, so we get a longer error message for echo amb like type mismatch: got <MyEnum | OtherEnum> but expected T

@metagn metagn marked this pull request as ready for review December 25, 2023 15:19
compiler/semexprs.nim Outdated Show resolved Hide resolved
@@ -2997,6 +2998,53 @@ proc semPragmaStmt(c: PContext; n: PNode) =
else:
pragma(c, c.p.owner, n, stmtPragmas, true)

proc resolveIdent(c: PContext, ident: PIdent, s: var PSym, n: PNode,
flags: TExprFlags, expectedType: PType): PNode =
Copy link
Member

Choose a reason for hiding this comment

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

So ... it returns what exactly? And when does it overwrite the s parameter? Convoluted.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I swapped s and the result value, and made it so only n's info is needed. Every parameter seems to be needed though, not sure how to get this cleaner.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Now merged n/info and ident into the same parameter (just n), and renamed to resolveIdentToSym. Hopefully this is clearer.

@Araq
Copy link
Member

Araq commented Jan 1, 2024

I'm merging this now but in a followup PR the manual needs to be patched and describe in detail how symbol lookups now interact with overloading etc.

@Araq Araq merged commit b280100 into nim-lang:devel Jan 1, 2024
19 checks passed
Copy link
Contributor

github-actions bot commented Jan 1, 2024

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

Hint: mm: orc; opt: speed; options: -d:release
177631 lines; 8.224s; 768.141MiB peakmem

@metagn metagn added the TODO: followup needed remove tag once fixed or tracked elsewhere label Jan 4, 2024
metagn added a commit to metagn/Nim that referenced this pull request Jan 4, 2024
@metagn metagn removed the TODO: followup needed remove tag once fixed or tracked elsewhere label Jan 4, 2024
Araq pushed a commit that referenced this pull request Jan 11, 2024
Araq pushed a commit that referenced this pull request May 10, 2024
refs
#23586 (comment)

In #20091 a bad kind of type inference was mistakenly left in where if
an identifier `abc` had an expected type of an enum type `Enum`, and
`Enum` had a member called `abc`, the identifier would change to be that
enum member. This causes bugs where a local symbol can have the same
name as an enum member but have a different value. I had assumed this
behavior was removed since but it wasn't, and CI seems to pass having it
removed.

A separate PR needs to be made for the 2.0 branch because these lines
were moved around during a refactoring in #23123 which is not in 2.0.
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 this pull request may close these issues.

Ambiguous identifier in pragma Unittest breaks if proc name on/off defined in same module
2 participants