From a2d17a3deb71a068fe0b24184e1860b7b93cf27d Mon Sep 17 00:00:00 2001 From: tandy Date: Wed, 26 Jan 2022 13:19:55 +0000 Subject: [PATCH] cli_reporter / typesrenderer refactor Small refactor moving all leftover string formatting for P(Node|Sym|Type) from types.nim to typesrenderer.nim. Removed some dead code, cleaned up some imports, reshuffled some consts & procs. String formatting / rendering procs should not be in types.nim, and this should be fixed by this PR. --- compiler/ast/reports.nim | 1 - compiler/ast/types.nim | 320 ----------------------------- compiler/ast/typesrenderer.nim | 305 ++++++++++++++++++++++++++- compiler/backend/cgen.nim | 3 +- compiler/front/cli_reporter.nim | 64 ++++++ compiler/sem/injectdestructors.nim | 1 + compiler/sem/semmacrosanity.nim | 1 + compiler/sem/semmagic.nim | 2 + compiler/sem/semobjconstr.nim | 2 - compiler/sem/sigmatch.nim | 1 + compiler/tools/docgen.nim | 1 - compiler/utils/debugutils.nim | 29 +++ compiler/vm/vm.nim | 1 + 13 files changed, 403 insertions(+), 328 deletions(-) diff --git a/compiler/ast/reports.nim b/compiler/ast/reports.nim index 8a32d1472e4..b70f79566aa 100644 --- a/compiler/ast/reports.nim +++ b/compiler/ast/reports.nim @@ -1136,7 +1136,6 @@ type SemTypeMismatch* = object formalTypeKind*: set[TTypeKind] actualType*, formalType*: PType - descriptionStr*: string SemCallMismatch* = object ## Description of the single candidate mismatch. This type is later diff --git a/compiler/ast/types.nim b/compiler/ast/types.nim index 8b063bb78e3..ef6a6b94d49 100644 --- a/compiler/ast/types.nim +++ b/compiler/ast/types.nim @@ -20,7 +20,6 @@ import trees, renderer, lineinfos, - astmsgs, errorhandling, reports ], @@ -51,17 +50,6 @@ type # most useful, shows: symbol + resolved symbols if it differs, e.g.: # tuple[a: MyInt{int}, b: float] -proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string - -proc addTypeDeclVerboseMaybe*(result: var string, conf: ConfigRef; typ: PType) = - if optDeclaredLocs in conf.globalOptions: - result.add typeToString(typ, preferMixed) - result.addDeclaredLoc(conf, typ) - else: - result.add typeToString(typ) - -template `$`*(typ: PType): string = typeToString(typ) - proc base*(t: PType): PType = result = t[0] @@ -153,32 +141,6 @@ proc isIntLit*(t: PType): bool {.inline.} = proc isFloatLit*(t: PType): bool {.inline.} = result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit -proc addTypeHeader*(result: var string, conf: ConfigRef; typ: PType; prefer: TPreferedDesc = preferMixed; getDeclarationPath = true) = - result.add typeToString(typ, prefer) - if getDeclarationPath: result.addDeclaredLoc(conf, typ.sym) - -proc getProcHeader*( - conf: ConfigRef; sym: PSym; prefer: TPreferedDesc = preferName; getDeclarationPath = true): string = - assert sym != nil - # consider using `skipGenericOwner` to avoid fun2.fun2 when fun2 is generic - result = sym.owner.name.s & '.' & sym.name.s - if sym.kind in routineKinds: - result.add '(' - var n = sym.typ.n - for i in 1..typedesc: typedesc is declared as such, and is 10x more common. - "GenericInvocation", "GenericBody", "GenericInst", "GenericParam", - "distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple", - "set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc", - "pointer", "OpenArray[$1]", "string", "cstring", "Forward", - "int", "int8", "int16", "int32", "int64", - "float", "float32", "float64", "float128", - "uint", "uint8", "uint16", "uint32", "uint64", - "owned", "sink", - "lent ", "varargs[$1]", "UncheckedArray[$1]", "Error Type", - "BuiltInTypeClass", "UserTypeClass", - "UserTypeClassInst", "CompositeTypeClass", "inferred", - "and", "or", "not", "any", "static", "TypeFromExpr", "concept", # xxx bugfix - "void", "iterable"] - -const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo, - preferGenericArg, preferResolved, preferMixed} - template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) = tc.add concrete tc.flags.incl tfResolved @@ -494,255 +424,6 @@ template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) = template isResolvedUserTypeClass*(t: PType): bool = tfResolved in t.flags -proc addTypeFlags(name: var string, typ: PType) {.inline.} = - if tfNotNil in typ.flags: name.add(" not nil") - -proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = - let preferToplevel = prefer - proc getPrefer(prefer: TPreferedDesc): TPreferedDesc = - if preferToplevel in {preferResolved, preferMixed}: - preferToplevel # sticky option - else: - prefer - - proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = - result = "" - let prefer = getPrefer(prefer) - let t = typ - if t == nil: return - if prefer in preferToResolveSymbols and t.sym != nil and - sfAnon notin t.sym.flags and t.kind != tySequence: - if t.kind == tyInt and isIntLit(t): - result = t.sym.name.s & " literal(" & $t.n.intVal & ")" - elif t.kind == tyAlias and t[0].kind != tyAlias: - result = typeToString(t[0]) - elif prefer in {preferResolved, preferMixed}: - case t.kind - of IntegralTypes + {tyFloat..tyFloat128} + {tyString, tyCstring}: - result = typeToStr[t.kind] - of tyGenericBody: - result = typeToString(t.lastSon) - of tyCompositeTypeClass: - # avoids showing `A[any]` in `proc fun(a: A)` with `A = object[T]` - result = typeToString(t.lastSon.lastSon) - else: - result = t.sym.name.s - if prefer == preferMixed and result != t.sym.name.s: - result = t.sym.name.s & "{" & result & "}" - elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil: - # note: should probably be: {preferName, preferTypeName, preferGenericArg} - result = t.sym.name.s - if t.kind == tyGenericParam and t.len > 0: - result.add ": " - var first = true - for son in t.sons: - if not first: result.add " or " - result.add son.typeToString - first = false - else: - result = t.sym.owner.name.s & '.' & t.sym.name.s - result.addTypeFlags(t) - return - case t.kind - of tyInt: - if not isIntLit(t) or prefer == preferExported: - result = typeToStr[t.kind] - else: - if prefer == preferGenericArg: - result = $t.n.intVal - else: - result = "int literal(" & $t.n.intVal & ")" - of tyGenericInst, tyGenericInvocation: - result = typeToString(t[0]) & '[' - for i in 1.. 1: result.add(", ") - result.add(typeToString(t[i], preferGenericArg)) - result.add(']') - of tyGenericBody: - result = typeToString(t.lastSon) & '[' - for i in 0.. 0: result.add(", ") - result.add(typeToString(t[i], preferTypeName)) - result.add(']') - of tyTypeDesc: - if t[0].kind == tyNone: result = "typedesc" - else: result = "typedesc[" & typeToString(t[0]) & "]" - of tyStatic: - if prefer == preferGenericArg and t.n != nil: - result = t.n.renderTree - else: - result = "static[" & (if t.len > 0: typeToString(t[0]) else: "") & "]" - if t.n != nil: result.add "(" & renderTree(t.n) & ")" - of tyUserTypeClass: - if t.sym != nil and t.sym.owner != nil: - if t.isResolvedUserTypeClass: return typeToString(t.lastSon) - return t.sym.owner.name.s - else: - result = "" - of tyBuiltInTypeClass: - result = case t.base.kind - of tyVar: "var" - of tyRef: "ref" - of tyPtr: "ptr" - of tySequence: "seq" - of tyArray: "array" - of tySet: "set" - of tyRange: "range" - of tyDistinct: "distinct" - of tyProc: "proc" - of tyObject: "object" - of tyTuple: "tuple" - of tyOpenArray: "openArray" - else: typeToStr[t.base.kind] - of tyInferred: - let concrete = t.previouslyInferred - if concrete != nil: result = typeToString(concrete) - else: result = "inferred[" & typeToString(t.base) & "]" - of tyUserTypeClassInst: - let body = t.base - result = body.sym.name.s & "[" - for i in 1.. 1: result.add(", ") - result.add(typeToString(t[i])) - result.add "]" - of tyAnd: - for i, son in t.sons: - result.add(typeToString(son)) - if i < t.sons.high: - result.add(" and ") - of tyOr: - for i, son in t.sons: - result.add(typeToString(son)) - if i < t.sons.high: - result.add(" or ") - of tyNot: - result = "not " & typeToString(t[0]) - of tyUntyped: - #internalAssert t.len == 0 - result = "untyped" - of tyFromExpr: - if t.n == nil: - result = "unknown" - else: - result = "typeof(" & renderTree(t.n) & ")" - of tyArray: - result = "array" - if t.len > 0: - if t[0].kind == tyRange: - result &= "[" & rangeToStr(t[0].n) & ", " & - typeToString(t[1]) & ']' - else: - result &= "[" & typeToString(t[0]) & ", " & - typeToString(t[1]) & ']' - of tyUncheckedArray: - result = "UncheckedArray" - if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' - of tySequence: - if t.sym != nil and prefer != preferResolved: - result = t.sym.name.s - else: - result = "seq" - if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' - of tyOrdinal: - result = "ordinal" - if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' - of tySet: - result = "set" - if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' - of tyOpenArray: - result = "openArray" - if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' - of tyDistinct: - result = "distinct " & typeToString(t[0], - if prefer == preferModuleInfo: preferModuleInfo else: preferTypeName) - of tyIterable: - # xxx factor this pattern - result = "iterable" - if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' - of tyTuple: - # we iterate over t.sons here, because t.n may be nil - if t.n != nil: - result = "tuple[" - assert(t.n.len == t.len) - for i in 0..= 2: - setLen(result, result.len-1) - result.add '[' - for i in 0.. 0 and t[0] != nil: result.add(": " & typeToString(t[0])) - var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: $t.callConv - if tfNoSideEffect in t.flags: - addSep(prag) - prag.add("noSideEffect") - if tfThread in t.flags: - addSep(prag) - prag.add("gcsafe") - if t.lockLevel.ord != UnspecifiedLockLevel.ord: - addSep(prag) - prag.add("locks: " & $t.lockLevel) - if prag.len != 0: result.add("{." & prag & ".}") - of tyVarargs: - result = typeToStr[t.kind] % typeToString(t[0]) - of tySink: - result = "sink " & typeToString(t[0]) - of tyOwned: - result = "owned " & typeToString(t[0]) - else: - result = typeToStr[t.kind] - result.addTypeFlags(t) - result = typeToString(typ, prefer) - proc firstOrd*(conf: ConfigRef; t: PType): Int128 = case t.kind of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: @@ -1583,7 +1264,6 @@ proc typeMismatch*( result = SemTypeMismatch( actualType: actual, formalType: formal, - descriptionStr: typeToString(formal, preferDesc) ) proc typeMismatch*( diff --git a/compiler/ast/typesrenderer.nim b/compiler/ast/typesrenderer.nim index 0da05d70d64..93b446ce96e 100644 --- a/compiler/ast/typesrenderer.nim +++ b/compiler/ast/typesrenderer.nim @@ -7,10 +7,22 @@ # distribution, for details about the copyright. # -import renderer, strutils, ast, types +import + std/strutils, + ast/[ + ast, + astmsgs, + renderer, + types, + ], + front/options const defaultParamSeparator* = "," +proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string + +template `$`*(typ: PType): string = typeToString(typ) + proc renderPlainSymbolName*(n: PNode): string = ## Returns the first non '*' nkIdent node from the tree. ## @@ -85,7 +97,6 @@ proc renderType(n: PNode): string = result.add(renderType(n[i])) else: result = "" - proc renderParamTypes(found: var seq[string], n: PNode) = ## Recursive helper, adds to `found` any types, or keeps diving the AST. ## @@ -123,3 +134,293 @@ proc renderParamTypes*(n: PNode, sep = defaultParamSeparator): string = renderParamTypes(found, n) if found.len > 0: result = found.join(sep) + +proc addTypeHeader*(result: var string, conf: ConfigRef; typ: PType; prefer: TPreferedDesc = preferMixed; getDeclarationPath = true) = + ## Calls `typeToString` on given `typ`. + ## If `getDeclarationPath` is true, it will add the declared location. + result.add typeToString(typ, prefer) + if getDeclarationPath: result.addDeclaredLoc(conf, typ.sym) + +proc valueToString(a: PNode): string = + ## Returns `int`, `float`, or `string` literals from the node, otherwise returns ``. + case a.kind + of nkCharLit..nkUInt64Lit: result = $a.intVal + of nkFloatLit..nkFloat128Lit: result = $a.floatVal + of nkStrLit..nkTripleStrLit: result = a.strVal + else: result = "" + +proc rangeToStr(n: PNode): string = + ## Encodes a range value for array types. + assert(n.kind == nkRange) + result = valueToString(n[0]) & ".." & valueToString(n[1]) + +const + preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo, + preferGenericArg, preferResolved, preferMixed} + typeToStr: array[TTypeKind, string] = ["None", "bool", "char", "empty", + "Alias", "typeof(nil)", "untyped", "typed", "typeDesc", + # xxx typeDesc=>typedesc: typedesc is declared as such, and is 10x more common. + "GenericInvocation", "GenericBody", "GenericInst", "GenericParam", + "distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple", + "set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc", + "pointer", "OpenArray[$1]", "string", "cstring", "Forward", + "int", "int8", "int16", "int32", "int64", + "float", "float32", "float64", "float128", + "uint", "uint8", "uint16", "uint32", "uint64", + "owned", "sink", + "lent ", "varargs[$1]", "UncheckedArray[$1]", "Error Type", + "BuiltInTypeClass", "UserTypeClass", + "UserTypeClassInst", "CompositeTypeClass", "inferred", + "and", "or", "not", "any", "static", "TypeFromExpr", "concept", # xxx bugfix + "void", "iterable"] + +proc addTypeFlags(name: var string, typ: PType) {.inline.} = + ## Adds " not nil" if tfNotNil is present + if tfNotNil in typ.flags: name.add(" not nil") + +proc typeToString*(typ: PType, prefer: TPreferedDesc = preferName): string = + ## Formats types to strings + let preferToplevel = prefer + proc getPrefer(prefer: TPreferedDesc): TPreferedDesc = + if preferToplevel in {preferResolved, preferMixed}: + preferToplevel # sticky option + else: + prefer + + proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = + result = "" + let prefer = getPrefer(prefer) + let t = typ + if t == nil: return + if prefer in preferToResolveSymbols and t.sym != nil and + sfAnon notin t.sym.flags and t.kind != tySequence: + if t.kind == tyInt and isIntLit(t): + result = t.sym.name.s & " literal(" & $t.n.intVal & ")" + elif t.kind == tyAlias and t[0].kind != tyAlias: + result = typeToString(t[0]) + elif prefer in {preferResolved, preferMixed}: + case t.kind + of IntegralTypes + {tyFloat..tyFloat128} + {tyString, tyCstring}: + result = typeToStr[t.kind] + of tyGenericBody: + result = typeToString(t.lastSon) + of tyCompositeTypeClass: + # avoids showing `A[any]` in `proc fun(a: A)` with `A = object[T]` + result = typeToString(t.lastSon.lastSon) + else: + result = t.sym.name.s + if prefer == preferMixed and result != t.sym.name.s: + result = t.sym.name.s & "{" & result & "}" + elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil: + # note: should probably be: {preferName, preferTypeName, preferGenericArg} + result = t.sym.name.s + if t.kind == tyGenericParam and t.len > 0: + result.add ": " + var first = true + for son in t.sons: + if not first: result.add " or " + result.add son.typeToString + first = false + else: + result = t.sym.owner.name.s & '.' & t.sym.name.s + result.addTypeFlags(t) + return + case t.kind + of tyInt: + if not isIntLit(t) or prefer == preferExported: + result = typeToStr[t.kind] + else: + if prefer == preferGenericArg: + result = $t.n.intVal + else: + result = "int literal(" & $t.n.intVal & ")" + of tyGenericInst, tyGenericInvocation: + result = typeToString(t[0]) & '[' + for i in 1.. 1: result.add(", ") + result.add(typeToString(t[i], preferGenericArg)) + result.add(']') + of tyGenericBody: + result = typeToString(t.lastSon) & '[' + for i in 0.. 0: result.add(", ") + result.add(typeToString(t[i], preferTypeName)) + result.add(']') + of tyTypeDesc: + if t[0].kind == tyNone: result = "typedesc" + else: result = "typedesc[" & typeToString(t[0]) & "]" + of tyStatic: + if prefer == preferGenericArg and t.n != nil: + result = t.n.renderTree + else: + result = "static[" & (if t.len > 0: typeToString(t[0]) else: "") & "]" + if t.n != nil: result.add "(" & renderTree(t.n) & ")" + of tyUserTypeClass: + if t.sym != nil and t.sym.owner != nil: + if t.isResolvedUserTypeClass: return typeToString(t.lastSon) + return t.sym.owner.name.s + else: + result = "" + of tyBuiltInTypeClass: + result = case t.base.kind + of tyVar: "var" + of tyRef: "ref" + of tyPtr: "ptr" + of tySequence: "seq" + of tyArray: "array" + of tySet: "set" + of tyRange: "range" + of tyDistinct: "distinct" + of tyProc: "proc" + of tyObject: "object" + of tyTuple: "tuple" + of tyOpenArray: "openArray" + else: typeToStr[t.base.kind] + of tyInferred: + let concrete = t.previouslyInferred + if concrete != nil: result = typeToString(concrete) + else: result = "inferred[" & typeToString(t.base) & "]" + of tyUserTypeClassInst: + let body = t.base + result = body.sym.name.s & "[" + for i in 1.. 1: result.add(", ") + result.add(typeToString(t[i])) + result.add "]" + of tyAnd: + for i, son in t.sons: + result.add(typeToString(son)) + if i < t.sons.high: + result.add(" and ") + of tyOr: + for i, son in t.sons: + result.add(typeToString(son)) + if i < t.sons.high: + result.add(" or ") + of tyNot: + result = "not " & typeToString(t[0]) + of tyUntyped: + #internalAssert t.len == 0 + result = "untyped" + of tyFromExpr: + if t.n == nil: + result = "unknown" + else: + result = "typeof(" & renderTree(t.n) & ")" + of tyArray: + result = "array" + if t.len > 0: + if t[0].kind == tyRange: + result &= "[" & rangeToStr(t[0].n) & ", " & + typeToString(t[1]) & ']' + else: + result &= "[" & typeToString(t[0]) & ", " & + typeToString(t[1]) & ']' + of tyUncheckedArray: + result = "UncheckedArray" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' + of tySequence: + if t.sym != nil and prefer != preferResolved: + result = t.sym.name.s + else: + result = "seq" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' + of tyOrdinal: + result = "ordinal" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' + of tySet: + result = "set" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' + of tyOpenArray: + result = "openArray" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' + of tyDistinct: + result = "distinct " & typeToString(t[0], + if prefer == preferModuleInfo: preferModuleInfo else: preferTypeName) + of tyIterable: + # xxx factor this pattern + result = "iterable" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' + of tyTuple: + # we iterate over t.sons here, because t.n may be nil + if t.n != nil: + result = "tuple[" + assert(t.n.len == t.len) + for i in 0..= 2: + setLen(result, result.len-1) + result.add '[' + for i in 0.. 0 and t[0] != nil: result.add(": " & typeToString(t[0])) + var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: $t.callConv + if tfNoSideEffect in t.flags: + addSep(prag) + prag.add("noSideEffect") + if tfThread in t.flags: + addSep(prag) + prag.add("gcsafe") + if t.lockLevel.ord != UnspecifiedLockLevel.ord: + addSep(prag) + prag.add("locks: " & $t.lockLevel) + if prag.len != 0: result.add("{." & prag & ".}") + of tyVarargs: + result = typeToStr[t.kind] % typeToString(t[0]) + of tySink: + result = "sink " & typeToString(t[0]) + of tyOwned: + result = "owned " & typeToString(t[0]) + else: + result = typeToStr[t.kind] + result.addTypeFlags(t) + result = typeToString(typ, prefer) diff --git a/compiler/backend/cgen.nim b/compiler/backend/cgen.nim index cc8fe26bd95..80010dd240f 100644 --- a/compiler/backend/cgen.nim +++ b/compiler/backend/cgen.nim @@ -25,6 +25,7 @@ import nimsets, idents, types, + typesrenderer, wordrecg, treetab, renderer, @@ -62,8 +63,6 @@ import cgendata ], plugins/[ - ], - vm/[ ] diff --git a/compiler/front/cli_reporter.nim b/compiler/front/cli_reporter.nim index 14fc0b2c79a..081aff61c88 100644 --- a/compiler/front/cli_reporter.nim +++ b/compiler/front/cli_reporter.nim @@ -32,6 +32,7 @@ import astmsgs, renderer, types, + typesrenderer, ast, reports ], @@ -52,6 +53,26 @@ import import front/options as compiler_options +type + HackController* = object + ## additional configuration switches to control the behavior of the + ## debug printer. Since most of them are for compiler debugging, you + ## will most likely recompile the compiler anyway, so toggling couple + ## hardcoded constants here is easier than dragging out completely + ## unnecessary switches, or adding more magic `define()` blocks + semStack*: bool ## Show `| context` entries in the call tracer + + reportInTrace*: bool ## Error messages are shown with matching indentation + ## if report was triggered during execution of the sem trace + + semTraceData*: bool ## For each sem step show processed data, or only + ## procedure calls. + +const controller = HackController( + semStack: off, + reportInTrace: off, + semTraceData: on +) @@ -330,6 +351,31 @@ proc renderAsType*(vals: IntSet, t: PType): string = inc(i) result &= "}" +proc getProcHeader( + conf: ConfigRef; sym: PSym; prefer: TPreferedDesc = preferName; getDeclarationPath = true): string = + ## Formats procs and types + ## Returns for procs `owner.name(argument: signature): return` + ## Returns for types `owner.name` + assert sym != nil + # consider using `skipGenericOwner` to avoid fun2.fun2 when fun2 is generic + result = sym.owner.name.s & '.' & sym.name.s + if sym.kind in routineKinds: + result.add '(' + var n = sym.typ.n + for i in 1.. to fail with + # 'got `seq[MyInt2{char}]` but expected `seq[MyInt2]`' - formatting + # becomes buggy, so leaving as it is until all implicit code interactions + # are figured out. commit: + # https://github.com/nim-works/nimskull/pull/179/commits/55808ea55e90f01a3617d11d33a1699f3e7f2f12 + # failing test: https://github.com/nim-works/nimskull/runs/4951209502 + if optDeclaredLocs in conf.globalOptions: + result.add typeToString(typ, preferMixed) + result.addDeclaredLoc(conf, typ) + else: + result.add typeToString(typ) proc presentFailedCandidates( conf: ConfigRef, @@ -3567,6 +3629,8 @@ proc reportHook*(conf: ConfigRef, r: Report): TErrorHandling = elif wkind == writeForceEnabled: echo conf.reportFull(r) + + elif r.kind == rsemProcessing and conf.hintProcessingDots: # REFACTOR 'processing with dots' - requires special hacks, pretty # useless, need to be removed in the future. diff --git a/compiler/sem/injectdestructors.nim b/compiler/sem/injectdestructors.nim index 3c2eea71ffe..ef5f5661462 100644 --- a/compiler/sem/injectdestructors.nim +++ b/compiler/sem/injectdestructors.nim @@ -25,6 +25,7 @@ import astalgo, renderer, types, + typesrenderer, idents, lineinfos, reports diff --git a/compiler/sem/semmacrosanity.nim b/compiler/sem/semmacrosanity.nim index d33fd52282b..4b36f7af515 100644 --- a/compiler/sem/semmacrosanity.nim +++ b/compiler/sem/semmacrosanity.nim @@ -16,6 +16,7 @@ import ast/[ ast, types, + typesrenderer, reports, ], front/[ diff --git a/compiler/sem/semmagic.nim b/compiler/sem/semmagic.nim index 50071d55c61..639f18d5a11 100644 --- a/compiler/sem/semmagic.nim +++ b/compiler/sem/semmagic.nim @@ -10,6 +10,8 @@ # This include file implements the semantic checking for magics. # included from sem.nim +import ast/typesrenderer + proc semAddrArg(c: PContext; n: PNode; isUnsafeAddr = false): PNode = let x = semExprWithType(c, n) if x.kind == nkSym: diff --git a/compiler/sem/semobjconstr.nim b/compiler/sem/semobjconstr.nim index a199dff4d8d..bc732479dea 100644 --- a/compiler/sem/semobjconstr.nim +++ b/compiler/sem/semobjconstr.nim @@ -177,8 +177,6 @@ iterator directFieldsInRecList(recList: PNode): PNode = if field.kind != nkSym: continue yield field -template quoteStr(s: string): string = "'" & s & "'" - proc fieldsPresentInInitExpr(c: PContext, fieldsRecList, initExpr: PNode): seq[PSym] = for field in directFieldsInRecList(fieldsRecList): let diff --git a/compiler/sem/sigmatch.nim b/compiler/sem/sigmatch.nim index fc73181425e..d78386bb84a 100644 --- a/compiler/sem/sigmatch.nim +++ b/compiler/sem/sigmatch.nim @@ -21,6 +21,7 @@ import renderer, idents, lexer, + typesrenderer, trees, linter, lineinfos, diff --git a/compiler/tools/docgen.nim b/compiler/tools/docgen.nim index c50c03bd3ed..467c52261a7 100644 --- a/compiler/tools/docgen.nim +++ b/compiler/tools/docgen.nim @@ -31,7 +31,6 @@ import renderer, lexer, trees, - types, typesrenderer, astalgo, lineinfos, diff --git a/compiler/utils/debugutils.nim b/compiler/utils/debugutils.nim index 616e6ddeccc..ac21ae5166a 100644 --- a/compiler/utils/debugutils.nim +++ b/compiler/utils/debugutils.nim @@ -324,6 +324,35 @@ template addInNimDebugUtils*( addInNimDebugUtilsAux(c, action, enterMsg, leaveMsg) +template addInNimDebugUtils*( + c: ConfigRef; action: string; n: PNode; resSym: PSym) = + ## add tracing to procs that are primarily `PNode -> PSym`, + + when defined(nimDebugUtils): + template enterMsg(indentLevel: int) = + handleReport(c, wrap(instLoc(instDepth), DebugReport( + kind: rdbgTraceStep, + semstep: DebugSemStep( + direction: semstepEnter, + level: indentLevel, + name: action, + steppedFrom: calledFromInfo(), + node: n, + kind: stepNodeToSym))), instLoc(instDepth)) + + template leaveMsg(indentLevel: int) = + handleReport(c, wrap(instLoc(instDepth), DebugReport( + kind: rdbgTraceStep, + semstep: DebugSemStep( + direction: semstepLeave, + level: indentLevel, + name: action, + steppedFrom: calledFromInfo(), + sym: resSym, + kind: stepNodeToSym))), instLoc(instDepth)) + + addInNimDebugUtilsAux(c, action, enterMsg, leaveMsg) + template addInNimDebugUtils*(c: ConfigRef; action: string; x, y, r: PType) = ## add tracing to procs that are primarily `PType, PType -> PType`, looking ## for a common type diff --git a/compiler/vm/vm.nim b/compiler/vm/vm.nim index 62adc9e8ddf..2ed0b8f7c67 100644 --- a/compiler/vm/vm.nim +++ b/compiler/vm/vm.nim @@ -23,6 +23,7 @@ import trees, idents, reports, + typesrenderer, types, nimsets, parser # `parseExpr()` and `parseStmt()`