* improve line error information

* fixes #13112
This commit is contained in:
Andreas Rumpf
2020-01-13 15:47:17 +01:00
committed by GitHub
parent abea80376a
commit eadd1ba9ed
3 changed files with 24 additions and 2 deletions

View File

@@ -383,7 +383,7 @@ proc semUnown(c: PContext; n: PNode): PNode =
# little hack for injectdestructors.nim (see bug #11350):
#result[0].typ = nil
proc turnFinalizerIntoDestructor(c: PContext; orig: PSym): PSym =
proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym =
# We need to do 2 things: Replace n.typ which is a 'ref T' by a 'var T' type.
# Replace nkDerefExpr by nkHiddenDeref
# nkDeref is for 'ref T': x[].field
@@ -400,7 +400,9 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym): PSym =
# result =
result = copySym(orig)
result.info = info
result.flags.incl sfFromGeneric
result.owner = orig
let origParamType = orig.typ[1]
let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs))
let oldParam = orig.typ.n[1].sym
@@ -477,7 +479,12 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
if n[^1].kind == nkSym and n[^1].sym.kind notin {skProc, skFunc}:
localError(c.config, n.info, "finalizer must be a direct reference to a proc")
elif optTinyRtti in c.config.globalOptions:
bindTypeHook(c, turnFinalizerIntoDestructor(c, n[^1].sym), n, attachedDestructor)
# check if we converted this finalizer into a destructor already:
let t = whereToBindTypeHook(c, n[^1].sym.typ[1].skipTypes(abstractInst+{tyRef}))
if t != nil and t.attachedOps[attachedDestructor] != nil and t.attachedOps[attachedDestructor].owner == n[^1].sym:
discard "already turned this one into a finalizer"
else:
bindTypeHook(c, turnFinalizerIntoDestructor(c, n[^1].sym, n.info), n, attachedDestructor)
result = n
of mDestroy:
result = n

View File

@@ -1603,6 +1603,15 @@ proc prevDestructor(c: PContext; prevOp: PSym; obj: PType; info: TLineInfo) =
msg.add "; previous declaration was here: " & (c.config $ prevOp.info)
localError(c.config, info, errGenerated, msg)
proc whereToBindTypeHook(c: PContext; t: PType): PType =
result = t
while true:
if result.kind in {tyGenericBody, tyGenericInst}: result = result.lastSon
elif result.kind == tyGenericInvocation: result = result[0]
else: break
if result.kind in {tyObject, tyDistinct, tySequence, tyString}:
result = canonType(c, result)
proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) =
let t = s.typ
var noError = false

View File

@@ -1,6 +1,7 @@
discard """
cmd: "nim c --gc:arc $file"
output: '''Foo(field: "Dick Laurent", k: ka, x: 0.0)
Nobody is dead
Dick Laurent is dead'''
"""
@@ -23,3 +24,8 @@ x.field = "Dick Laurent"
# reference to a great movie. If you haven't seen it, highly recommended.
echo repr x
# bug #13112: bind the same finalizer multiple times:
var xx: Foo
new(xx, finalizer)
xx.field = "Nobody"