honor --declaredLocs in more places, including type mismatch errors; also show kind with --declaredLocs (#15673)
* honor --declaredLocs in more places, including type mismatch errors * fix tests * show declaration location also when type mismatch names clash
This commit is contained in:
parent
218acfe367
commit
0fb878324e
7 changed files with 40 additions and 24 deletions
|
|
@ -154,12 +154,14 @@ type
|
||||||
scope*: PScope
|
scope*: PScope
|
||||||
inSymChoice: IntSet
|
inSymChoice: IntSet
|
||||||
|
|
||||||
proc getSymRepr*(conf: ConfigRef; s: PSym): string =
|
proc getSymRepr*(conf: ConfigRef; s: PSym, getDeclarationPath = true): string =
|
||||||
case s.kind
|
case s.kind
|
||||||
of routineKinds, skType:
|
of routineKinds, skType:
|
||||||
result = getProcHeader(conf, s)
|
result = getProcHeader(conf, s, getDeclarationPath = getDeclarationPath)
|
||||||
else:
|
else:
|
||||||
result = s.name.s
|
result = "'$1'" % s.name.s
|
||||||
|
if getDeclarationPath:
|
||||||
|
result.addDeclaredLoc(conf, s)
|
||||||
|
|
||||||
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
|
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
|
||||||
# check if all symbols have been used and defined:
|
# check if all symbols have been used and defined:
|
||||||
|
|
@ -172,7 +174,7 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
|
||||||
# and slow 'suggest' down:
|
# and slow 'suggest' down:
|
||||||
if missingImpls == 0:
|
if missingImpls == 0:
|
||||||
localError(c.config, s.info, "implementation of '$1' expected" %
|
localError(c.config, s.info, "implementation of '$1' expected" %
|
||||||
getSymRepr(c.config, s))
|
getSymRepr(c.config, s, getDeclarationPath=false))
|
||||||
inc missingImpls
|
inc missingImpls
|
||||||
elif {sfUsed, sfExported} * s.flags == {}:
|
elif {sfUsed, sfExported} * s.flags == {}:
|
||||||
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam, skEnumField}:
|
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam, skEnumField}:
|
||||||
|
|
|
||||||
|
|
@ -231,8 +231,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
|
||||||
doAssert err.firstMismatch.formal != nil
|
doAssert err.firstMismatch.formal != nil
|
||||||
candidates.add("\n required type for " & nameParam & ": ")
|
candidates.add("\n required type for " & nameParam & ": ")
|
||||||
candidates.add typeToString(wanted)
|
candidates.add typeToString(wanted)
|
||||||
if wanted.sym != nil:
|
candidates.addDeclaredLocMaybe(c.config, wanted)
|
||||||
candidates.addDeclaredLocMaybe(c.config, wanted.sym)
|
|
||||||
candidates.add "\n but expression '"
|
candidates.add "\n but expression '"
|
||||||
if err.firstMismatch.kind == kVarNeeded:
|
if err.firstMismatch.kind == kVarNeeded:
|
||||||
candidates.add renderNotLValue(nArg)
|
candidates.add renderNotLValue(nArg)
|
||||||
|
|
@ -242,9 +241,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
|
||||||
candidates.add "' is of type: "
|
candidates.add "' is of type: "
|
||||||
var got = nArg.typ
|
var got = nArg.typ
|
||||||
candidates.add typeToString(got)
|
candidates.add typeToString(got)
|
||||||
if got.sym != nil:
|
candidates.addDeclaredLocMaybe(c.config, got)
|
||||||
candidates.addDeclaredLocMaybe(c.config, got.sym)
|
|
||||||
|
|
||||||
doAssert wanted != nil
|
doAssert wanted != nil
|
||||||
if got != nil: effectProblem(wanted, got, candidates, c)
|
if got != nil: effectProblem(wanted, got, candidates, c)
|
||||||
of kUnknown: discard "do not break 'nim check'"
|
of kUnknown: discard "do not break 'nim check'"
|
||||||
|
|
@ -320,7 +317,7 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string =
|
||||||
var o: TOverloadIter
|
var o: TOverloadIter
|
||||||
var sym = initOverloadIter(o, c, f)
|
var sym = initOverloadIter(o, c, f)
|
||||||
while sym != nil:
|
while sym != nil:
|
||||||
result &= "\n found '$1' of kind '$2'" % [getSymRepr(c.config, sym), sym.kind.toHumanStr]
|
result &= "\n found $1" % [getSymRepr(c.config, sym)]
|
||||||
sym = nextOverloadIter(o, c, f)
|
sym = nextOverloadIter(o, c, f)
|
||||||
|
|
||||||
let ident = considerQuotedIdent(c, f, n).s
|
let ident = considerQuotedIdent(c, f, n).s
|
||||||
|
|
|
||||||
|
|
@ -966,8 +966,9 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# t.kind != tySequence(It is tyProc)
|
# t.kind != tySequence(It is tyProc)
|
||||||
if typ.sym != nil and sfAnon notin typ.sym.flags and
|
if typ.sym != nil and sfAnon notin typ.sym.flags and
|
||||||
typ.kind == tyProc:
|
typ.kind == tyProc:
|
||||||
msg.add(" = " &
|
# when can `typ.sym != nil` ever happen?
|
||||||
typeToString(typ, preferDesc))
|
msg.add(" = " & typeToString(typ, preferDesc))
|
||||||
|
msg.addDeclaredLocMaybe(c.config, typ)
|
||||||
localError(c.config, n.info, msg)
|
localError(c.config, n.info, msg)
|
||||||
return errorNode(c, n)
|
return errorNode(c, n)
|
||||||
result = nil
|
result = nil
|
||||||
|
|
|
||||||
|
|
@ -124,13 +124,22 @@ proc isFloatLit*(t: PType): bool {.inline.} =
|
||||||
result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
|
result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
|
||||||
|
|
||||||
proc addDeclaredLoc*(result: var string, conf: ConfigRef; sym: PSym) =
|
proc addDeclaredLoc*(result: var string, conf: ConfigRef; sym: PSym) =
|
||||||
# result.add " [declared in " & conf$sym.info & "]"
|
result.add " [$1 declared in $2]" % [sym.kind.toHumanStr, toFileLineCol(conf, sym.info)]
|
||||||
result.add " [declared in " & toFileLineCol(conf, sym.info) & "]"
|
|
||||||
|
|
||||||
proc addDeclaredLocMaybe*(result: var string, conf: ConfigRef; sym: PSym) =
|
proc addDeclaredLocMaybe*(result: var string, conf: ConfigRef; sym: PSym) =
|
||||||
if optDeclaredLocs in conf.globalOptions:
|
if optDeclaredLocs in conf.globalOptions and sym != nil:
|
||||||
addDeclaredLoc(result, conf, sym)
|
addDeclaredLoc(result, conf, sym)
|
||||||
|
|
||||||
|
proc addDeclaredLoc(result: var string, conf: ConfigRef; typ: PType) =
|
||||||
|
let typ = typ.skipTypes(abstractInst - {tyRange})
|
||||||
|
result.add " [$1" % typ.kind.toHumanStr
|
||||||
|
if typ.sym != nil:
|
||||||
|
result.add " declared in " & toFileLineCol(conf, typ.sym.info)
|
||||||
|
result.add "]"
|
||||||
|
|
||||||
|
proc addDeclaredLocMaybe*(result: var string, conf: ConfigRef; typ: PType) =
|
||||||
|
if optDeclaredLocs in conf.globalOptions: addDeclaredLoc(result, conf, typ)
|
||||||
|
|
||||||
proc addTypeHeader*(result: var string, conf: ConfigRef; typ: PType; prefer: TPreferedDesc = preferMixed; getDeclarationPath = true) =
|
proc addTypeHeader*(result: var string, conf: ConfigRef; typ: PType; prefer: TPreferedDesc = preferMixed; getDeclarationPath = true) =
|
||||||
result.add typeToString(typ, prefer)
|
result.add typeToString(typ, prefer)
|
||||||
if getDeclarationPath: result.addDeclaredLoc(conf, typ.sym)
|
if getDeclarationPath: result.addDeclaredLoc(conf, typ.sym)
|
||||||
|
|
@ -1473,12 +1482,19 @@ proc skipHiddenSubConv*(n: PNode; idgen: IdGenerator): PNode =
|
||||||
|
|
||||||
proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType) =
|
proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType) =
|
||||||
if formal.kind != tyError and actual.kind != tyError:
|
if formal.kind != tyError and actual.kind != tyError:
|
||||||
let named = typeToString(formal)
|
let actualStr = typeToString(actual)
|
||||||
|
let formalStr = typeToString(formal)
|
||||||
let desc = typeToString(formal, preferDesc)
|
let desc = typeToString(formal, preferDesc)
|
||||||
let x = if named == desc: named else: named & " = " & desc
|
let x = if formalStr == desc: formalStr else: formalStr & " = " & desc
|
||||||
var msg = "type mismatch: got <" &
|
let verbose = actualStr == formalStr or optDeclaredLocs in conf.globalOptions
|
||||||
typeToString(actual) & "> " &
|
var msg = "type mismatch:"
|
||||||
"but expected '" & x & "'"
|
if verbose: msg.add "\n"
|
||||||
|
msg.add " got <$1>" % actualStr
|
||||||
|
if verbose:
|
||||||
|
msg.addDeclaredLoc(conf, actual)
|
||||||
|
msg.add "\n"
|
||||||
|
msg.add " but expected '$1'" % x
|
||||||
|
if verbose: msg.addDeclaredLoc(conf, formal)
|
||||||
|
|
||||||
if formal.kind == tyProc and actual.kind == tyProc:
|
if formal.kind == tyProc and actual.kind == tyProc:
|
||||||
case compatibleEffects(formal, actual)
|
case compatibleEffects(formal, actual)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ discard """
|
||||||
cmd: "nim check $options $file"
|
cmd: "nim check $options $file"
|
||||||
errormsg: ""
|
errormsg: ""
|
||||||
nimout: '''
|
nimout: '''
|
||||||
t8794.nim(39, 27) Error: undeclared field: 'a3' for type m8794.Foo3 [declared in m8794.nim(1, 6)]
|
t8794.nim(39, 27) Error: undeclared field: 'a3' for type m8794.Foo3 [type declared in m8794.nim(1, 6)]
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ discard """
|
||||||
cmd: '''nim c --hints:off $file'''
|
cmd: '''nim c --hints:off $file'''
|
||||||
errormsg: "attempting to call routine: 'myiter'"
|
errormsg: "attempting to call routine: 'myiter'"
|
||||||
nimout: '''undeclared_routime.nim(13, 15) Error: attempting to call routine: 'myiter'
|
nimout: '''undeclared_routime.nim(13, 15) Error: attempting to call routine: 'myiter'
|
||||||
found 'undeclared_routime.myiter(a: string)[declared in undeclared_routime.nim(10, 9)]' of kind 'iterator'
|
found 'undeclared_routime.myiter(a: string)[iterator declared in undeclared_routime.nim(10, 9)]'
|
||||||
found 'undeclared_routime.myiter()[declared in undeclared_routime.nim(11, 9)]' of kind 'iterator'
|
found 'undeclared_routime.myiter()[iterator declared in undeclared_routime.nim(11, 9)]'
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
nimout: '''
|
nimout: '''
|
||||||
found 'a' of kind 'var'
|
found 'a' [var declared in tnoop.nim(11, 3)]
|
||||||
'''
|
'''
|
||||||
file: "tnoop.nim"
|
file: "tnoop.nim"
|
||||||
line: 13
|
line: 13
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue