properly fix #10053 ; FieldDefect msg now shows discriminant value + lineinfo, in all backends (c,vm,js) (#11955)

* fix #10053 FieldError for vm

* fixup

* FieldError now also shows runtime value of discriminant

* fix field error reporting in vm

* also report culprit line info in err msg

* fix errors for newruntime 2

* fix for js

* fixup

* PRTEMP4

* works

* works

* works perfect

* refactor

* std/private/repr_impl

* suppport --gc:arc

* cleanup

* refactor

* simplify

* simplify

* simplify

* fixup

* move out compiler.vmgen.genCustom

* fixup

* fixup

* add tests

* revert compiler/debugutils.nim

* simplify reprDiscriminant

* fixup

* lib/std/private/repr_impl.nim -> lib/system/repr_impl.nim

* try to fix D20210812T165220

* honor --declaredlocs

* control toFileLineCol via --declaredlocs
This commit is contained in:
Timothee Cour 2021-08-13 00:35:48 -07:00 • committed by GitHub
commit b24812df5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 151 additions and 43 deletions

View file

@ -26,8 +26,18 @@ proc raiseIndexError() {.compilerproc, noinline.} =
sysFatal(IndexDefect, "index out of bounds")
proc raiseFieldError(f: string) {.compilerproc, noinline.} =
## remove after bootstrap > 1.5.1
sysFatal(FieldDefect, f)
when defined(gcdestructors):
proc raiseFieldError2(f: string, discVal: int) {.compilerproc, noinline.} =
## raised when field is inaccessible given runtime value of discriminant
sysFatal(FieldError, f & $discVal & "'")
else:
proc raiseFieldError2(f: string, discVal: string) {.compilerproc, noinline.} =
## raised when field is inaccessible given runtime value of discriminant
sysFatal(FieldError, formatFieldDefect(f, discVal))
proc raiseRangeErrorI(i, a, b: BiggestInt) {.compilerproc, noinline.} =
when defined(standalone):
sysFatal(RangeDefect, "value out of range")

View file

@ -1,4 +1,5 @@
# imported by other modules, unlike helpers.nim which is included
# xxx this is now included instead of imported, we should import instead
template formatErrorIndexBound*[T](i, a, b: T): string =
when defined(standalone):
@ -9,3 +10,6 @@ template formatErrorIndexBound*[T](i, a, b: T): string =
template formatErrorIndexBound*[T](i, n: T): string =
formatErrorIndexBound(i, 0, n)
template formatFieldDefect*(f, discVal): string =
f & discVal & "'"

View file

@ -171,8 +171,8 @@ proc raiseRangeError() {.compilerproc, noreturn.} =
proc raiseIndexError(i, a, b: int) {.compilerproc, noreturn.} =
raise newException(IndexDefect, formatErrorIndexBound(int(i), int(a), int(b)))
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(FieldDefect, f)
proc raiseFieldError2(f: string, discVal: string) {.compilerproc, noreturn.} =
raise newException(FieldDefect, formatFieldDefect(f, discVal))
proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} =
asm """

View file

@ -72,6 +72,8 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
result = $e & " (invalid data!)"
include system/repr_impl
type
PByteArray = ptr UncheckedArray[byte] # array[0xffff, byte]

15
lib/system/repr_impl.nim Normal file
View file

@ -0,0 +1,15 @@
#[
other APIs common to system/repr and system/reprjs could be refactored here, eg:
* reprChar
* reprBool
* reprStr
Another possibility in future work would be to have a single include file instead
of system/repr and system/reprjs, and use `when defined(js)` inside it.
]#
proc reprDiscriminant*(e: int, typ: PNimType): string {.compilerRtl.} =
case typ.kind
of tyEnum: reprEnum(e, typ)
of tyBool: $(e != 0)
else: $e

View file

@ -1,3 +1,5 @@
include system/inclrtl
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
## imported from typetraits
@ -66,6 +68,11 @@ proc repr*[Enum: enum](x: Enum): string {.magic: "EnumToStr", noSideEffect.}
## If a `repr` operator for a concrete enumeration is provided, this is
## used instead. (In other words: *Overwriting* is possible.)
proc reprDiscriminant*(e: int): string {.compilerproc.} =
# repr and reprjs can use `PNimType` to symbolize `e`; making this work here
# would require a way to pass the set of enum stringified values to cgen.
$e
proc repr*(p: pointer): string =
## repr of pointer as its hexadecimal value
if p == nil:

View file

@ -30,6 +30,8 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
else:
result = $e & " (invalid data!)"
include system/repr_impl
proc reprChar(x: char): string {.compilerRtl.} =
result = "\'"
case x