From 81a937ce1f23e443a2b60375a0961bafa5b8bd06 Mon Sep 17 00:00:00 2001 From: metagn Date: Tue, 14 May 2024 12:26:33 +0300 Subject: [PATCH] ignore modules when looking up symbol with expected type (#23597) fixes #23596 When importing a module and declaring an overloadable symbol with the same name as the module in the same scope, the module symbol can take over and make the declared overload impossible to access. Previously enum overloading had a quirk that bypassed this in a context where a specific enum type was expected but this was removed in #23588. Now this is bypassed in every place where a specific type is expected since module symbols don't have a type and so wouldn't be compatible anyway. But the issue still exists in places where no type is expected like `let x = modulename`. I don't see a way of fixing this without nerfing module symbols to the point where they're not accessible by default, which might break some macro code. --- compiler/semexprs.nim | 2 +- tests/lookups/tmoduleclash1.nim | 13 +++++++++++++ tests/lookups/tmoduleclash2.nim | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/lookups/tmoduleclash1.nim create mode 100644 tests/lookups/tmoduleclash2.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6893f7287e21..8fcf5936ef57 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -3029,7 +3029,7 @@ proc resolveIdentToSym(c: PContext, n: PNode, resultNode: var PNode, # result is nil on error or if a node that can't produce a sym is resolved let ident = considerQuotedIdent(c, n) var filter = {low(TSymKind)..high(TSymKind)} - if efNoEvaluateGeneric in flags: + if efNoEvaluateGeneric in flags or expectedType != nil: # `a[...]` where `a` is a module or package is not possible filter.excl {skModule, skPackage} let candidates = lookUpCandidates(c, ident, filter) diff --git a/tests/lookups/tmoduleclash1.nim b/tests/lookups/tmoduleclash1.nim new file mode 100644 index 000000000000..7058f691edb2 --- /dev/null +++ b/tests/lookups/tmoduleclash1.nim @@ -0,0 +1,13 @@ +# issue #23596 + +import std/heapqueue +type Algo = enum heapqueue, quick +when false: + let x = heapqueue +let y: Algo = heapqueue +proc bar*(algo=quick) = + var x: HeapQueue[int] + case algo + of heapqueue: echo 1 # `Algo.heapqueue` works on devel + of quick: echo 2 + echo x.len diff --git a/tests/lookups/tmoduleclash2.nim b/tests/lookups/tmoduleclash2.nim new file mode 100644 index 000000000000..958da229966e --- /dev/null +++ b/tests/lookups/tmoduleclash2.nim @@ -0,0 +1,6 @@ +import std/heapqueue +proc heapqueue(x: int) = discard +let x: proc (x: int) = heapqueue +let y: proc = heapqueue +when false: + let z = heapqueue