mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-08 04:44:20 +00:00
* fixes #8794 : `Error: undeclared field: 'foo'` should show type (+ where type is defined) (hard to guess in generic code) * fixes #9270: `--listFullPaths` not honored by `declared in foo.nim` messages * fixes #9767: VM stacktrace doesn't honor --excessiveStackTrace:on * fixes #9768: VM stacktrace misses column info, can lead to ambiguous or harder to read stacktraces * refactors some col+1 code to col + ColOffset (self documents code) * make getProcHeader show declared info location also for types and all routine kinds (including macros,templates) instead of just (rather arbitrarily) for iterator,proc,func,method * --listFullPaths now is honored in more places * fix typo system/except.nim => lib/system/excpt.nim * remove substr(foo, 0) hack in compiler/vm.nim which seems old and not applicable anymore
This commit is contained in:
@@ -150,7 +150,7 @@ type
|
||||
|
||||
proc getSymRepr*(conf: ConfigRef; s: PSym): string =
|
||||
case s.kind
|
||||
of skProc, skFunc, skMethod, skConverter, skIterator:
|
||||
of routineKinds, skType:
|
||||
result = getProcHeader(conf, s)
|
||||
else:
|
||||
result = s.name.s
|
||||
|
||||
@@ -135,6 +135,10 @@ const
|
||||
WarningColor = fgYellow
|
||||
HintTitle = "Hint: "
|
||||
HintColor = fgGreen
|
||||
# NOTE: currently line info line numbers start with 1,
|
||||
# but column numbers start with 0, however most editors expect
|
||||
# first column to be 1, so we need to +1 here
|
||||
ColOffset* = 1
|
||||
|
||||
proc getInfoContextLen*(conf: ConfigRef): int = return conf.m.msgContext.len
|
||||
proc setInfoContextLen*(conf: ConfigRef; L: int) = setLen(conf.m.msgContext, L)
|
||||
@@ -155,7 +159,10 @@ template toFilename*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||
if fileIdx.int32 < 0 or conf == nil:
|
||||
"???"
|
||||
else:
|
||||
conf.m.fileInfos[fileIdx.int32].projPath.string
|
||||
if optListFullPaths in conf.globalOptions:
|
||||
conf.m.fileInfos[fileIdx.int32].fullPath.string
|
||||
else:
|
||||
conf.m.fileInfos[fileIdx.int32].projPath.string
|
||||
|
||||
proc toFullPath*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||
if fileIdx.int32 < 0 or conf == nil: result = "???"
|
||||
@@ -192,10 +199,10 @@ proc toMsgFilename*(conf: ConfigRef; info: TLineInfo): string =
|
||||
result = "???"
|
||||
return
|
||||
let absPath = conf.m.fileInfos[info.fileIndex.int32].fullPath.string
|
||||
let relPath = conf.m.fileInfos[info.fileIndex.int32].projPath.string
|
||||
if optListFullPaths in conf.globalOptions:
|
||||
result = absPath
|
||||
else:
|
||||
let relPath = conf.m.fileInfos[info.fileIndex.int32].projPath.string
|
||||
result = if absPath.len < relPath.len: absPath else: relPath
|
||||
|
||||
proc toLinenumber*(info: TLineInfo): int {.inline.} =
|
||||
@@ -208,7 +215,9 @@ proc toFileLine*(conf: ConfigRef; info: TLineInfo): string {.inline.} =
|
||||
result = toFilename(conf, info) & ":" & $info.line
|
||||
|
||||
proc toFileLineCol*(conf: ConfigRef; info: TLineInfo): string {.inline.} =
|
||||
result = toFilename(conf, info) & "(" & $info.line & ", " & $(info.col+1) & ")"
|
||||
# consider calling `helpers.lineInfoToString` instead
|
||||
result = toFilename(conf, info) & "(" & $info.line & ", " &
|
||||
$(info.col + ColOffset) & ")"
|
||||
|
||||
proc `$`*(conf: ConfigRef; info: TLineInfo): string = toFileLineCol(conf, info)
|
||||
|
||||
@@ -359,7 +368,7 @@ proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) =
|
||||
styledMsgWriteln(styleBright,
|
||||
PosFormat % [toMsgFilename(conf, context.info),
|
||||
coordToStr(context.info.line.int),
|
||||
coordToStr(context.info.col+1)],
|
||||
coordToStr(context.info.col+ColOffset)],
|
||||
resetStyle,
|
||||
message)
|
||||
info = context.info
|
||||
@@ -446,7 +455,7 @@ proc formatMsg*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string): s
|
||||
of hintMin..hintMax: HintTitle
|
||||
else: ErrorTitle
|
||||
result = PosFormat % [toMsgFilename(conf, info), coordToStr(info.line.int),
|
||||
coordToStr(info.col+1)] &
|
||||
coordToStr(info.col+ColOffset)] &
|
||||
title &
|
||||
getMessageStr(msg, arg)
|
||||
|
||||
@@ -483,11 +492,8 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
|
||||
color = HintColor
|
||||
if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)]
|
||||
inc(conf.hintCounter)
|
||||
# NOTE: currently line info line numbers start with 1,
|
||||
# but column numbers start with 0, however most editors expect
|
||||
# first column to be 1, so we need to +1 here
|
||||
let x = PosFormat % [toMsgFilename(conf, info), coordToStr(info.line.int),
|
||||
coordToStr(info.col+1)]
|
||||
coordToStr(info.col+ColOffset)]
|
||||
let s = getMessageStr(msg, arg)
|
||||
|
||||
if not ignoreMsg:
|
||||
|
||||
@@ -78,7 +78,7 @@ type # please make sure we have under 32 options
|
||||
optShowAllMismatches # show all overloading resolution candidates
|
||||
optWholeProject # for 'doc2': output any dependency
|
||||
optMixedMode # true if some module triggered C++ codegen
|
||||
optListFullPaths
|
||||
optListFullPaths # use full paths in toMsgFilename, toFilename
|
||||
optNoNimblePath
|
||||
optDynlibOverrideAll
|
||||
|
||||
|
||||
@@ -287,7 +287,20 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string =
|
||||
|
||||
let ident = considerQuotedIdent(c, f, n).s
|
||||
if nfDotField in n.flags and nfExplicitCall notin n.flags:
|
||||
result = errUndeclaredField % ident & result
|
||||
let sym = n.sons[1].typ.sym
|
||||
var typeHint = ""
|
||||
if sym == nil:
|
||||
#[
|
||||
Perhaps we're in a `compiles(foo.bar)` expression, or
|
||||
in a concept, eg:
|
||||
ExplainedConcept {.explain.} = concept o
|
||||
o.foo is int
|
||||
We coudl use: `(c.config $ n.sons[1].info)` to get more context.
|
||||
]#
|
||||
discard
|
||||
else:
|
||||
typeHint = " for type " & getProcHeader(c.config, sym)
|
||||
result = errUndeclaredField % ident & typeHint & " " & result
|
||||
else:
|
||||
if result.len == 0: result = errUndeclaredRoutine % ident
|
||||
else: result = errBadRoutine % [ident, result]
|
||||
|
||||
@@ -107,20 +107,23 @@ proc isFloatLit*(t: PType): bool {.inline.} =
|
||||
result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
|
||||
|
||||
proc getProcHeader*(conf: ConfigRef; sym: PSym; prefer: TPreferedDesc = preferName): string =
|
||||
result = sym.owner.name.s & '.' & sym.name.s & '('
|
||||
var n = sym.typ.n
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
let p = n.sons[i]
|
||||
if p.kind == nkSym:
|
||||
add(result, p.sym.name.s)
|
||||
add(result, ": ")
|
||||
add(result, typeToString(p.sym.typ, prefer))
|
||||
if i != sonsLen(n)-1: add(result, ", ")
|
||||
else:
|
||||
result.add renderTree(p)
|
||||
add(result, ')')
|
||||
if n.sons[0].typ != nil:
|
||||
result.add(": " & typeToString(n.sons[0].typ, prefer))
|
||||
assert sym != nil
|
||||
result = sym.owner.name.s & '.' & sym.name.s
|
||||
if sym.kind in routineKinds:
|
||||
result.add '('
|
||||
var n = sym.typ.n
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
let p = n.sons[i]
|
||||
if p.kind == nkSym:
|
||||
add(result, p.sym.name.s)
|
||||
add(result, ": ")
|
||||
add(result, typeToString(p.sym.typ, prefer))
|
||||
if i != sonsLen(n)-1: add(result, ", ")
|
||||
else:
|
||||
result.add renderTree(p)
|
||||
add(result, ')')
|
||||
if n.sons[0].typ != nil:
|
||||
result.add(": " & typeToString(n.sons[0].typ, prefer))
|
||||
result.add "[declared in "
|
||||
result.add(conf$sym.info)
|
||||
result.add "]"
|
||||
|
||||
@@ -65,15 +65,20 @@ proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int; recursionLimit=100) =
|
||||
return
|
||||
stackTraceAux(c, x.next, x.comesFrom, recursionLimit-1)
|
||||
var info = c.debug[pc]
|
||||
# we now use the same format as in system/except.nim
|
||||
var s = substr(toFilename(c.config, info), 0)
|
||||
# this 'substr' prevents a strange corruption. XXX This needs to be
|
||||
# investigated eventually but first attempts to fix it broke everything
|
||||
# see the araq-wip-fixed-writebarrier branch.
|
||||
# we now use a format similar to the one in lib/system/excpt.nim
|
||||
var s = ""
|
||||
# todo: factor with quotedFilename
|
||||
if optExcessiveStackTrace in c.config.globalOptions:
|
||||
s = toFullPath(c.config, info)
|
||||
else:
|
||||
s = toFilename(c.config, info)
|
||||
var line = toLinenumber(info)
|
||||
var col = toColumn(info)
|
||||
if line > 0:
|
||||
add(s, '(')
|
||||
add(s, $line)
|
||||
add(s, ", ")
|
||||
add(s, $(col + ColOffset))
|
||||
add(s, ')')
|
||||
if x.prc != nil:
|
||||
for k in 1..max(1, 25-s.len): add(s, ' ')
|
||||
|
||||
2
tests/errmsgs/m8794.nim
Normal file
2
tests/errmsgs/m8794.nim
Normal file
@@ -0,0 +1,2 @@
|
||||
type Foo3* = object
|
||||
a1: int
|
||||
39
tests/errmsgs/t8794.nim
Normal file
39
tests/errmsgs/t8794.nim
Normal file
@@ -0,0 +1,39 @@
|
||||
discard """
|
||||
cmd: "nim check $options $file"
|
||||
errormsg: ""
|
||||
nimout: '''
|
||||
t8794.nim(39, 27) Error: undeclared field: 'a3' for type m8794.Foo3[declared in m8794.nim(1, 6)]
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## line 20
|
||||
|
||||
## issue #8794
|
||||
|
||||
import m8794
|
||||
|
||||
when false: # pending https://github.com/nim-lang/Nim/pull/10091 add this
|
||||
type Foo = object
|
||||
a1: int
|
||||
|
||||
discard Foo().a2
|
||||
|
||||
type Foo3b = Foo3
|
||||
var x2: Foo3b
|
||||
|
||||
proc getFun[T](): T =
|
||||
var a: T
|
||||
a
|
||||
|
||||
discard getFun[type(x2)]().a3
|
||||
30
tests/errmsgs/t9768.nim
Normal file
30
tests/errmsgs/t9768.nim
Normal file
@@ -0,0 +1,30 @@
|
||||
discard """
|
||||
errmsg: "unhandled exception:"
|
||||
file: "system.nim"
|
||||
nimout: '''
|
||||
stack trace: (most recent call last)
|
||||
t9768.nim(28, 33) main
|
||||
t9768.nim(23, 11) foo1
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## line 20
|
||||
|
||||
proc foo1(a: int): auto =
|
||||
doAssert a < 4
|
||||
result = a * 2
|
||||
|
||||
proc main()=
|
||||
static:
|
||||
if foo1(1) > 0: discard foo1(foo1(2))
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user