summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-08-22 08:20:20 +0300
committerGitHub <noreply@github.com>2024-08-22 07:20:20 +0200
commit04da0a6028a4a0d469a10567a35655646f4957c2 (patch)
treef2dfce79bf0519a7eafa5379d4117fccd9f26dfb /compiler
parentac0179ced9a85a0a04f1e3d4f038fb989498d008 (diff)
downloadNim-04da0a6028a4a0d469a10567a35655646f4957c2.tar.gz
fix subscript magic giving unresolved generic param type (#23988)
fixes #19737

As in the diff, `semResolvedCall` sets the return type of a call to a
proc to the type of the call. But in the case of the [subscript
magic](https://nim-lang.org/docs/system.html#%5B%5D%2CT%2CI), this type
is the first generic param which is also supposed to be the type of the
first argument, but this is invalid, the correct type is the element
type eventually given by `semSubscript`. Some lines above also [prevent
the subscript magics from instantiating their
params](https://github.com/nim-lang/Nim/blob/dda638c1ba985a77eac3c7518138992521884172/compiler/semcall.nim#L699)
so this type ends up being an unresolved generic param.

Since the type of the node is not `nil`, `prepareOperand` doesn't try to
type it again, and this unresolved generic param type ends up being the
final type of the node. To prevent this, we just never set the type of
the node if we encountered a subscript magic.

Maybe we could also rename the generic parameters of the subscript
magics to stuff like `DummyT`, `DummyI` if we want this to be easier to
debug in the future.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semcall.nim3
1 files changed, 2 insertions, 1 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 3981d256f..4240bc603 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -725,7 +725,8 @@ proc semResolvedCall(c: PContext, x: var TCandidate,
   result = x.call
   instGenericConvertersSons(c, result, x)
   result[0] = newSymNode(finalCallee, getCallLineInfo(result[0]))
-  result.typ = finalCallee.typ.returnType
+  if finalCallee.magic notin {mArrGet, mArrPut}:
+    result.typ = finalCallee.typ.returnType
   updateDefaultParams(result)
 
 proc canDeref(n: PNode): bool {.inline.} =