diff options
author | alaviss <alaviss@users.noreply.github.com> | 2019-01-23 15:24:21 +0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-01-23 09:24:21 +0100 |
commit | e962be8981ff6ef09625b3cc89e0c0aa1f07b35a (patch) | |
tree | 708a09ca0587adaee52c26f9129f5a4c5df91278 /compiler | |
parent | f1a841c605870711c4b046ee8f8c0a5bbf479bf2 (diff) | |
download | Nim-e962be8981ff6ef09625b3cc89e0c0aa1f07b35a.tar.gz |
compiler/sem*: improve lineinfo for qualified and generic procs (#10427)
Previously the compiler will believe these are where `newSeq` symbol starts: newSeq[int]() ^ system.newSeq[int]() ^ This commit moves them back to: newSeq[int]() ^ system.newSeq[int]() ^
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semcall.nim | 28 | ||||
-rw-r--r-- | compiler/semexprs.nim | 7 | ||||
-rw-r--r-- | compiler/semtempl.nim | 13 |
3 files changed, 29 insertions, 19 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 3723d3fc1..0613a4145 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -462,16 +462,23 @@ proc updateDefaultParams(call: PNode) = if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam call[i] = def +proc getCallLineInfo(n: PNode): TLineInfo = + case n.kind + of nkBracketExpr, nkCall, nkCommand: getCallLineInfo(n.sons[0]) + of nkDotExpr: getCallLineInfo(n.sons[1]) + else: n.info + proc semResolvedCall(c: PContext, x: TCandidate, n: PNode, flags: TExprFlags): PNode = assert x.state == csMatch var finalCallee = x.calleeSym - markUsed(c.config, n.sons[0].info, finalCallee, c.graph.usageSym) - onUse(n.sons[0].info, finalCallee) + let info = getCallLineInfo(n) + markUsed(c.config, info, finalCallee, c.graph.usageSym) + onUse(info, finalCallee) assert finalCallee.ast != nil if x.hasFauxMatch: result = x.call - result.sons[0] = newSymNode(finalCallee, result.sons[0].info) + result.sons[0] = newSymNode(finalCallee, getCallLineInfo(result.sons[0])) if containsGenericType(result.typ) or x.fauxMatch == tyUnknown: result.typ = newTypeS(x.fauxMatch, c) return @@ -496,7 +503,7 @@ proc semResolvedCall(c: PContext, x: TCandidate, result = x.call instGenericConvertersSons(c, result, x) - result[0] = newSymNode(finalCallee, result[0].info) + result[0] = newSymNode(finalCallee, getCallLineInfo(result[0])) result.typ = finalCallee.typ.sons[0] updateDefaultParams(result) @@ -551,7 +558,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, notFoundError(c, n, errors) proc explicitGenericInstError(c: PContext; n: PNode): PNode = - localError(c.config, n.info, errCannotInstantiateX % renderTree(n)) + localError(c.config, getCallLineInfo(n), errCannotInstantiateX % renderTree(n)) result = n proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = @@ -574,9 +581,10 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = if tm in {isNone, isConvertible}: return nil var newInst = generateInstance(c, s, m.bindings, n.info) newInst.typ.flags.excl tfUnresolved - markUsed(c.config, n.info, s, c.graph.usageSym) - onUse(n.info, s) - result = newSymNode(newInst, n.info) + let info = getCallLineInfo(n) + markUsed(c.config, info, s, c.graph.usageSym) + onUse(info, s) + result = newSymNode(newInst, info) proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = assert n.kind == nkBracketExpr @@ -593,7 +601,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # number of generic type parameters: if safeLen(s.ast.sons[genericParamsPos]) != n.len-1: let expected = safeLen(s.ast.sons[genericParamsPos]) - localError(c.config, n.info, errGenerated, "cannot instantiate: '" & renderTree(n) & + localError(c.config, getCallLineInfo(n), errGenerated, "cannot instantiate: '" & renderTree(n) & "'; got " & $(n.len-1) & " type(s) but expected " & $expected) return n result = explicitGenericSym(c, n, s) @@ -602,7 +610,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # 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. - result = newNodeI(a.kind, n.info) + result = newNodeI(a.kind, getCallLineInfo(n)) for i in countup(0, len(a)-1): var candidate = a.sons[i].sym if candidate.kind in {skProc, skMethod, skConverter, diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 82f948492..96fefa4b8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1171,9 +1171,10 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = onUse(n.info, s) result = newSymNode(s, n.info) else: - markUsed(c.config, n.info, s, c.graph.usageSym) - onUse(n.info, s) - result = newSymNode(s, n.info) + let info = getCallLineInfo(n) + markUsed(c.config, info, s, c.graph.usageSym) + onUse(info, s) + result = newSymNode(s, info) proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if it's not a built-in field access diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 14507cf9d..d920a54b8 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -58,25 +58,26 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = inc(i) if i > 1: break a = nextOverloadIter(o, c, n) + let info = getCallLineInfo(n) if i <= 1 and r != scForceOpen: # XXX this makes more sense but breaks bootstrapping for now: # (s.kind notin routineKinds or s.magic != mNone): # for instance 'nextTry' is both in tables.nim and astalgo.nim ... - result = newSymNode(s, n.info) - markUsed(c.config, n.info, s, c.graph.usageSym) - onUse(n.info, s) + result = newSymNode(s, info) + markUsed(c.config, info, s, c.graph.usageSym) + onUse(info, s) else: # semantic checking requires a type; ``fitNode`` deals with it # appropriately let kind = if r == scClosed or n.kind == nkDotExpr: nkClosedSymChoice else: nkOpenSymChoice - result = newNodeIT(kind, n.info, newTypeS(tyNone, c)) + result = newNodeIT(kind, info, newTypeS(tyNone, c)) a = initOverloadIter(o, c, n) while a != nil: if a.kind != skModule: incl(a.flags, sfUsed) - addSon(result, newSymNode(a, n.info)) - onUse(n.info, a) + addSon(result, newSymNode(a, info)) + onUse(info, a) a = nextOverloadIter(o, c, n) proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode = |