diff options
-rw-r--r-- | compiler/astalgo.nim | 13 | ||||
-rw-r--r-- | compiler/ccgutils.nim | 1 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 | ||||
-rw-r--r-- | compiler/docgen.nim | 54 | ||||
-rw-r--r-- | compiler/lookups.nim | 28 | ||||
-rw-r--r-- | compiler/semexprs.nim | 13 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 4 | ||||
-rw-r--r-- | compiler/transf.nim | 3 | ||||
-rw-r--r-- | lib/core/macros.nim | 35 | ||||
-rw-r--r-- | lib/packages/docutils/rst.nim | 29 | ||||
-rw-r--r-- | lib/pure/strscans.nim | 4 | ||||
-rw-r--r-- | tests/ccgbugs/tcodegenbug1.nim | 35 | ||||
-rw-r--r-- | tests/openarray/t8259.nim | 7 | ||||
-rw-r--r-- | tests/pragmas/tcustom_pragma.nim | 2 | ||||
-rw-r--r-- | tests/stdlib/t8925.nim | 16 |
16 files changed, 190 insertions, 58 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 34963ee83..b716882dc 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -549,7 +549,8 @@ proc strTableAdd*(t: var TStrTable, n: PSym) = strTableRawInsert(t.data, n) inc(t.counter) -proc strTableIncl*(t: var TStrTable, n: PSym; onConflictKeepOld=false): bool {.discardable.} = +proc strTableInclReportConflict*(t: var TStrTable, n: PSym; + onConflictKeepOld = false): PSym = # returns true if n is already in the string table: # It is essential that `n` is written nevertheless! # This way the newest redefinition is picked by the semantic analyses! @@ -564,13 +565,13 @@ proc strTableIncl*(t: var TStrTable, n: PSym; onConflictKeepOld=false): bool {.d # So it is possible the very same sym is added multiple # times to the symbol table which we allow here with the 'it == n' check. if it.name.id == n.name.id: - if it == n: return false + if it == n: return nil replaceSlot = h h = nextTry(h, high(t.data)) if replaceSlot >= 0: if not onConflictKeepOld: t.data[replaceSlot] = n # overwrite it with newer definition! - return true # found it + return t.data[replaceSlot] # found it elif mustRehash(len(t.data), t.counter): strTableEnlarge(t) strTableRawInsert(t.data, n) @@ -578,7 +579,11 @@ proc strTableIncl*(t: var TStrTable, n: PSym; onConflictKeepOld=false): bool {.d assert(t.data[h] == nil) t.data[h] = n inc(t.counter) - result = false + result = nil + +proc strTableIncl*(t: var TStrTable, n: PSym; + onConflictKeepOld = false): bool {.discardable.} = + result = strTableInclReportConflict(t, n, onConflictKeepOld) != nil proc strTableGet*(t: TStrTable, name: PIdent): PSym = var h: Hash = name.h and high(t.data) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 75cd3d35d..6d2f33f2d 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -92,6 +92,7 @@ proc mangle*(name: string): string = of '+': special "plus" of '-': special "minus" of '/': special "slash" + of '\\': special "backslash" of '=': special "eq" of '<': special "lt" of '>': special "gt" diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 2db92bc21..3040f98da 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -707,7 +707,7 @@ proc containsResult(n: PNode): bool = for i in 0..<n.safeLen: if containsResult(n[i]): return true -const harmless = {nkConstSection, nkTypeSection, nkEmpty, nkCommentStmt} + +const harmless = {nkConstSection, nkTypeSection, nkEmpty, nkCommentStmt, nkTemplateDef, nkMacroDef} + declarativeDefs proc easyResultAsgn(n: PNode): PNode = diff --git a/compiler/docgen.nim b/compiler/docgen.nim index ca3b1ac2d..e7920ad06 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -19,6 +19,9 @@ import typesrenderer, astalgo, modulepaths, lineinfos, sequtils, intsets, pathutils +const + exportSection = skTemp + type TSections = array[TSymKind, Rope] TDocumentor = object of rstgen.RstGenerator @@ -254,6 +257,15 @@ proc belongsToPackage(conf: ConfigRef; module: PSym): bool = result = module.kind == skModule and module.owner != nil and module.owner.id == conf.mainPackageId +proc externalDep(d: PDoc; module: PSym): string = + if optWholeProject in d.conf.globalOptions: + let full = AbsoluteFile toFullPath(d.conf, FileIndex module.position) + let tmp = getOutFile2(d.conf, full.relativeTo(d.conf.projectPath), HtmlExt, + RelativeDir"htmldocs", sfMainModule notin module.flags) + result = relativeTo(tmp, d.thisDir, '/').string + else: + result = extractFilename toFullPath(d.conf, FileIndex module.position) + proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRenderFlags = {}) = var r: TSrcGen var literal = "" @@ -290,12 +302,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe if s != nil and s.kind == skType and sfExported in s.flags and s.owner != nil and belongsToPackage(d.conf, s.owner) and d.target == outHtml: - - let full = AbsoluteFile toFullPath(d.conf, FileIndex s.owner.position) - let tmp = getOutFile2(d.conf, full.relativeTo(d.conf.projectPath), - HtmlExt, RelativeDir"htmldocs", sfMainModule notin s.owner.flags) - - let external = tmp.relativeTo(d.thisDir, '/') + let external = externalDep(d, s.owner) result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>", [rope changeFileExt(external, "html").string, rope literal, rope(esc(d.target, literal))] @@ -688,15 +695,32 @@ proc traceDeps(d: PDoc, it: PNode) = a.sons[2] = x traceDeps(d, a) elif it.kind == nkSym and belongsToPackage(d.conf, it.sym): - let full = AbsoluteFile toFullPath(d.conf, FileIndex it.sym.position) - let tmp = getOutFile2(d.conf, full.relativeTo(d.conf.projectPath), HtmlExt, - RelativeDir"htmldocs", sfMainModule notin it.sym.flags) - let external = relativeTo(tmp, d.thisDir, '/').string + let external = externalDep(d, it.sym) + if d.section[k] != nil: add(d.section[k], ", ") + dispA(d.conf, d.section[k], + "<a class=\"reference external\" href=\"$2\">$1</a>", + "$1", [rope esc(d.target, changeFileExt(external, "")), + rope changeFileExt(external, "html")]) + +proc exportSym(d: PDoc; s: PSym) = + const k = exportSection + if s.kind == skModule and belongsToPackage(d.conf, s): + let external = externalDep(d, s) if d.section[k] != nil: add(d.section[k], ", ") dispA(d.conf, d.section[k], "<a class=\"reference external\" href=\"$2\">$1</a>", "$1", [rope esc(d.target, changeFileExt(external, "")), rope changeFileExt(external, "html")]) + elif s.owner != nil: + let module = originatingModule(s) + if belongsToPackage(d.conf, module): + let external = externalDep(d, module) + if d.section[k] != nil: add(d.section[k], ", ") + # XXX proper anchor generation here + dispA(d.conf, d.section[k], + "<a href=\"$2#$1\"><span class=\"Identifier\">$1</span></a>", + "$1", [rope esc(d.target, s.name.s), + rope changeFileExt(external, "html")]) proc generateDoc*(d: PDoc, n, orig: PNode) = if orig.info.fileIndex != n.info.fileIndex: return @@ -732,7 +756,11 @@ proc generateDoc*(d: PDoc, n, orig: PNode) = if not checkForFalse(n.sons[0].sons[0]): generateDoc(d, lastSon(n.sons[0]), orig) of nkImportStmt: - for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i]) + for it in n: traceDeps(d, it) + of nkExportStmt: + for it in n: + if it.kind == nkSym: exportSym(d, it.sym) + of nkExportExceptStmt: discard "transformed into nkExportStmt by semExportExcept" of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0]) of nkCallKinds: var comm: Rope = nil @@ -828,8 +856,8 @@ proc generateTags*(d: PDoc, n: PNode, r: var Rope) = else: discard proc genSection(d: PDoc, kind: TSymKind) = - const sectionNames: array[skModule..skTemplate, string] = [ - "Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Funcs", + const sectionNames: array[skTemp..skTemplate, string] = [ + "Exports", "Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Funcs", "Methods", "Iterators", "Converters", "Macros", "Templates" ] if d.section[kind] == nil: return diff --git a/compiler/lookups.nim b/compiler/lookups.nim index ec9c130e3..d2e7fdcfa 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -58,8 +58,8 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent = template addSym*(scope: PScope, s: PSym) = strTableAdd(scope.symbols, s) -proc addUniqueSym*(scope: PScope, s: PSym): bool = - result = not strTableIncl(scope.symbols, s) +proc addUniqueSym*(scope: PScope, s: PSym): PSym = + result = strTableInclReportConflict(scope.symbols, s) proc openScope*(c: PContext): PScope {.discardable.} = result = PScope(parent: c.currentScope, @@ -177,24 +177,30 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) = message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(c.config, s)) s = nextIter(it, scope.symbols) -proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string) = +proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string; + conflictsWith: TLineInfo) = if c.config.cmd != cmdInteractive: - localError(c.config, info, "redefinition of '$1'" % s) + localError(c.config, info, + "redefinition of '$1'; previous declaration here: $2" % + [s, c.config $ conflictsWith]) proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) = - if not c.currentScope.addUniqueSym(sym): - wrongRedefinition(c, info, sym.name.s) + let conflict = c.currentScope.addUniqueSym(sym) + if conflict != nil: + wrongRedefinition(c, info, sym.name.s, conflict.info) proc addDecl*(c: PContext, sym: PSym) = - if not c.currentScope.addUniqueSym(sym): - wrongRedefinition(c, sym.info, sym.name.s) + let conflict = c.currentScope.addUniqueSym(sym) + if conflict != nil: + wrongRedefinition(c, sym.info, sym.name.s, conflict.info) proc addPrelimDecl*(c: PContext, sym: PSym) = discard c.currentScope.addUniqueSym(sym) proc addDeclAt*(c: PContext; scope: PScope, sym: PSym) = - if not scope.addUniqueSym(sym): - wrongRedefinition(c, sym.info, sym.name.s) + let conflict = scope.addUniqueSym(sym) + if conflict != nil: + wrongRedefinition(c, sym.info, sym.name.s, conflict.info) proc addInterfaceDeclAux(c: PContext, sym: PSym) = if sfExported in sym.flags: @@ -212,7 +218,7 @@ proc addOverloadableSymAt*(c: PContext; scope: PScope, fn: PSym) = return let check = strTableGet(scope.symbols, fn.name) if check != nil and check.kind notin OverloadableSyms: - wrongRedefinition(c, fn.info, fn.name.s) + wrongRedefinition(c, fn.info, fn.name.s, check.info) else: scope.addSym(fn) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 43f04fc9f..e683984c5 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1560,6 +1560,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = rhsTyp = rhsTyp.lastSon if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}: internalAssert c.config, c.p.resultSym != nil + # Make sure the type is valid for the result variable + typeAllowedCheck(c.config, n.info, rhsTyp, skResult) lhs.typ = rhsTyp c.p.resultSym.typ = rhsTyp c.p.owner.typ.sons[0] = rhsTyp @@ -2267,6 +2269,7 @@ proc semExportExcept(c: PContext, n: PNode): PNode = return n let exceptSet = readExceptSet(c, n) let exported = moduleName.sym + result = newNodeI(nkExportStmt, n.info) strTableAdd(c.module.tab, exported) var i: TTabIter var s = initTabIter(i, exported.tab) @@ -2274,11 +2277,12 @@ proc semExportExcept(c: PContext, n: PNode): PNode = if s.kind in ExportableSymKinds+{skModule} and s.name.id notin exceptSet: strTableAdd(c.module.tab, s) + result.add newSymNode(s, n.info) s = nextIter(i, exported.tab) - result = n proc semExport(c: PContext, n: PNode): PNode = - var x = newNodeI(n.kind, n.info) + result = newNodeI(nkExportStmt, n.info) + for i in 0..<n.len: let a = n.sons[i] var o: TOverloadIter @@ -2288,20 +2292,19 @@ proc semExport(c: PContext, n: PNode): PNode = elif s.kind == skModule: # forward everything from that module: strTableAdd(c.module.tab, s) - x.add(newSymNode(s, a.info)) var ti: TTabIter var it = initTabIter(ti, s.tab) while it != nil: if it.kind in ExportableSymKinds+{skModule}: strTableAdd(c.module.tab, it) + result.add newSymNode(it, a.info) it = nextIter(ti, s.tab) else: while s != nil: if s.kind in ExportableSymKinds+{skModule}: - x.add(newSymNode(s, a.info)) + result.add(newSymNode(s, a.info)) strTableAdd(c.module.tab, s) s = nextOverloadIter(o, c, a) - result = n proc shouldBeBracketExpr(n: PNode): bool = assert n.kind in nkCallKinds diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 566b634af..87d144dc6 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1604,7 +1604,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, localError(c.config, n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX % ("'" & proto.name.s & "' from " & c.config$proto.info)) if sfForward notin proto.flags and proto.magic == mNone: - wrongRedefinition(c, n.info, proto.name.s) + wrongRedefinition(c, n.info, proto.name.s, proto.info) excl(proto.flags, sfForward) closeScope(c) # close scope with wrong parameter symbols openScope(c) # open scope for old (correct) parameter symbols diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index a90a06150..5394e291f 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -125,8 +125,8 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if sfGenSym notin e.flags: if not isPure: addDecl(c, e) else: importPureEnumField(c, e) - if isPure and strTableIncl(symbols, e): - wrongRedefinition(c, e.info, e.name.s) + if isPure and (let conflict = strTableInclReportConflict(symbols, e); conflict != nil): + wrongRedefinition(c, e.info, e.name.s, conflict.info) inc(counter) if not hasNull: incl(result.flags, tfNeedsInit) diff --git a/compiler/transf.nim b/compiler/transf.nim index 347df3e49..0c3ddf27a 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -914,7 +914,8 @@ proc transform(c: PTransf, n: PNode): PTransNode = # ensure that e.g. discard "some comment" gets optimized away # completely: result = PTransNode(newNode(nkCommentStmt)) - of nkCommentStmt, nkTemplateDef, nkImportStmt, nkStaticStmt: + of nkCommentStmt, nkTemplateDef, nkImportStmt, nkStaticStmt, + nkExportStmt, nkExportExceptStmt: return n.PTransNode of nkConstSection: # do not replace ``const c = 3`` with ``const 3 = 3`` diff --git a/lib/core/macros.nim b/lib/core/macros.nim index aec766068..e7ef89551 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1321,17 +1321,18 @@ proc customPragmaNode(n: NimNode): NimNode = return typ.getImpl()[0][1] if n.kind in {nnkDotExpr, nnkCheckedFieldExpr}: - let name = (if n.kind == nnkCheckedFieldExpr: n[0][1] else: n[1]) + let name = $(if n.kind == nnkCheckedFieldExpr: n[0][1] else: n[1]) var typDef = getImpl(getTypeInst(if n.kind == nnkCheckedFieldExpr or n[0].kind == nnkHiddenDeref: n[0][0] else: n[0])) while typDef != nil: typDef.expectKind(nnkTypeDef) - typDef[2].expectKind({nnkRefTy, nnkPtrTy, nnkObjectTy}) - let isRef = typDef[2].kind in {nnkRefTy, nnkPtrTy} - if isRef and typDef[2][0].kind in {nnkSym, nnkBracketExpr}: # defines ref type for another object(e.g. X = ref X) - typDef = getImpl(typDef[2][0]) + let typ = typDef[2] + typ.expectKind({nnkRefTy, nnkPtrTy, nnkObjectTy}) + let isRef = typ.kind in {nnkRefTy, nnkPtrTy} + if isRef and typ[0].kind in {nnkSym, nnkBracketExpr}: # defines ref type for another object(e.g. X = ref X) + typDef = getImpl(typ[0]) else: # object definition, maybe an object directly defined as a ref type let - obj = (if isRef: typDef[2][0] else: typDef[2]) + obj = (if isRef: typ[0] else: typ) var identDefsStack = newSeq[NimNode](obj[2].len) for i in 0..<identDefsStack.len: identDefsStack[i] = obj[2][i] while identDefsStack.len > 0: @@ -1339,19 +1340,25 @@ proc customPragmaNode(n: NimNode): NimNode = if identDefs.kind == nnkRecCase: identDefsStack.add(identDefs[0]) for i in 1..<identDefs.len: + let varNode = identDefs[i] # if it is and empty branch, skip - if identDefs[i][0].kind == nnkNilLit: continue - if identDefs[i][1].kind == nnkIdentDefs: - identDefsStack.add(identDefs[i][1]) + if varNode[0].kind == nnkNilLit: continue + if varNode[1].kind == nnkIdentDefs: + identDefsStack.add(varNode[1]) else: # nnkRecList - for j in 0..<identDefs[i][1].len: - identDefsStack.add(identDefs[i][1][j]) + for j in 0 ..< varNode[1].len: + identDefsStack.add(varNode[1][j]) else: for i in 0 .. identDefs.len - 3: - if identDefs[i].kind == nnkPragmaExpr and - identDefs[i][0].kind == nnkIdent and $identDefs[i][0] == $name: - return identDefs[i][1] + let varNode = identDefs[i] + if varNode.kind == nnkPragmaExpr: + var varName = varNode[0] + if varName.kind == nnkPostfix: + # This is a public field. We are skipping the postfix * + varName = varName[1] + if eqIdent(varName.strVal, name): + return varNode[1] if obj[1].kind == nnkOfInherit: # explore the parent object typDef = getImpl(obj[1][0]) diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index d35f109e7..161509afe 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -363,6 +363,12 @@ proc addNodes(n: PRstNode): string = addNodesAux(n, result) proc rstnodeToRefnameAux(n: PRstNode, r: var string, b: var bool) = + template special(s) = + if b: + add(r, '-') + b = false + add(r, s) + if n == nil: return if n.kind == rnLeaf: for i in countup(0, len(n.text) - 1): @@ -373,7 +379,7 @@ proc rstnodeToRefnameAux(n: PRstNode, r: var string, b: var bool) = b = false if len(r) == 0: add(r, 'Z') add(r, n.text[i]) - of 'a'..'z': + of 'a'..'z', '\128'..'\255': if b: add(r, '-') b = false @@ -383,8 +389,27 @@ proc rstnodeToRefnameAux(n: PRstNode, r: var string, b: var bool) = add(r, '-') b = false add(r, chr(ord(n.text[i]) - ord('A') + ord('a'))) + of '$': special "dollar" + of '%': special "percent" + of '&': special "amp" + of '^': special "roof" + of '!': special "emark" + of '?': special "qmark" + of '*': special "star" + of '+': special "plus" + of '-': special "minus" + of '/': special "slash" + of '\\': special "backslash" + of '=': special "eq" + of '<': special "lt" + of '>': special "gt" + of '~': special "tilde" + of ':': special "colon" + of '.': special "dot" + of '@': special "at" + of '|': special "bar" else: - if (len(r) > 0): b = true + if len(r) > 0: b = true else: for i in countup(0, len(n) - 1): rstnodeToRefnameAux(n.sons[i], r, b) diff --git a/lib/pure/strscans.nim b/lib/pure/strscans.nim index 734317e67..77763ff43 100644 --- a/lib/pure/strscans.nim +++ b/lib/pure/strscans.nim @@ -317,8 +317,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b template at(s: string; i: int): char = (if i < s.len: s[i] else: '\0') template matchError() = - error("type mismatch between pattern '$" & pattern[p] & "' (position: " & $p & ") and " & repr(getType(results[i])) & - " var '" & repr(results[i]) & "'") + error("type mismatch between pattern '$" & pattern[p] & "' (position: " & $p & + ") and " & $getTypeInst(results[i]) & " var '" & repr(results[i]) & "'") var i = 0 var p = 0 diff --git a/tests/ccgbugs/tcodegenbug1.nim b/tests/ccgbugs/tcodegenbug1.nim index fce74de0c..012a4de47 100644 --- a/tests/ccgbugs/tcodegenbug1.nim +++ b/tests/ccgbugs/tcodegenbug1.nim @@ -2,7 +2,8 @@ discard """ output: '''obj = (inner: (kind: Just, id: 7)) obj.inner.id = 7 id = 7 -obj = (inner: (kind: Just, id: 7))''' +obj = (inner: (kind: Just, id: 7)) +2''' """ # bug #6960 @@ -105,3 +106,35 @@ type proc bug5137(d: MyIntDistinct) = discard d.MyInt + +#------------------------------------- +# bug #8979 + +type + MyKind = enum + Fixed, Float + + MyObject = object + someInt: int + case kind: MyKind + of Float: index: string + of Fixed: nil + + MyResult = object + val: array[0..1, string] + vis: set[0..1] + +import macros + +func myfunc(obj: MyObject): MyResult {.raises: [].} = + template index: auto = + case obj.kind: + of Float: $obj.index + of Fixed: "Fixed" + macro to_str(a: untyped): string = + result = newStrLitNode(a.repr) + result.val[0] = index + result.val[1] = to_str(obj.kind + Ola) + +let x = MyObject(someInt: 10, kind: Fixed) +echo myfunc(x).val.len diff --git a/tests/openarray/t8259.nim b/tests/openarray/t8259.nim new file mode 100644 index 000000000..40ff2b2f1 --- /dev/null +++ b/tests/openarray/t8259.nim @@ -0,0 +1,7 @@ +discard """ + line: 6 + errormsg: "invalid type: 'openarray[int]' for result" +""" + +proc foo(a: openArray[int]):auto = a +echo foo(toOpenArray([1, 2], 0, 2)) diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index d7b199a22..ae0f39631 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -22,7 +22,7 @@ import custom_pragma block: # A bit more advanced case type Subfield {.defaultValue: "catman".} = object - c {.serializationKey: "cc".}: float + c* {.serializationKey: "cc".}: float MySerializable = object a {.serializationKey"asdf", defaultValue: 5.} : int diff --git a/tests/stdlib/t8925.nim b/tests/stdlib/t8925.nim new file mode 100644 index 000000000..d3dc1ea86 --- /dev/null +++ b/tests/stdlib/t8925.nim @@ -0,0 +1,16 @@ +discard """ + file: "strscans.nim" + errormsg: "type mismatch between pattern '$i' (position: 1) and HourRange var 'hour'" +""" + +import strscans + +type + HourRange = range[0..23] + +var + hour: HourRange + timeStr: string + +if scanf(timeStr, "$i", hour): + discard |