diff --git a/compiler/ast.nim b/compiler/ast.nim index a381521a73173..1c41ae56072e2 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1089,18 +1089,6 @@ proc setInfoRecursive*(n: PNode, info: TLineInfo) = for i in 0.. 0: - return getCallLineInfo(n[0]) - of nkDotExpr: - if len(n) > 1: - return getCallLineInfo(n[1]) - else: - discard - result = n.info - when defined(useNodeIds): const nodeIdToDebug* = -1 # 2322968 var gNodeId: int diff --git a/compiler/semcall.nim b/compiler/semcall.nim index c5eb7c17775bb..986088fc0323d 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -668,6 +668,18 @@ proc updateDefaultParams(c: PContext, call: PNode) = def.typ = errorType(c) call[i] = def +proc getCallLineInfo*(n: PNode): TLineInfo = + case n.kind + of nkAccQuoted, nkBracketExpr, nkCall, nkCallStrLit, nkCommand: + if len(n) > 0: + return getCallLineInfo(n[0]) + of nkDotExpr: + if len(n) > 1: + return getCallLineInfo(n[1]) + else: + discard + result = n.info + proc inheritBindings(c: PContext, x: var TCandidate, expectedType: PType) = ## Helper proc to inherit bound generic parameters from expectedType into x. ## Does nothing if 'inferGenericTypes' isn't in c.features. @@ -816,19 +828,20 @@ proc explicitGenericInstError(c: PContext; n: PNode): PNode = localError(c.config, getCallLineInfo(n), errCannotInstantiateX % renderTree(n)) result = n -proc explicitGenericSym(m: var TCandidate, n: PNode, s: PSym): PSym = +proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = if s.kind in {skTemplate, skMacro}: - internalError m.c.config, n.info, "cannot get explicitly instantiated symbol of " & + internalError c.config, n.info, "cannot get explicitly instantiated symbol of " & (if s.kind == skTemplate: "template" else: "macro") + var m = newCandidate(c, s, nil) matchGenericParams(m, n, s) if m.state != csMatch: return nil - var newInst = m.c.semGenerateInstance(m.c, s, m.bindings, n.info) + var newInst = c.semGenerateInstance(c, s, m.bindings, n.info) newInst.typ.flags.excl tfUnresolved - result = newInst let info = getCallLineInfo(n) - markUsed(m.c, info, s) + markUsed(c, info, s) onUse(info, s) + result = newSymNode(newInst, info) proc setGenericParams(c: PContext, n, expectedParams: PNode) = ## sems generic params in subscript expression @@ -858,16 +871,13 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = localError(c.config, getCallLineInfo(n), errGenerated, "cannot instantiate: '" & renderTree(n) & "'; got " & $(n.len-1) & " typeof(s) but expected " & $expected) return n - var m = newCandidate(c, s, nil) - let x = explicitGenericSym(m, n, s) - if x == nil: result = explicitGenericInstError(c, n) - else: result = newSymNode(x, getCallLineInfo(n)) + result = explicitGenericSym(c, n, s) + if result == nil: result = explicitGenericInstError(c, n) elif a.kind in {nkClosedSymChoice, nkOpenSymChoice}: # choose the generic proc with the proper number of type parameters. # XXX I think this could be improved by reusing sigmatch.paramTypesMatch. # It's good enough for now. - let info = getCallLineInfo(n) - result = newNodeI(a.kind, info) + result = newNodeI(a.kind, getCallLineInfo(n)) for i in 0.. 0: + while arg != nil and arg.kind == tyGenericParam: + arg = idTableGet(m.bindings, arg) + if arg == nil or arg.containsGenericType: + m.state = csNoMatch + return # fix up the type to get ready to match formal: var formalBase = formal while formalBase.kind == tyGenericParam and diff --git a/tests/proc/texplicitgenerics.nim b/tests/proc/texplicitgenerics.nim index ffa34322e1e66..eb3e186dff648 100644 --- a/tests/proc/texplicitgenerics.nim +++ b/tests/proc/texplicitgenerics.nim @@ -32,11 +32,12 @@ block: # sigmatch can't handle this without pre-instantiating the type: proc bar[T](f: Foo[T]) = discard bar[int](foo) -when false: # ditto, but needs #24005 to show the issue +block: # ditto but may be wrong minimization # minimized from measuremancer - proc foo[T](): T = default(T) + type Foo[T] = object + proc foo[T](): Foo[T] = Foo[T]() proc bar[T](x = foo[T]()) = discard - bar[int](123) + bar[int](Foo[int]()) # alternative version proc baz[T](x: typeof(foo[T]())) = discard - baz[int](123) + baz[int](Foo[int]())