* improve line error information

* fixes #13112
This commit is contained in:
Andreas Rumpf 2020-01-13 15:47:17 +01:00 • committed by GitHub
commit eadd1ba9ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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): # little hack for injectdestructors.nim (see bug #11350):
#result[0].typ = nil #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. # We need to do 2 things: Replace n.typ which is a 'ref T' by a 'var T' type.
# Replace nkDerefExpr by nkHiddenDeref # Replace nkDerefExpr by nkHiddenDeref
# nkDeref is for 'ref T': x[].field # nkDeref is for 'ref T': x[].field
@ -400,7 +400,9 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym): PSym =
# result = # result =
result = copySym(orig) result = copySym(orig)
result.info = info
result.flags.incl sfFromGeneric result.flags.incl sfFromGeneric
result.owner = orig
let origParamType = orig.typ[1] let origParamType = orig.typ[1]
let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs)) let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs))
let oldParam = orig.typ.n[1].sym 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}: 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") localError(c.config, n.info, "finalizer must be a direct reference to a proc")
elif optTinyRtti in c.config.globalOptions: 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 result = n
of mDestroy: of mDestroy:
result = n 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) msg.add "; previous declaration was here: " & (c.config $ prevOp.info)
localError(c.config, info, errGenerated, msg) 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) = proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) =
let t = s.typ let t = s.typ
var noError = false var noError = false

View file

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