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.
narimiran pushed a commit that referenced this pull request Aug 29, 2024
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:

```nim
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`

(cherry picked from commit b280100)
narimiran pushed a commit that referenced this pull request Aug 31, 2024
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:

```nim
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`

(cherry picked from commit b280100)
narimiran pushed a commit that referenced this pull request Aug 31, 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.

(cherry picked from commit c101490)
Araq pushed a commit that referenced this pull request Sep 9, 2024
fixes #23397

All ambiguous symbols generate symchoices for call arguments since
#23123. So, if a type mismatch receives a symchoice node for an
argument, we now treat it as an ambiguous identifier and list the
ambiguous symbols in the error message.
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