From e4081a720190dfdeb347442cdc2c01745476ff9c Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sun, 7 Jan 2018 23:09:26 +0100 Subject: preparations for language extensions: 'sink' and 'lent' types --- compiler/semobjconstr.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'compiler/semobjconstr.nim') diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index a0bf084fa..46e6ef25d 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -260,8 +260,8 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = result = newNodeIT(nkObjConstr, n.info, t) for child in n: result.add child - t = skipTypes(t, {tyGenericInst, tyAlias}) - if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias}) + t = skipTypes(t, {tyGenericInst, tyAlias, tySink}) + if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink}) if t.kind != tyObject: localError(n.info, errGenerated, "object constructor needs an object type") return -- cgit 1.4.1-2-gfad0 From 31263ef8f3ed7dfea7b4e635aede5a1d627db031 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sun, 4 Feb 2018 07:35:32 +0100 Subject: fixes #5450 --- compiler/semobjconstr.nim | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'compiler/semobjconstr.nim') diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 46e6ef25d..63a4eb99a 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -260,6 +260,10 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = result = newNodeIT(nkObjConstr, n.info, t) for child in n: result.add child + if t == nil: + localError(n.info, errGenerated, "object constructor needs an object type") + return + t = skipTypes(t, {tyGenericInst, tyAlias, tySink}) if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink}) if t.kind != tyObject: -- cgit 1.4.1-2-gfad0 From 9de05ec3e04e8a2321b29896fe9fa7db4c6e65f3 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 30 Mar 2018 02:32:13 +0200 Subject: further steps in implementing sink parameters; refs #7041 --- compiler/ast.nim | 2 + compiler/commands.nim | 2 + compiler/destroyer.nim | 157 +++++++++++++++++++++++++++++++++++++++++++--- compiler/msgs.nim | 5 +- compiler/options.nim | 7 ++- compiler/pragmas.nim | 8 ++- compiler/semobjconstr.nim | 2 +- compiler/wordrecg.nim | 4 +- lib/system.nim | 5 ++ lib/system/chcks.nim | 5 ++ 10 files changed, 177 insertions(+), 20 deletions(-) (limited to 'compiler/semobjconstr.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index a28a7e7e3..68bf95772 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -453,6 +453,8 @@ type nfPreventCg # this node should be ignored by the codegen nfBlockArg # this a stmtlist appearing in a call (e.g. a do block) nfFromTemplate # a top-level node returned from a template + nfPreventDestructor # prevent destructor injectsion for the node + # (but not necessarily its children) TNodeFlags* = set[TNodeFlag] TTypeFlag* = enum # keep below 32 for efficiency reasons (now: beyond that) diff --git a/compiler/commands.nim b/compiler/commands.nim index 766b78798..2e9b6f8db 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -257,6 +257,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool = of "rangechecks": result = contains(gOptions, optRangeCheck) of "boundchecks": result = contains(gOptions, optBoundsCheck) of "overflowchecks": result = contains(gOptions, optOverflowCheck) + of "movechecks": result = contains(gOptions, optMoveCheck) of "linedir": result = contains(gOptions, optLineDir) of "assertions", "a": result = contains(gOptions, optAssert) of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim) @@ -493,6 +494,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "rangechecks": processOnOffSwitch({optRangeCheck}, arg, pass, info) of "boundchecks": processOnOffSwitch({optBoundsCheck}, arg, pass, info) of "overflowchecks": processOnOffSwitch({optOverflowCheck}, arg, pass, info) + of "movechecks": processOnOffSwitch({optMoveCheck}, arg, pass, info) of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info) of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info) of "deadcodeelim": processOnOffSwitchG({optDeadCodeElim}, arg, pass, info) diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index 55da69985..9acc89be4 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -89,11 +89,36 @@ ## tmp.bar)) ## destroy(tmp.bar) ## destroy(tmp.x); destroy(tmp.y) +## + +##[ +From https://github.com/nim-lang/Nim/wiki/Destructors + +Rule Pattern Transformed into +---- ------- ---------------- +1.1 var x: T; stmts var x: T; try stmts + finally: `=destroy`(x) +1.2 var x: sink T; stmts var x: sink T; stmts; ensureEmpty(x) +2 x = f() `=sink`(x, f()) +3 x = lastReadOf z `=sink`(x, z) +4.1 y = sinkParam `=sink`(y, sinkParam) +4.2 x = y `=`(x, y) # a copy +5.1 f_sink(g()) f_sink(g()) +5.2 f_sink(y) f_sink(copy y); # copy unless we can see it's the last read +5.3 f_sink(move y) f_sink(y); reset(y) # explicit moves empties 'y' +5.4 f_noSink(g()) var tmp = bitwiseCopy(g()); f(tmp); `=destroy`(tmp) + +Remarks: Rule 1.2 is not yet implemented because ``sink`` is currently + not allowed as a local variable. + +``move`` builtin needs to be implemented. +XXX Think about nfPreventDestructor logic. +]## import intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, - strutils, options, dfa, lowerings, rodread + strutils, options, dfa, lowerings, rodread, tables const InterestingSyms = {skVar, skResult, skLet} @@ -106,6 +131,14 @@ type tmpObj: PType tmp: PSym destroys, topLevelVars: PNode + toDropBit: Table[int, PSym] + +proc getTemp(c: var Con; typ: PType; info: TLineInfo): PNode = + # XXX why are temps fields in an object here? + let f = newSym(skField, getIdent(":d" & $c.tmpObj.n.len), c.owner, info) + f.typ = typ + rawAddField c.tmpObj, f + result = rawDirectAccess(c.tmp, f) proc isHarmlessVar*(s: PSym; c: Con): bool = # 's' is harmless if it used only once and its @@ -212,14 +245,44 @@ proc genDestroy(t: PType; dest: PNode): PNode = proc addTopVar(c: var Con; v: PNode) = c.topLevelVars.add newTree(nkIdentDefs, v, emptyNode, emptyNode) +proc dropBit(c: var Con; s: PSym): PSym = + result = c.toDropBit.getOrDefault(s.id) + assert result != nil + +proc registerDropBit(c: var Con; s: PSym) = + let result = newSym(skTemp, getIdent(s.name.s & "_AliveBit"), c.owner, s.info) + result.typ = getSysType(tyBool) + let trueVal = newIntTypeNode(nkIntLit, 1, result.typ) + c.topLevelVars.add newTree(nkIdentDefs, newSymNode result, emptyNode, trueVal) + c.toDropBit[s.id] = result + # generate: + # if not sinkParam_AliveBit: `=destroy`(sinkParam) + c.destroys.add newTree(nkIfStmt, + newTree(nkElifBranch, newSymNode result, genDestroy(s.typ, newSymNode s))) + proc p(n: PNode; c: var Con): PNode template recurse(n, dest) = for i in 0.. 0: c.addTopVar(newSymNode c.tmp) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 09413128b..70504cfc9 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -134,7 +134,7 @@ type hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, hintConditionAlwaysTrue, hintName, hintPattern, hintExecuting, hintLinking, hintDependency, - hintSource, hintStackTrace, hintGCStats, + hintSource, hintPerformance, hintStackTrace, hintGCStats, hintUser, hintUserRaw const @@ -438,6 +438,7 @@ const hintLinking: "", hintDependency: "$1", hintSource: "$1", + hintPerformance: "$1", hintStackTrace: "$1", hintGCStats: "$1", hintUser: "$1", @@ -460,7 +461,7 @@ const "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", "ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf", "Path", "CondTrue", "Name", "Pattern", "Exec", "Link", "Dependency", - "Source", "StackTrace", "GCStats", + "Source", "Performance", "StackTrace", "GCStats", "User", "UserRaw"] const diff --git a/compiler/options.nim b/compiler/options.nim index 65f5a6245..be13e15d7 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -25,7 +25,7 @@ type # please make sure we have under 32 options TOption* = enum # **keep binary compatible** optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck, optOverflowCheck, optNilCheck, - optNaNCheck, optInfCheck, + optNaNCheck, optInfCheck, optMoveCheck, optAssert, optLineDir, optWarns, optHints, optOptimizeSpeed, optOptimizeSize, optStackTrace, # stack tracing support optLineTrace, # line tracing support (includes stack tracing) @@ -119,13 +119,14 @@ var const ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck, - optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck} + optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck, + optMoveCheck} var gOptions*: TOptions = {optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck, optOverflowCheck, optAssert, optWarns, optHints, optStackTrace, optLineTrace, - optPatterns, optNilCheck} + optPatterns, optNilCheck, optMoveCheck} gGlobalOptions*: TGlobalOptions = {optThreadAnalysis} gExitcode*: int8 gCmd*: TCommands = cmdNone # the command diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 1b8078628..1295ee18d 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -40,7 +40,8 @@ const wTags, wLocks, wGcSafe, wExportNims, wUsed} exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, - wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, + wBoundchecks, wOverflowchecks, wNilchecks, wMovechecks, wAssertions, + wWarnings, wHints, wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop, wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated, @@ -323,6 +324,7 @@ proc processOption(c: PContext, n: PNode): bool = of wFloatchecks: onOff(c, n, {optNaNCheck, optInfCheck}) of wNanChecks: onOff(c, n, {optNaNCheck}) of wInfChecks: onOff(c, n, {optInfCheck}) + of wMovechecks: onOff(c, n, {optMoveCheck}) of wAssertions: onOff(c, n, {optAssert}) of wWarnings: onOff(c, n, {optWarns}) of wHints: onOff(c, n, {optHints}) @@ -693,7 +695,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, inc c.instCounter if c.instCounter > 100: globalError(it.info, errRecursiveDependencyX, userPragma.name.s) - + pragma(c, sym, userPragma.ast, validPragmas) n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty @@ -906,7 +908,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wCodegenDecl: processCodegenDecl(c, it, sym) of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, - wLinedir, wStacktrace, wLinetrace, wOptimization, + wLinedir, wStacktrace, wLinetrace, wOptimization, wMovechecks, wCallconv, wDebugger, wProfiler, wFloatchecks, wNanChecks, wInfChecks, wPatterns: diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 63a4eb99a..e2296a0d2 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -76,7 +76,7 @@ proc semConstrField(c: PContext, flags: TExprFlags, return initValue proc caseBranchMatchesExpr(branch, matched: PNode): bool = - for i in 0 .. (branch.len - 2): + for i in 0 .. branch.len-2: if exprStructuralEquivalent(branch[i], matched): return true diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index e458cad03..76d91d4e7 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -52,7 +52,7 @@ type wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline, wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, - wFloatchecks, wNanChecks, wInfChecks, + wFloatchecks, wNanChecks, wInfChecks, wMoveChecks, wAssertions, wPatterns, wWarnings, wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags, wDeadCodeElim, wSafecode, wPackage, wNoForward, wReorder, wNoRewrite, @@ -139,7 +139,7 @@ const "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure", "noconv", "on", "off", "checks", "rangechecks", "boundchecks", "overflowchecks", "nilchecks", - "floatchecks", "nanchecks", "infchecks", + "floatchecks", "nanchecks", "infchecks", "movechecks", "assertions", "patterns", "warnings", "hints", "optimization", "raises", "writes", "reads", "size", "effects", "tags", diff --git a/lib/system.nim b/lib/system.nim index 7116f8818..7eda30276 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -617,6 +617,11 @@ type ## ## This is only raised if the ``segfaults.nim`` module was imported! +when defined(nimNewRuntime): + type + MoveError* = object of SystemError ## \ + ## Raised on attempts to re-sink an already consumed ``sink`` parameter. + {.deprecated: [TObject: RootObj, PObject: RootRef, TEffect: RootEffect, FTime: TimeEffect, FIO: IOEffect, FReadIO: ReadIOEffect, FWriteIO: WriteIOEffect, FExecIO: ExecIOEffect, diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index 69b680dbd..d3651f659 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -52,6 +52,11 @@ proc chckNil(p: pointer) = if p == nil: sysFatal(NilAccessError, "attempt to write to a nil address") +when defined(nimNewRuntime): + proc chckMove(b: bool) {.compilerproc.} = + if not b: + sysFatal(MoveError, "attempt to access an object that was moved") + proc chckNilDisp(p: pointer) {.compilerproc.} = if p == nil: sysFatal(NilAccessError, "cannot dispatch; dispatcher is nil") -- cgit 1.4.1-2-gfad0 From 824092be312ff16445f137c4322d0cd3cc95fb2e Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 6 Apr 2018 13:01:24 +0200 Subject: fixes a regression about static object case variant checking --- compiler/semobjconstr.nim | 4 +++- tests/objvariant/tvariantstack.nim | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'compiler/semobjconstr.nim') diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index e2296a0d2..cfa0fbd05 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -77,7 +77,9 @@ proc semConstrField(c: PContext, flags: TExprFlags, proc caseBranchMatchesExpr(branch, matched: PNode): bool = for i in 0 .. branch.len-2: - if exprStructuralEquivalent(branch[i], matched): + if branch[i].kind == nkRange: + if overlap(branch[i], matched): return true + elif exprStructuralEquivalent(branch[i], matched): return true return false diff --git a/tests/objvariant/tvariantstack.nim b/tests/objvariant/tvariantstack.nim index d81f6e001..0cdde5a20 100644 --- a/tests/objvariant/tvariantstack.nim +++ b/tests/objvariant/tvariantstack.nim @@ -49,4 +49,34 @@ var t = stack.pop() echo "came here" +# another regression: +type + LexerToken* = enum + ltYamlDirective, ltYamlVersion, ltTagDirective, ltTagShorthand, + ltTagUri, ltUnknownDirective, ltUnknownDirectiveParams, ltEmptyLine, + ltDirectivesEnd, ltDocumentEnd, ltStreamEnd, ltIndentation, ltQuotedScalar, + ltScalarPart, ltBlockScalarHeader, ltBlockScalar, ltSeqItemInd, ltMapKeyInd, + ltMapValInd, ltBraceOpen, ltBraceClose, ltBracketOpen, ltBracketClose, + ltComma, ltLiteralTag, ltTagHandle, ltAnchor, ltAlias + +const tokensWithValue = + {ltScalarPart, ltQuotedScalar, ltYamlVersion, ltTagShorthand, ltTagUri, + ltUnknownDirective, ltUnknownDirectiveParams, ltLiteralTag, ltAnchor, + ltAlias, ltBlockScalar} + +type + TokenWithValue = object + case kind: LexerToken + of tokensWithValue: + value: string + of ltIndentation: + indentation: int + of ltTagHandle: + handle, suffix: string + else: discard + +proc sp(v: string): TokenWithValue = + # test.nim(27, 17) Error: a case selecting discriminator 'kind' with value 'ltScalarPart' appears in the object construction, but the field(s) 'value' are in conflict with this value. + TokenWithValue(kind: ltScalarPart, value: v) +let a = sp("test") -- cgit 1.4.1-2-gfad0 From ce859d8c166595184832b4bbfb663cba2fc68901 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 12 May 2018 16:35:59 +0200 Subject: more modules compile again --- compiler/configuration.nim | 19 +-- compiler/evaltempl.nim | 2 +- compiler/hlo.nim | 12 +- compiler/nimfix/pretty.nim | 4 +- compiler/sem.nim | 29 +++-- compiler/semcall.nim | 59 +++++---- compiler/semexprs.nim | 214 +++++++++++++++---------------- compiler/semfields.nim | 10 +- compiler/seminst.nim | 27 ++-- compiler/semmagic.nim | 28 ++-- compiler/semobjconstr.nim | 22 ++-- compiler/semstmts.nim | 248 ++++++++++++++++++------------------ compiler/semtempl.nim | 77 +++++------ compiler/semtypes.nim | 309 ++++++++++++++++++++++++--------------------- compiler/vm.nim | 2 +- 15 files changed, 544 insertions(+), 518 deletions(-) (limited to 'compiler/semobjconstr.nim') diff --git a/compiler/configuration.nim b/compiler/configuration.nim index b2548eb74..4b3cecfca 100644 --- a/compiler/configuration.nim +++ b/compiler/configuration.nim @@ -229,7 +229,6 @@ errXExpectsArrayType: "'$1' expects an array type", errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet", errExprXAmbiguous: "expression '$1' ambiguous in this context", errConstantDivisionByZero: , -errOrdinalTypeExpected: "ordinal type expected", errOrdinalOrFloatTypeExpected: "ordinal or float type expected", errOverOrUnderflow: , errCannotEvalXBecauseIncompletelyDefined: , @@ -274,9 +273,6 @@ errConstNeedsConstExpr: "a constant can only be initialized with a constant expr errConstNeedsValue: "a constant needs a value", errResultCannotBeOpenArray: "the result type cannot be on open array", errSizeTooBig: "computing the type's size produced an overflow", -errSetTooBig: "set is too large", -errBaseTypeMustBeOrdinal: "base type of a set must be an ordinal", -errInheritanceOnlyWithNonFinalObjects: "inheritance only works with non-final objects", errInheritanceOnlyWithEnums: "inheritance only works with an enum", errIllegalRecursionInTypeX:, errCannotInstantiateX: "cannot instantiate: '$1'", @@ -293,7 +289,6 @@ errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'", errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters", errXCannotBePassedToProcVar: , errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1", -errImplOfXNotAllowed: "implementation of '$1' is not allowed", errImplOfXexpected: , errNoSymbolToBorrowFromFound: "no symbol to borrow from found", errDiscardValueX: "value of type '$1' has to be discarded", @@ -312,7 +307,7 @@ errUnknownSubstitionVar: "unknown substitution variable: '$1'", errComplexStmtRequiresInd: "complex statement requires indentation", errXisNotCallable: "'$1' is not callable", errNoPragmasAllowedForX: "no pragmas allowed for $1", -errNoGenericParamsAllowedForX: "no generic parameters allowed for $1", +, errInvalidParamKindX: "invalid param kind: '$1'", errDefaultArgumentInvalid: "default argument invalid", errNamedParamHasToBeIdent: "named parameter has to be an identifier", @@ -328,17 +323,8 @@ errInvalidExpressionX: "invalid expression: '$1'", errEnumHasNoValueX: "enum has no value '$1'", errNamedExprExpected: "named expression expected", errNamedExprNotAllowed: "named expression not allowed here", -errXExpectsOneTypeParam: "'$1' expects one type parameter", -errArrayExpectsTwoTypeParams: "array expects two type parameters", -errInvalidVisibilityX: "invalid visibility: '$1'", -errInitHereNotAllowed: "initialization not allowed here", -errXCannotBeAssignedTo: "'$1' cannot be assigned to", -errIteratorNotAllowed: "iterators can only be defined at the module's top level", -errXNeedsReturnType: "$1 needs a return type", -errNoReturnTypeDeclared: "no return type declared", errNoCommand: "no command given", errInvalidCommandX: "invalid command: '$1'", -errXOnlyAtModuleScope: "'$1' is only allowed at top level", errXNeedsParamObjectType: "'$1' needs a parameter that has an object type", errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N", errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N", @@ -347,7 +333,7 @@ errInvalidIndexValueForTuple: "invalid index value for tuple subscript", errCommandExpectsFilename: "command expects a filename argument", errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file", errXExpected: "'$1' expected", -errTIsNotAConcreteType: "'$1' is not a concrete type.", +, errCastToANonConcreteType: "cannot cast to a non concrete type: '$1'", errInvalidSectionStart: "invalid section start", errGridTableNotImplemented: "grid table is not implemented", @@ -396,5 +382,4 @@ errGenericLambdaNotAllowed: "A nested proc can have generic parameters only when "it is used as an operand to another routine and the types " & "of the generic paramers can be inferred from the expected signature.", errProcHasNoConcreteType: "'$1' doesn't have a concrete type, due to unspecified generic parameters.", -errInOutFlagNotExtern: "The `$1` modifier can be used only with imported types", ]# diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 2133701e6..311bb6539 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -114,7 +114,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode # to prevent endless recursion in template instantiation const evalTemplateLimit* = 1000 -var evalTemplateCounter* = 0 +var evalTemplateCounter* = 0 # XXX remove this global proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode = when true: diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 3e19be6e9..76404e49b 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -17,7 +17,7 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode = # aweful to semcheck before macro invocation, so we don't and treat # templates and macros as immediate in this context. var rule: string - if optHints in gOptions and hintPattern in gNotes: + if optHints in gOptions and hintPattern in c.config.notes: rule = renderTree(n, {renderNoComments}) let s = n.sons[0].sym case s.kind @@ -27,8 +27,8 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode = result = semTemplateExpr(c, n, s, {efFromHlo}) else: result = semDirectOp(c, n, {}) - if optHints in gOptions and hintPattern in gNotes: - message(orig.info, hintPattern, rule & " --> '" & + if optHints in gOptions and hintPattern in c.config.notes: + message(c.config, orig.info, hintPattern, rule & " --> '" & renderTree(result, {renderNoComments}) & "'") proc applyPatterns(c: PContext, n: PNode): PNode = @@ -45,7 +45,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode = # better be safe than sorry, so check evalTemplateCounter too: inc(evalTemplateCounter) if evalTemplateCounter > evalTemplateLimit: - globalError(n.info, errTemplateInstantiationTooNested) + globalError(c.config, n.info, "template instantiation too nested") # deactivate this pattern: c.patterns[i] = nil if x.kind == nkStmtList: @@ -86,9 +86,9 @@ proc hlo(c: PContext, n: PNode): PNode = else: result = fitNode(c, n.typ, result, n.info) # optimization has been applied so check again: - result = commonOptimizations(c.module, result) + result = commonOptimizations(c.graph, c.module, result) result = hlo(c, result) - result = commonOptimizations(c.module, result) + result = commonOptimizations(c.graph, c.module, result) proc hloBody(c: PContext, n: PNode): PNode = # fast exit: diff --git a/compiler/nimfix/pretty.nim b/compiler/nimfix/pretty.nim index c68c3ccf1..96429ad53 100644 --- a/compiler/nimfix/pretty.nim +++ b/compiler/nimfix/pretty.nim @@ -132,9 +132,9 @@ template styleCheckDef*(info: TLineInfo; s: PSym; k: TSymKind) = if gStyleCheck != StyleCheck.None: styleCheckDefImpl(conf, info, s, k) template styleCheckDef*(info: TLineInfo; s: PSym) = - styleCheckDef(conf, info, s, s.kind) + styleCheckDef(info, s, s.kind) template styleCheckDef*(s: PSym) = - styleCheckDef(conf, s.info, s, s.kind) + styleCheckDef(s.info, s, s.kind) proc styleCheckUseImpl(info: TLineInfo; s: PSym) = if info.fileIndex.int < 0: return diff --git a/compiler/sem.nim b/compiler/sem.nim index ae32ecb8a..de0b2d306 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -16,7 +16,7 @@ import procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity, - semparallel, lowerings, pluginsupport, plugins.active, rod + semparallel, lowerings, pluginsupport, plugins.active, rod, configuration from modulegraphs import ModuleGraph @@ -382,7 +382,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode, ## contains. inc(evalTemplateCounter) if evalTemplateCounter > evalTemplateLimit: - globalError(s.info, errTemplateInstantiationTooNested) + globalError(c.config, s.info, "template instantiation too nested") c.friendModules.add(s.owner.getModule) result = macroResult @@ -424,43 +424,46 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode, dec(evalTemplateCounter) discard c.friendModules.pop() +const + errMissingGenericParamsForTemplate = "'$1' has unspecified generic parameters" + proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, flags: TExprFlags = {}): PNode = pushInfoContext(nOrig.info) - markUsed(n.info, sym, c.graph.usageSym) + markUsed(c.config, n.info, sym, c.graph.usageSym) styleCheckUse(n.info, sym) if sym == c.p.owner: - globalError(n.info, errRecursiveDependencyX, sym.name.s) + globalError(c.config, n.info, "recursive dependency: '$1'" % sym.name.s) let genericParams = if sfImmediate in sym.flags: 0 else: sym.ast[genericParamsPos].len let suppliedParams = max(n.safeLen - 1, 0) if suppliedParams < genericParams: - globalError(n.info, errMissingGenericParamsForTemplate, n.renderTree) + globalError(c.config, n.info, errMissingGenericParamsForTemplate % n.renderTree) #if c.evalContext == nil: # c.evalContext = c.createEvalContext(emStatic) - result = evalMacroCall(c.module, c.cache, c.graph.config, n, nOrig, sym) + result = evalMacroCall(c.module, c.cache, c.graph, n, nOrig, sym) if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, sym, flags) result = wrapInComesFrom(nOrig.info, sym, result) popInfoContext() proc forceBool(c: PContext, n: PNode): PNode = - result = fitNode(c, getSysType(tyBool), n, n.info) + result = fitNode(c, getSysType(c.graph, n.info, tyBool), n, n.info) if result == nil: result = n proc semConstBoolExpr(c: PContext, n: PNode): PNode = let nn = semExprWithType(c, n) - result = fitNode(c, getSysType(tyBool), nn, nn.info) + result = fitNode(c, getSysType(c.graph, n.info, tyBool), nn, nn.info) if result == nil: - localError(n.info, errConstExprExpected) + localError(c.config, n.info, errConstExprExpected) return nn - result = getConstExpr(c.module, result) + result = getConstExpr(c.module, result, c.graph) if result == nil: - localError(n.info, errConstExprExpected) + localError(c.config, n.info, errConstExprExpected) result = nn proc semGenericStmt(c: PContext, n: PNode): PNode @@ -480,7 +483,7 @@ proc addCodeForGenerics(c: PContext, n: PNode) = proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = var c = newContext(graph, module, cache) - if c.p != nil: internalError(module.info, "sem.myOpen") + if c.p != nil: internalError(graph.config, module.info, "sem.myOpen") c.semConstExpr = semConstExpr c.semExpr = semExpr c.semTryExpr = tryExpr @@ -532,7 +535,7 @@ proc isImportSystemStmt(n: PNode): bool = proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = if n.kind == nkDefer: - localError(n.info, "defer statement not supported at top level") + localError(c.config, n.info, "defer statement not supported at top level") if c.topStmts == 0 and not isImportSystemStmt(n): if sfSystemModule notin c.module.flags and n.kind notin {nkEmpty, nkCommentStmt}: diff --git a/compiler/semcall.nim b/compiler/semcall.nim index aa53fda3b..b4d4cad7e 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -202,24 +202,31 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): result = (prefer, candidates) +const + errTypeMismatch = "type mismatch: got <" + errButExpected = "but expected one of: " + errUndeclaredField = "undeclared field: '$1'" + errUndeclaredRoutine = "attempting to call undeclared routine: '$1'" + errAmbiguousCallXYZ = "ambiguous call; both $1 and $2 match for: $3" + proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = # Gives a detailed error message; this is separated from semOverloadedCall, # as semOverlodedCall is already pretty slow (and we need this information # only in case of an error). if errorOutputs == {}: # fail fast: - globalError(n.info, errTypeMismatch, "") + globalError(c.config, n.info, "type mismatch") if errors.len == 0: - localError(n.info, errExprXCannotBeCalled, n[0].renderTree) + localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree) return let (prefer, candidates) = presentFailedCandidates(c, n, errors) - var result = msgKindToString(errTypeMismatch) + var result = errTypeMismatch add(result, describeArgs(c, n, 1, prefer)) add(result, '>') if candidates != "": - add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates) - localError(n.info, errGenerated, result & "\nexpression: " & $n) + add(result, "\n" & errButExpected & "\n" & candidates) + localError(c.config, n.info, result & "\nexpression: " & $n) proc bracketNotFoundError(c: PContext; n: PNode) = var errors: CandidateErrors = @[] @@ -234,7 +241,7 @@ proc bracketNotFoundError(c: PContext; n: PNode) = enabled: false)) symx = nextOverloadIter(o, c, headSymbol) if errors.len == 0: - localError(n.info, "could not resolve: " & $n) + localError(c.config, n.info, "could not resolve: " & $n) else: notFoundError(c, n, errors) @@ -277,7 +284,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, else: return if nfDotField in n.flags: - internalAssert f.kind == nkIdent and n.sonsLen >= 2 + internalAssert c.config, f.kind == nkIdent and n.len >= 2 # leave the op head symbol empty, # we are going to try multiple variants @@ -306,13 +313,13 @@ proc resolveOverloads(c: PContext, n, orig: PNode, if overloadsState == csEmpty and result.state == csEmpty: if nfDotField in n.flags and nfExplicitCall notin n.flags: - localError(n.info, errUndeclaredField, considerQuotedIdent(f, n).s) + localError(c.config, n.info, errUndeclaredField % considerQuotedIdent(c.config, f, n).s) else: - localError(n.info, errUndeclaredRoutine, considerQuotedIdent(f, n).s) + localError(c.config, n.info, errUndeclaredRoutine % considerQuotedIdent(c.config, f, n).s) return elif result.state != csMatch: if nfExprCall in n.flags: - localError(n.info, errExprXCannotBeCalled, + localError(c.config, n.info, "expression '$1' cannot be called" % renderTree(n, {renderNoComments})) else: if {nfDotField, nfDotSetter} * n.flags != {}: @@ -322,13 +329,13 @@ proc resolveOverloads(c: PContext, n, orig: PNode, return if alt.state == csMatch and cmpCandidates(result, alt) == 0 and not sameMethodDispatcher(result.calleeSym, alt.calleeSym): - internalAssert result.state == csMatch + internalAssert c.config, result.state == csMatch #writeMatches(result) #writeMatches(alt) if errorOutputs == {}: # quick error message for performance of 'compiles' built-in: - globalError(n.info, errGenerated, "ambiguous call") - elif gErrorCounter == 0: + globalError(c.config, n.info, errGenerated, "ambiguous call") + elif c.config.errorCounter == 0: # don't cascade errors var args = "(" for i in countup(1, sonsLen(n) - 1): @@ -336,7 +343,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, add(args, typeToString(n.sons[i].typ)) add(args, ")") - localError(n.info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ + localError(c.config, n.info, errAmbiguousCallXYZ % [ getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym), args]) @@ -377,7 +384,7 @@ proc inferWithMetatype(c: PContext, formal: PType, result.typ = generateTypeInstance(c, m.bindings, arg.info, formal.skipTypes({tyCompositeTypeClass})) else: - typeMismatch(arg.info, formal, arg.typ) + typeMismatch(c.config, arg.info, formal, arg.typ) # error correction: result = copyTree(arg) result.typ = formal @@ -385,7 +392,7 @@ proc inferWithMetatype(c: PContext, formal: PType, proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = assert x.state == csMatch var finalCallee = x.calleeSym - markUsed(n.sons[0].info, finalCallee, c.graph.usageSym) + markUsed(c.config, n.sons[0].info, finalCallee, c.graph.usageSym) styleCheckUse(n.sons[0].info, finalCallee) assert finalCallee.ast != nil if x.hasFauxMatch: @@ -411,7 +418,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = of skType: x.call.add newSymNode(s, n.info) else: - internalAssert false + internalAssert c.config, false result = x.call instGenericConvertersSons(c, result, x) @@ -435,7 +442,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, # this may be triggered, when the explain pragma is used if errors.len > 0: let (_, candidates) = presentFailedCandidates(c, n, errors) - message(n.info, hintUserRaw, + message(c.config, n.info, hintUserRaw, "Non-matching candidates for " & renderTree(n) & "\n" & candidates) result = semResolvedCall(c, n, r) @@ -468,8 +475,8 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, else: notFoundError(c, n, errors) -proc explicitGenericInstError(n: PNode): PNode = - localError(n.info, errCannotInstantiateX, renderTree(n)) +proc explicitGenericInstError(c: PContext; n: PNode): PNode = + localError(c.config, n.info, errCannotInstantiateX % renderTree(n)) result = n proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = @@ -484,7 +491,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = if tm in {isNone, isConvertible}: return nil var newInst = generateInstance(c, s, m.bindings, n.info) newInst.typ.flags.excl tfUnresolved - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(newInst, n.info) @@ -500,11 +507,11 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # number of generic type parameters: if safeLen(s.ast.sons[genericParamsPos]) != n.len-1: let expected = safeLen(s.ast.sons[genericParamsPos]) - localError(n.info, errGenerated, "cannot instantiate: " & renderTree(n) & + localError(c.config, n.info, errGenerated, "cannot instantiate: " & renderTree(n) & "; got " & $(n.len-1) & " type(s) but expected " & $expected) return n result = explicitGenericSym(c, n, s) - if result == nil: result = explicitGenericInstError(n) + if result == nil: result = explicitGenericInstError(c, n) elif a.kind in {nkClosedSymChoice, nkOpenSymChoice}: # choose the generic proc with the proper number of type parameters. # XXX I think this could be improved by reusing sigmatch.paramTypesMatch. @@ -522,10 +529,10 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # get rid of nkClosedSymChoice if not ambiguous: if result.len == 1 and a.kind == nkClosedSymChoice: result = result[0] - elif result.len == 0: result = explicitGenericInstError(n) - # candidateCount != 1: return explicitGenericInstError(n) + elif result.len == 0: result = explicitGenericInstError(c, n) + # candidateCount != 1: return explicitGenericInstError(c, n) else: - result = explicitGenericInstError(n) + result = explicitGenericInstError(c, n) proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 4a3672aa0..001e0ccf2 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -31,12 +31,12 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.typ != nil: # XXX tyGenericInst here? if result.typ.kind == tyProc and tfUnresolved in result.typ.flags: - localError(n.info, errProcHasNoConcreteType, n.renderTree) + localError(c.config, n.info, errProcHasNoConcreteType, n.renderTree) if result.typ.kind in {tyVar, tyLent}: result = newDeref(result) elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyVoid, c) else: - localError(n.info, errExprXHasNoType, + localError(c.config, n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -47,7 +47,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = #raiseRecoverableError("") result = errorNode(c, n) if result.typ == nil or result.typ == enforceVoidContext: - localError(n.info, errExprXHasNoType, + localError(c.config, n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) result.typ = errorType(c) else: @@ -59,7 +59,7 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: result = errorNode(c, n) if result.typ == nil: - localError(n.info, errExprXHasNoType, + localError(c.config, n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -69,7 +69,7 @@ proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = proc inlineConst(n: PNode, s: PSym): PNode {.inline.} = result = copyTree(s.ast) if result.isNil: - localError(n.info, "constant of type '" & typeToString(s.typ) & "' has no value") + localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value") result = newSymNode(s) else: result.typ = s.typ @@ -172,7 +172,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) = proc semConv(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - localError(n.info, errConvNeedsOneArg) + localError(c.config, n.info, errConvNeedsOneArg) return n result = newNodeI(nkConv, n.info) @@ -192,7 +192,7 @@ proc semConv(c: PContext, n: PNode): PNode = # special case to make MyObject(x = 3) produce a nicer error message: if n[1].kind == nkExprEqExpr and targetType.skipTypes(abstractPtrs).kind == tyObject: - localError(n.info, "object contruction uses ':', not '='") + localError(c.config, n.info, "object contruction uses ':', not '='") var op = semExprWithType(c, n.sons[1]) if targetType.isMetaType: let final = inferWithMetatype(c, targetType, op, true) @@ -219,7 +219,7 @@ proc semConv(c: PContext, n: PNode): PNode = of convNotLegal: result = fitNode(c, result.typ, result.sons[1], result.info) if result == nil: - localError(n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% + localError(c.config, n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% [op.typ.typeToString, result.typ.typeToString]) else: for i in countup(0, sonsLen(op) - 1): @@ -234,16 +234,16 @@ proc semConv(c: PContext, n: PNode): PNode = proc semCast(c: PContext, n: PNode): PNode = ## Semantically analyze a casting ("cast[type](param)") - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) let targetType = semTypeNode(c, n.sons[0], nil) let castedExpr = semExprWithType(c, n.sons[1]) if tfHasMeta in targetType.flags: - localError(n.sons[0].info, errCastToANonConcreteType, $targetType) + localError(c.config, n.sons[0].info, errCastToANonConcreteType, $targetType) if not isCastable(targetType, castedExpr.typ): let tar = $targetType let alt = typeToString(targetType, preferDesc) let msg = if tar != alt: tar & "=" & alt else: tar - localError(n.info, errExprCannotBeCastToX, msg) + localError(c.config, n.info, errExprCannotBeCastToX, msg) result = newNodeI(nkCast, n.info) result.typ = targetType addSon(result, copyTree(n.sons[0])) @@ -253,7 +253,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const opToStr: array[mLow..mHigh, string] = ["low", "high"] if sonsLen(n) != 2: - localError(n.info, errXExpectsTypeOrValue, opToStr[m]) + localError(c.config, n.info, errXExpectsTypeOrValue, opToStr[m]) else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc}) @@ -271,12 +271,12 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = # that could easily turn into an infinite recursion in semtypinst n.typ = makeTypeFromExpr(c, n.copyTree) else: - localError(n.info, errInvalidArgForX, opToStr[m]) + localError(c.config, n.info, errInvalidArgForX, opToStr[m]) result = n proc semSizeof(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - localError(n.info, errXExpectsTypeOrValue, "sizeof") + localError(c.config, n.info, errXExpectsTypeOrValue, "sizeof") else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) #restoreOldStyleType(n.sons[1]) @@ -315,7 +315,7 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode = if sonsLen(n) != 3: - localError(n.info, errXExpectsTwoArguments, "is") + localError(c.config, n.info, errXExpectsTwoArguments, "is") result = n n.typ = getSysType(tyBool) @@ -396,7 +396,7 @@ proc changeType(n: PNode, newType: PType, check: bool) = if check and n.kind != nkUInt64Lit: let value = n.intVal if value < firstOrd(newType) or value > lastOrd(newType): - localError(n.info, errGenerated, "cannot convert " & $value & + localError(c.config, n.info, errGenerated, "cannot convert " & $value & " to " & typeToString(newType)) else: discard n.typ = newType @@ -438,7 +438,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var idx = semConstExpr(c, x.sons[0]) idx = fitNode(c, indexType, idx, x.info) if lastIndex+1 != getOrdValue(idx): - localError(x.info, errInvalidOrderInArrayConstructor) + localError(c.config, x.info, errInvalidOrderInArrayConstructor) x = x.sons[1] let xx = semExprWithType(c, x, flags*{efAllowDestructor}) @@ -471,13 +471,13 @@ proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult proc newHiddenAddrTaken(c: PContext, n: PNode): PNode = if n.kind == nkHiddenDeref and not (gCmd == cmdCompileToCpp or sfCompileToCpp in c.module.flags): - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) result = n.sons[0] else: result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ)) addSon(result, n) if isAssignable(c, n) notin {arLValue, arLocalLValue}: - localError(n.info, errVarForOutParamNeededX, renderNotLValue(n)) + localError(c.config, n.info, errVarForOutParamNeededX, renderNotLValue(n)) proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = n @@ -489,7 +489,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = incl(n.sym.flags, sfAddrTaken) result = newHiddenAddrTaken(c, n) of nkDotExpr: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) if n.sons[1].kind != nkSym: internalError(n.info, "analyseIfAddressTaken") return @@ -497,7 +497,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = incl(n.sons[1].sym.flags, sfAddrTaken) result = newHiddenAddrTaken(c, n) of nkBracketExpr: - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}: if n.sons[0].kind == nkSym: incl(n.sons[0].sym.flags, sfAddrTaken) result = newHiddenAddrTaken(c, n) @@ -505,7 +505,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = newHiddenAddrTaken(c, n) proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) const FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl, mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, @@ -524,14 +524,14 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = let it = n[i] if isAssignable(c, it) notin {arLValue, arLocalLValue}: if it.kind != nkHiddenAddr: - localError(it.info, errVarForOutParamNeededX, $it) + localError(c.config, it.info, errVarForOutParamNeededX % $it) # bug #5113: disallow newSeq(result) where result is a 'var T': if n[0].sym.magic in {mNew, mNewFinalize, mNewSeq}: var arg = n[1] #.skipAddr if arg.kind == nkHiddenDeref: arg = arg[0] if arg.kind == nkSym and arg.sym.kind == skResult and arg.typ.skipTypes(abstractInst).kind in {tyVar, tyLent}: - localError(n.info, errXStackEscape, renderTree(n[1], {renderNoComments})) + localError(c.config, n.info, errXStackEscape % renderTree(n[1], {renderNoComments})) return for i in countup(1, sonsLen(n) - 1): @@ -560,14 +560,14 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = call.add(n.sons[0]) var allConst = true for i in 1 ..< n.len: - var a = getConstExpr(c.module, n.sons[i]) + var a = getConstExpr(c.module, n.sons[i], c.graph) if a == nil: allConst = false a = n.sons[i] if a.kind == nkHiddenStdConv: a = a.sons[1] call.add(a) if allConst: - result = semfold.getConstExpr(c.module, call) + result = semfold.getConstExpr(c.module, call, c.graph) if result.isNil: result = n else: return result @@ -607,7 +607,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = if sfCompileTime in callee.flags: result = evalStaticExpr(c.module, c.cache, c.graph.config, call, c.p.owner) if result.isNil: - localError(n.info, errCannotInterpretNodeX, renderTree(call)) + localError(c.config, n.info, errCannotInterpretNodeX, renderTree(call)) else: result = fixupTypeAfterEval(c, result, n) else: result = evalConstExpr(c.module, c.cache, c.graph.config, call) @@ -621,7 +621,7 @@ proc semStaticExpr(c: PContext, n: PNode): PNode = if a.findUnresolvedStatic != nil: return a result = evalStaticExpr(c.module, c.cache, c.graph.config, a, c.p.owner) if result.isNil: - localError(n.info, errCannotInterpretNodeX, renderTree(n)) + localError(c.config, n.info, errCannotInterpretNodeX, renderTree(n)) result = emptyNode else: result = fixupTypeAfterEval(c, result, a) @@ -648,7 +648,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, of skMacro, skTemplate: discard else: if callee.kind == skIterator and callee.id == c.p.owner.id: - localError(n.info, errRecursiveDependencyX, callee.name.s) + localError(c.config, n.info, errRecursiveDependencyX, callee.name.s) # error correction, prevents endless for loop elimination in transf. # See bug #2051: result.sons[0] = newSymNode(errorSym(c, n)) @@ -696,10 +696,10 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode = proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = nil - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) var prc = n.sons[0] if n.sons[0].kind == nkDotExpr: - checkSonsLen(n.sons[0], 2) + checkSonsLen(n.sons[0], 2, c.config) let n0 = semFieldAccess(c, n.sons[0]) if n0.kind == nkDotCall: # it is a static call! @@ -732,7 +732,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if m.state != csMatch: if errorOutputs == {}: # speed up error generation: - globalError(n.info, errTypeMismatch, "") + globalError(c.config, n.info, "type mismatch") return emptyNode else: var hasErrorType = false @@ -747,7 +747,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if not hasErrorType: add(msg, ">\n" & msgKindToString(errButExpected) & "\n" & typeToString(n.sons[0].typ)) - localError(n.info, errGenerated, msg) + localError(c.config, n.info, msg) return errorNode(c, n) result = nil else: @@ -794,7 +794,7 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode = if e != nil: add(result, newSymNode(e)) else: - localError(n.info, errSystemNeeds, "echo") + localError(c.config, n.info, "system needs: echo") add(result, errorNode(c, n)) add(result, n) result = semExpr(c, result) @@ -838,8 +838,8 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, result = lookupInRecordAndBuildCheck(c, n, r.sons[i], field, check) if result != nil: return of nkRecCase: - checkMinSonsLen(r, 2) - if (r.sons[0].kind != nkSym): illFormedAst(r) + checkMinSonsLen(r, 2, c.config) + if (r.sons[0].kind != nkSym): illFormedAst(r, c.config) result = lookupInRecordAndBuildCheck(c, n, r.sons[0], field, check) if result != nil: return let setType = createSetType(c, r.sons[0].typ) @@ -879,10 +879,10 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, addSon(notExpr, inExpr) addSon(check, notExpr) return - else: illFormedAst(it) + else: illFormedAst(it, c.config) of nkSym: if r.sym.name.id == field.id: result = r.sym - else: illFormedAst(n) + else: illFormedAst(n, c.config) const tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass} @@ -995,7 +995,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = result = newSymNode(s, n.info) of skVar, skLet, skResult, skForVar: if s.magic == mNimvm: - localError(n.info, "illegal context for 'nimvm' magic") + localError(c.config, n.info, "illegal context for 'nimvm' magic") markUsed(n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) @@ -1060,7 +1060,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if it's not a built-in field access - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) # tests/bind/tbindoverload.nim wants an early exit here, but seems to # work without now. template/tsymchoicefield doesn't like an early exit # here at all! @@ -1222,7 +1222,7 @@ proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode = for i in 0 .. n.len-1: result.add(n[i]) proc semDeref(c: PContext, n: PNode): PNode = - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) n.sons[0] = semExprWithType(c, n.sons[0]) result = n var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink}) @@ -1240,7 +1240,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result = newNodeIT(nkDerefExpr, x.info, x.typ) result.add(x[0]) return - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) # make sure we don't evaluate generic macros/templates n.sons[0] = semExprWithType(c, n.sons[0], {efNoEvaluateGeneric}) @@ -1277,7 +1277,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = {tyInt..tyInt64}: var idx = getOrdValue(n.sons[1]) if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)] - else: localError(n.info, errInvalidIndexValueForTuple) + else: localError(c.config, n.info, errInvalidIndexValueForTuple) result = n else: result = nil @@ -1340,10 +1340,10 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode = let root = exprRoot(n) if root != nil and root.owner == c.p.owner: if root.kind in {skLet, skVar, skTemp} and sfGlobal notin root.flags: - localError(n.info, "'$1' escapes its stack frame; context: '$2'; see $3/var_t_return.html" % [ + localError(c.config, n.info, "'$1' escapes its stack frame; context: '$2'; see $3/var_t_return.html" % [ root.name.s, renderTree(n, {renderNoComments}), explanationsBaseUrl]) elif root.kind == skParam and root.position != 0: - localError(n.info, "'$1' is not the first parameter; context: '$2'; see $3/var_t_return.html" % [ + localError(c.config, n.info, "'$1' is not the first parameter; context: '$2'; see $3/var_t_return.html" % [ root.name.s, renderTree(n, {renderNoComments}), explanationsBaseUrl]) case n.kind of nkHiddenAddr, nkAddr: return n @@ -1354,9 +1354,9 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode = let valid = isAssignable(c, n) if valid != arLValue: if valid == arLocalLValue: - localError(n.info, errXStackEscape, renderTree(n, {renderNoComments})) + localError(c.config, n.info, errXStackEscape, renderTree(n, {renderNoComments})) elif not isLent: - localError(n.info, errExprHasNoAddress) + localError(c.config, n.info, errExprHasNoAddress) result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ)) result.add(n) @@ -1373,7 +1373,7 @@ template resultTypeIsInferrable(typ: PType): untyped = typ.isMetaType and typ.kind != tyTypeDesc proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) var a = n.sons[0] case a.kind of nkDotExpr: @@ -1426,7 +1426,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = isAssignable(c, a) == arNone) or skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}: # Direct assignment to a discriminant is allowed! - localError(a.info, errXCannotBeAssignedTo, + localError(c.config, a.info, errXCannotBeAssignedTo, renderTree(a, {renderNoComments})) else: let @@ -1463,7 +1463,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = proc semReturn(c: PContext, n: PNode): PNode = result = n - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or ( c.p.owner.kind == skIterator and c.p.owner.typ.callConv == ccClosure): if n.sons[0].kind != nkEmpty: @@ -1477,9 +1477,9 @@ proc semReturn(c: PContext, n: PNode): PNode = if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym: n.sons[0] = ast.emptyNode else: - localError(n.info, errNoReturnTypeDeclared) + localError(c.config, n.info, errNoReturnTypeDeclared) else: - localError(n.info, errXNotAllowedHere, "\'return\'") + localError(c.config, n.info, errXNotAllowedHere, "\'return\'") proc semProcBody(c: PContext, n: PNode): PNode = openScope(c) @@ -1510,7 +1510,7 @@ proc semProcBody(c: PContext, n: PNode): PNode = c.p.resultSym.typ = errorType(c) c.p.owner.typ.sons[0] = nil else: - localError(c.p.resultSym.info, errCannotInferReturnType) + localError(c.config, c.p.resultSym.info, errCannotInferReturnType) closeScope(c) @@ -1534,16 +1534,16 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = var a = n.sons[0].sons[1] a.sons[i] = takeImplicitAddr(c, a.sons[i], false) else: - localError(n.sons[0].info, errXExpected, "tuple constructor") + localError(c.config, n.sons[0].info, errXExpected, "tuple constructor") else: discard proc semYield(c: PContext, n: PNode): PNode = result = n - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) if c.p.owner == nil or c.p.owner.kind != skIterator: - localError(n.info, errYieldNotAllowedHere) + localError(c.config, n.info, errYieldNotAllowedHere) elif c.p.inTryStmt > 0 and c.p.owner.typ.callConv != ccInline: - localError(n.info, errYieldNotAllowedInTryStmt) + localError(c.config, n.info, errYieldNotAllowedInTryStmt) elif n.sons[0].kind != nkEmpty: n.sons[0] = semExprWithType(c, n.sons[0]) # check for type compatibility: var iterType = c.p.owner.typ @@ -1559,9 +1559,9 @@ proc semYield(c: PContext, n: PNode): PNode = semYieldVarResult(c, n, restype) else: - localError(n.info, errCannotReturnExpr) + localError(c.config, n.info, errCannotReturnExpr) elif c.p.owner.typ.sons[0] != nil: - localError(n.info, errGenerated, "yield statement must yield a value") + localError(c.config, n.info, errGenerated, "yield statement must yield a value") proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym = if onlyCurrentScope: @@ -1576,7 +1576,7 @@ proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = of nkDotExpr: result = nil if onlyCurrentScope: return - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope) if m != nil and m.kind == skModule: let ident = considerQuotedIdent(n[1], n) @@ -1591,16 +1591,16 @@ proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym else: - localError(n.info, errIdentifierExpected, renderTree(n)) + localError(c.config, n.info, errIdentifierExpected, renderTree(n)) result = nil proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) # we replace this node by a 'true' or 'false' node: result = newIntNode(nkIntLit, 0) - if not onlyCurrentScope and considerQuotedIdent(n[0], n).s == "defined": + if not onlyCurrentScope and considerQuotedIdent(c.config, n[0], n).s == "defined": if n.sons[1].kind != nkIdent: - localError(n.info, "obsolete usage of 'defined', use 'declared' instead") + localError(c.config, n.info, "obsolete usage of 'defined', use 'declared' instead") elif condsyms.isDefined(n.sons[1].ident): result.intVal = 1 elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil: @@ -1618,12 +1618,12 @@ proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym = return errorSym(c, n[0]) if expandedSym.kind notin {skMacro, skTemplate}: - localError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s) + localError(c.config, n.info, errXisNoMacroOrTemplate, expandedSym.name.s) return errorSym(c, n[0]) result = expandedSym else: - localError(n.info, errXisNoMacroOrTemplate, n.renderTree) + localError(c.config, n.info, errXisNoMacroOrTemplate, n.renderTree) result = errorSym(c, n) proc expectString(c: PContext, n: PNode): string = @@ -1631,7 +1631,7 @@ proc expectString(c: PContext, n: PNode): string = if n.kind in nkStrKinds: return n.strVal else: - localError(n.info, errStringLiteralExpected) + localError(c.config, n.info, errStringLiteralExpected) proc getMagicSym(magic: TMagic): PSym = result = newSym(skProc, getIdent($magic), systemModule, gCodegenLineInfo) @@ -1668,9 +1668,9 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = inc cands symx = nextOverloadIter(o, c, headSymbol) if cands == 0: - localError(n.info, "expected a template that takes " & $(macroCall.len-1) & " arguments") + localError(c.config, n.info, "expected a template that takes " & $(macroCall.len-1) & " arguments") elif cands >= 2: - localError(n.info, "ambiguous symbol in 'getAst' context: " & $macroCall) + localError(c.config, n.info, "ambiguous symbol in 'getAst' context: " & $macroCall) else: let info = macroCall.sons[0].info macroCall.sons[0] = newSymNode(cand, info) @@ -1680,7 +1680,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = # we just perform overloading resolution here: #n.sons[1] = semOverloadedCall(c, macroCall, macroCall, {skTemplate, skMacro}) else: - localError(n.info, "getAst takes a call, but got " & n.renderTree) + localError(c.config, n.info, "getAst takes a call, but got " & n.renderTree) # Preserve the magic symbol in order to be handled in evals.nim internalAssert n.sons[0].sym.magic == mExpandToAst #n.typ = getSysSym("NimNode").typ # expandedSym.getReturnType @@ -1707,7 +1707,7 @@ proc processQuotations(n: var PNode, op: string, return if n.kind == nkPrefix: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) if n[0].kind == nkIdent: var examinedOp = n[0].ident.s if examinedOp == op: @@ -1734,7 +1734,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = # this will store the generated param names if quotedBlock.kind != nkStmtList: - localError(n.info, errXExpected, "block") + localError(c.config, n.info, errXExpected, "block") processQuotations(quotedBlock, op, quotes, ids) @@ -1829,7 +1829,7 @@ proc instantiateCreateFlowVarCall(c: PContext; t: PType; info: TLineInfo): PSym = let sym = magicsys.getCompilerProc("nimCreateFlowVar") if sym == nil: - localError(info, errSystemNeeds, "nimCreateFlowVar") + localError(c.config, info, errSystemNeeds, "nimCreateFlowVar") var bindings: TIdTable initIdTable(bindings) bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t) @@ -1858,10 +1858,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result = n case s.magic # magics that need special treatment of mAddr: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) result = semAddr(c, n.sons[1], s.name.s == "unsafeAddr") of mTypeOf: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) result = semTypeOf(c, n.sons[1]) #of mArrGet: result = semArrGet(c, n, flags) #of mArrPut: result = semArrPut(c, n, flags) @@ -1878,12 +1878,12 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mExpandToAst: result = semExpandToAst(c, n, s, flags) of mQuoteAst: result = semQuoteAst(c, n) of mAstToStr: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) result = newStrNodeT(renderTree(n[1], {renderNoComments}), n) result.typ = getSysType(tyString) of mParallel: if parallel notin c.features: - localError(n.info, "use the {.experimental.} pragma to enable 'parallel'") + localError(c.config, n.info, "use the {.experimental.} pragma to enable 'parallel'") result = setMs(n, s) var x = n.lastSon if x.kind == nkDo: x = x.sons[bodyPos] @@ -1969,7 +1969,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = var it = n.sons[i] case it.kind of nkElifBranch, nkElifExpr: - checkSonsLen(it, 2) + checkSonsLen(it, 2, c.config) if whenNimvm: if semCheck: it.sons[1] = semExpr(c, it.sons[1]) @@ -1984,14 +1984,14 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = elif e.intVal != 0 and result == nil: setResult(it.sons[1]) of nkElse, nkElseExpr: - checkSonsLen(it, 1) + checkSonsLen(it, 1, c.config) if result == nil or whenNimvm: if semCheck: it.sons[0] = semExpr(c, it.sons[0]) typ = commonType(typ, it.sons[0].typ) if result == nil: result = it.sons[0] - else: illFormedAst(n) + else: illFormedAst(n, c.config) if result == nil: result = newNodeI(nkEmpty, n.info) if whenNimvm: result.typ = typ @@ -2010,7 +2010,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = var typ: PType = nil for i in countup(0, sonsLen(n) - 1): if isRange(n.sons[i]): - checkSonsLen(n.sons[i], 3) + checkSonsLen(n.sons[i], 3, c.config) n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1]) n.sons[i].sons[2] = semExprWithType(c, n.sons[i].sons[2]) if typ == nil: @@ -2027,7 +2027,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = if typ == nil: typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) if not isOrdinalType(typ): - localError(n.info, errOrdinalTypeExpected) + localError(c.config, n.info, errOrdinalTypeExpected) typ = makeRangeType(c, 0, MaxSetElements-1, n.info) elif lengthOrd(typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements-1, n.info) @@ -2065,7 +2065,7 @@ proc semTableConstr(c: PContext, n: PNode): PNode = lastKey = i+1 - if lastKey != n.len: illFormedAst(n) + if lastKey != n.len: illFormedAst(n, c.config) result = semExpr(c, result) type @@ -2087,11 +2087,11 @@ proc checkPar(n: PNode): TParKind = if result == paTupleFields: if (n.sons[i].kind != nkExprColonExpr) or not (n.sons[i].sons[0].kind in {nkSym, nkIdent}): - localError(n.sons[i].info, errNamedExprExpected) + localError(c.config, n.sons[i].info, errNamedExprExpected) return paNone else: if n.sons[i].kind == nkExprColonExpr: - localError(n.sons[i].info, errNamedExprNotAllowed) + localError(c.config, n.sons[i].info, errNamedExprNotAllowed) return paNone proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -2101,12 +2101,12 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var ids = initIntSet() for i in countup(0, sonsLen(n) - 1): if n[i].kind != nkExprColonExpr or n[i][0].kind notin {nkSym, nkIdent}: - illFormedAst(n.sons[i]) + illFormedAst(n.sons[i], c.config) var id: PIdent if n.sons[i].sons[0].kind == nkIdent: id = n.sons[i].sons[0].ident else: id = n.sons[i].sons[0].sym.name if containsOrIncl(ids, id.id): - localError(n.sons[i].info, errFieldInitTwice, id.s) + localError(c.config, n.sons[i].info, errFieldInitTwice, id.s) n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1], flags*{efAllowDestructor}) var f = newSymS(skField, n.sons[i].sons[0], c) @@ -2140,7 +2140,7 @@ include semobjconstr proc semBlock(c: PContext, n: PNode): PNode = result = n inc(c.p.nestedBlockCounter) - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) openScope(c) # BUGFIX: label is in the scope of block! if n.sons[0].kind != nkEmpty: var labl = newSymG(skLabel, n.sons[0], c) @@ -2164,7 +2164,7 @@ proc semExport(c: PContext, n: PNode): PNode = var o: TOverloadIter var s = initOverloadIter(o, c, a) if s == nil: - localError(a.info, errGenerated, "cannot export: " & renderTree(a)) + localError(c.config, a.info, errGenerated, "cannot export: " & renderTree(a)) elif s.kind == skModule: # forward everything from that module: strTableAdd(c.module.tab, s) @@ -2217,7 +2217,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.kind == nkSym: markIndirect(c, result.sym) # if isGenericRoutine(result.sym): - # localError(n.info, errInstantiateXExplicitly, s.name.s) + # localError(c.config, n.info, errInstantiateXExplicitly, s.name.s) of nkSym: # because of the changed symbol binding, this does not mean that we # don't have to check the symbol for semantics here again! @@ -2277,7 +2277,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result.typ = makeTypeDesc(c, typ) of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: # check if it is an expression macro: - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) #when defined(nimsuggest): # if gIdeCmd == ideCon and gTrackPos == n.info: suggestExprNoCheck(c, n) let mode = if nfDotField in n.flags: {} else: {checkUndeclared} @@ -2333,7 +2333,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = else: result = semExpr(c, result, flags) of nkBracketExpr: - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) result = semArrayAccess(c, n, flags) of nkCurlyExpr: result = semExpr(c, buildOverloadedSubscripts(n, getIdent"{}"), flags) @@ -2372,24 +2372,24 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkDerefExpr: result = semDeref(c, n) of nkAddr: result = n - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) result = semAddr(c, n.sons[0]) of nkHiddenAddr, nkHiddenDeref: - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) n.sons[0] = semExpr(c, n.sons[0], flags) of nkCast: result = semCast(c, n) of nkIfExpr, nkIfStmt: result = semIf(c, n) of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkHiddenCallConv: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) considerGenSyms(c, n) of nkStringToCString, nkCStringToString, nkObjDownConv, nkObjUpConv: - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) considerGenSyms(c, n) of nkChckRangeF, nkChckRange64, nkChckRange: - checkSonsLen(n, 3) + checkSonsLen(n, 3, c.config) considerGenSyms(c, n) of nkCheckedFieldExpr: - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) considerGenSyms(c, n) of nkTableConstr: result = semTableConstr(c, n) @@ -2433,19 +2433,19 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # # works: if c.currentScope.depthLevel > 2 + c.compilesContextId: - localError(n.info, errXOnlyAtModuleScope, "import") + localError(c.config, n.info, errXOnlyAtModuleScope, "import") result = evalImport(c, n) of nkImportExceptStmt: - if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "import") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "import") result = evalImportExcept(c, n) of nkFromStmt: - if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "from") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "from") result = evalFrom(c, n) of nkIncludeStmt: - #if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "include") + #if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "include") result = evalInclude(c, n) of nkExportStmt, nkExportExceptStmt: - if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "export") result = semExport(c, n) of nkPragmaBlock: result = semPragmaBlock(c, n) @@ -2454,14 +2454,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkDefer: n.sons[0] = semExpr(c, n.sons[0]) if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]): - localError(n.info, errGenerated, "'defer' takes a 'void' expression") - #localError(n.info, errGenerated, "'defer' not allowed in this context") + localError(c.config, n.info, errGenerated, "'defer' takes a 'void' expression") + #localError(c.config, n.info, errGenerated, "'defer' not allowed in this context") of nkGotoState, nkState: - if n.len != 1 and n.len != 2: illFormedAst(n) + if n.len != 1 and n.len != 2: illFormedAst(n, c.config) for i in 0 ..< n.len: n.sons[i] = semExpr(c, n.sons[i]) of nkComesFrom: discard "ignore the comes from information for now" else: - localError(n.info, errInvalidExpressionX, + localError(c.config, n.info, errInvalidExpressionX, renderTree(n, {renderNoComments})) if result != nil: incl(result.flags, nfSem) diff --git a/compiler/semfields.nim b/compiler/semfields.nim index c5bc07d77..70efe8c4c 100644 --- a/compiler/semfields.nim +++ b/compiler/semfields.nim @@ -47,7 +47,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode = break else: if n.kind == nkContinueStmt: - localError(n.info, errGenerated, + localError(c.config, n.info, errGenerated, "'continue' not supported in a 'fields' loop") result = copyNode(n) newSons(result, sonsLen(n)) @@ -76,7 +76,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) = let L = forLoop.len let call = forLoop.sons[L-2] if call.len > 2: - localError(forLoop.info, errGenerated, + localError(c.config, forLoop.info, errGenerated, "parallel 'fields' iterator does not work for 'case' objects") return # iterate over the selector: @@ -107,7 +107,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = result = newNodeI(nkWhileStmt, n.info, 2) var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true") if trueSymbol == nil: - localError(n.info, errSystemNeeds, "true") + localError(c.config, n.info, errSystemNeeds, "true") trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(c), n.info) trueSymbol.typ = getSysType(tyBool) @@ -118,13 +118,13 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = var length = sonsLen(n) var call = n.sons[length-2] if length-2 != sonsLen(call)-1 + ord(m==mFieldPairs): - localError(n.info, errWrongNumberOfVariables) + localError(c.config, n.info, errWrongNumberOfVariables) return result const skippedTypesForFields = abstractVar - {tyTypeDesc} + tyUserTypeClasses var tupleTypeA = skipTypes(call.sons[1].typ, skippedTypesForFields) if tupleTypeA.kind notin {tyTuple, tyObject}: - localError(n.info, errGenerated, "no object or tuple type") + localError(c.config, n.info, errGenerated, "no object or tuple type") return result for i in 1..call.len-1: var tupleTypeB = skipTypes(call.sons[i].typ, skippedTypesForFields) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 32b385308..60c655bba 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -54,10 +54,13 @@ proc pushProcCon*(c: PContext; owner: PSym) = rawPushProcCon(c, owner) rawHandleSelf(c, owner) +const + errCannotInstantiateX = "cannot instantiate: '$1'" + iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym = - internalAssert n.kind == nkGenericParams + internalAssert c.config, n.kind == nkGenericParams for i, a in n.pairs: - internalAssert a.kind == nkSym + internalAssert c.config, a.kind == nkSym var q = a.sym if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses: continue @@ -71,10 +74,10 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym # later by semAsgn in return type inference scenario t = q.typ else: - localError(a.info, errCannotInstantiateX, s.name.s) + localError(c.config, a.info, errCannotInstantiateX & s.name.s) t = errorType(c) elif t.kind == tyGenericParam: - localError(a.info, errCannotInstantiateX, q.name.s) + localError(c.config, a.info, errCannotInstantiateX & q.name.s) t = errorType(c) elif t.kind == tyGenericInvocation: #t = instGenericContainer(c, a, t) @@ -145,7 +148,7 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) = freshGenSyms(b, result, orig, symMap) b = semProcBody(c, b) b = hloBody(c, b) - n.sons[bodyPos] = transformBody(c.module, b, result) + n.sons[bodyPos] = transformBody(c.graph, c.module, b, result) #echo "code instantiated ", result.name.s excl(result.flags, sfForward) dec c.inGenericInst @@ -174,7 +177,7 @@ proc sideEffectsCheck(c: PContext, s: PSym) = proc instGenericContainer(c: PContext, info: TLineInfo, header: PType, allowMetaTypes = false): PType = - internalAssert header.kind == tyGenericInvocation + internalAssert c.config, header.kind == tyGenericInvocation var typeMap: LayeredIdTable @@ -199,7 +202,7 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType, var param: PSym template paramSym(kind): untyped = - newSym(kind, genParam.sym.name, genericTyp.sym, genParam.sym.info) + newSym(kind, genParam.sym.name, genericTyp.sym, genParam.sym.info) if genParam.kind == tyStatic: param = paramSym skConst @@ -233,14 +236,12 @@ proc instantiateProcType(c: PContext, pt: TIdTable, # at this point semtypinst have to become part of sem, because it # will need to use openScope, addDecl, etc. #addDecl(c, prc) - pushInfoContext(info) var typeMap = initLayeredTypeMap(pt) var cl = initTypeVars(c, addr(typeMap), info, nil) var result = instCopyType(cl, prc.typ) let originalParams = result.n result.n = originalParams.shallowCopy - for i in 1 ..< result.len: # twrong_field_caching requires these 'resetIdTable' calls: if i > 1: @@ -248,7 +249,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable, resetIdTable(cl.localCache) result.sons[i] = replaceTypeVarsT(cl, result.sons[i]) propagateToOwner(result, result.sons[i]) - internalAssert originalParams[i].kind == nkSym + internalAssert c.config, originalParams[i].kind == nkSym when true: let oldParam = originalParams[i].sym let param = copySym(oldParam) @@ -285,9 +286,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, ## The `pt` parameter is a type-unsafe mapping table used to link generic ## parameters to their concrete types within the generic instance. # no need to instantiate generic templates/macros: - internalAssert fn.kind notin {skMacro, skTemplate} + internalAssert c.config, fn.kind notin {skMacro, skTemplate} # generates an instantiated proc - if c.instCounter > 1000: internalError(fn.ast.info, "nesting too deep") + if c.instCounter > 1000: internalError(c.config, fn.ast.info, "nesting too deep") inc(c.instCounter) # careful! we copy the whole AST including the possibly nil body! var n = copyTree(fn.ast) @@ -306,7 +307,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, openScope(c) let gp = n.sons[genericParamsPos] - internalAssert gp.kind != nkEmpty + internalAssert c.config, gp.kind != nkEmpty n.sons[namePos] = newSymNode(result) pushInfoContext(info) var entry = TInstantiation.new diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 3f0df0065..49dfb58f9 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -16,7 +16,7 @@ proc semAddr(c: PContext; n: PNode; isUnsafeAddr=false): PNode = if x.kind == nkSym: x.sym.flags.incl(sfAddrTaken) if isAssignable(c, x, isUnsafeAddr) notin {arLValue, arLocalLValue}: - localError(n.info, errExprHasNoAddress) + localError(c.config, n.info, errExprHasNoAddress) result.add x result.typ = makePtrType(c, x.typ) @@ -43,7 +43,7 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode = let x = copyTree(n) x.sons[0] = newIdentNode(getIdent"[]", n.info) bracketNotFoundError(c, x) - #localError(n.info, "could not resolve: " & $n) + #localError(c.config, n.info, "could not resolve: " & $n) result = n proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode = @@ -70,7 +70,7 @@ proc expectIntLit(c: PContext, n: PNode): int = let x = c.semConstExpr(c, n) case x.kind of nkIntLit..nkInt64Lit: result = int(x.intVal) - else: localError(n.info, errIntLiteralExpected) + else: localError(c.config, n.info, errIntLiteralExpected) proc semInstantiationInfo(c: PContext, n: PNode): PNode = result = newNodeIT(nkTupleConstr, n.info, n.typ) @@ -140,7 +140,7 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode = of "genericHead": var res = uninstantiate(operand) if res == operand and res.kind notin tyMagicGenerics: - localError(traitCall.info, + localError(c.config, traitCall.info, "genericHead expects a generic type. The given type was " & typeToString(operand)) return newType(tyError, context).toNode(traitCall.info) @@ -153,7 +153,7 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode = hasDestructor(t) result = newIntNodeT(ord(not complexObj), traitCall) else: - localError(traitCall.info, "unknown trait") + localError(c.config, traitCall.info, "unknown trait") result = emptyNode proc semTypeTraits(c: PContext, n: PNode): PNode = @@ -176,7 +176,7 @@ proc semOrd(c: PContext, n: PNode): PNode = elif parType.kind == tySet: result.typ = makeRangeType(c, firstOrd(parType), lastOrd(parType), n.info) else: - localError(n.info, errOrdinalTypeExpected) + localError(c.config, n.info, errOrdinalTypeExpected) result.typ = errorType(c) proc semBindSym(c: PContext, n: PNode): PNode = @@ -185,13 +185,13 @@ proc semBindSym(c: PContext, n: PNode): PNode = let sl = semConstExpr(c, n.sons[1]) if sl.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit}: - localError(n.sons[1].info, errStringLiteralExpected) + localError(c.config, n.sons[1].info, errStringLiteralExpected) return errorNode(c, n) let isMixin = semConstExpr(c, n.sons[2]) if isMixin.kind != nkIntLit or isMixin.intVal < 0 or isMixin.intVal > high(TSymChoiceRule).int: - localError(n.sons[2].info, errConstExprExpected) + localError(c.config, n.sons[2].info, errConstExprExpected) return errorNode(c, n) let id = newIdentNode(getIdent(sl.strVal), n.info) @@ -221,9 +221,9 @@ proc semOf(c: PContext, n: PNode): PNode = let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc}) if x.kind == tyTypeDesc or y.kind != tyTypeDesc: - localError(n.info, errXExpectsObjectTypes, "of") + localError(c.config, n.info, errXExpectsObjectTypes, "of") elif b.kind != tyObject or a.kind != tyObject: - localError(n.info, errXExpectsObjectTypes, "of") + localError(c.config, n.info, errXExpectsObjectTypes, "of") else: let diff = inheritanceDiff(a, b) # | returns: 0 iff `a` == `b` @@ -238,9 +238,9 @@ proc semOf(c: PContext, n: PNode): PNode = result.typ = getSysType(tyBool) return result elif diff == high(int): - localError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) + localError(c.config, n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) else: - localError(n.info, errXExpectsTwoArguments, "of") + localError(c.config, n.info, errXExpectsTwoArguments, "of") n.typ = getSysType(tyBool) result = n @@ -277,11 +277,11 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mDotDot: result = n of mRoof: - localError(n.info, "builtin roof operator is not supported anymore") + localError(c.config, n.info, "builtin roof operator is not supported anymore") of mPlugin: let plugin = getPlugin(n[0].sym) if plugin.isNil: - localError(n.info, "cannot find plugin " & n[0].sym.name.s) + localError(c.config, n.info, "cannot find plugin " & n[0].sym.name.s) result = n else: result = plugin(c, n) diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index cfa0fbd05..a47bc24ed 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -41,9 +41,9 @@ proc mergeInitStatus(existing: var InitStatus, newStatus: InitStatus) = proc invalidObjConstr(n: PNode) = if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s[0] == ':': - localError(n.info, "incorrect object construction syntax; use a space after the colon") + localError(c.config, n.info, "incorrect object construction syntax; use a space after the colon") else: - localError(n.info, "incorrect object construction syntax") + localError(c.config, n.info, "incorrect object construction syntax") proc locateFieldInInitExpr(field: PSym, initExpr: PNode): PNode = # Returns the assignment nkExprColonExpr node or nil @@ -63,7 +63,7 @@ proc semConstrField(c: PContext, flags: TExprFlags, if assignment != nil: if nfSem in assignment.flags: return assignment[1] if not fieldVisible(c, field): - localError(initExpr.info, + localError(c.config, initExpr.info, "the field '$1' is not accessible.", [field.name.s]) return @@ -130,7 +130,7 @@ proc missingMandatoryFields(fieldsRecList, initExpr: PNode): string = proc checkForMissingFields(recList, initExpr: PNode) = let missing = missingMandatoryFields(recList, initExpr) if missing != nil: - localError(initExpr.info, "fields not initialized: $1.", [missing]) + localError(c.config, initExpr.info, "fields not initialized: $1.", [missing]) proc semConstructFields(c: PContext, recNode: PNode, initExpr: PNode, flags: TExprFlags): InitStatus = @@ -164,7 +164,7 @@ proc semConstructFields(c: PContext, recNode: PNode, if selectedBranch != -1: let prevFields = fieldsPresentInBranch(selectedBranch) let currentFields = fieldsPresentInBranch(i) - localError(initExpr.info, + localError(c.config, initExpr.info, "The fields ($1) and ($2) cannot be initialized together, " & "because they are from conflicting branches in the case object.", [prevFields, currentFields]) @@ -179,7 +179,7 @@ proc semConstructFields(c: PContext, recNode: PNode, discriminator.sym, initExpr) if discriminatorVal == nil: let fields = fieldsPresentInBranch(selectedBranch) - localError(initExpr.info, + localError(c.config, initExpr.info, "you must provide a compile-time value for the discriminator '$1' " & "in order to prove that it's safe to initialize $2.", [discriminator.sym.name.s, fields]) @@ -189,7 +189,7 @@ proc semConstructFields(c: PContext, recNode: PNode, template wrongBranchError(i) = let fields = fieldsPresentInBranch(i) - localError(initExpr.info, + localError(c.config, initExpr.info, "a case selecting discriminator '$1' with value '$2' " & "appears in the object construction, but the field(s) $3 " & "are in conflict with this value.", @@ -263,13 +263,13 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = for child in n: result.add child if t == nil: - localError(n.info, errGenerated, "object constructor needs an object type") + localError(c.config, n.info, errGenerated, "object constructor needs an object type") return t = skipTypes(t, {tyGenericInst, tyAlias, tySink}) if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink}) if t.kind != tyObject: - localError(n.info, errGenerated, "object constructor needs an object type") + localError(c.config, n.info, errGenerated, "object constructor needs an object type") return # Check if the object is fully initialized by recursively testing each @@ -304,9 +304,9 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = for j in 1 ..< i: let prevId = considerQuotedIdent(result[j][0]) if prevId.id == id.id: - localError(field.info, errFieldInitTwice, id.s) + localError(c.config, field.info, errFieldInitTwice, id.s) return # 2) No such field exists in the constructed type - localError(field.info, errUndeclaredFieldX, id.s) + localError(c.config, field.info, errUndeclaredFieldX, id.s) return diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index b0bd4e0f6..f1a34785b 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -14,22 +14,22 @@ var enforceVoidContext = PType(kind: tyStmt) proc semDiscard(c: PContext, n: PNode): PNode = result = n - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) if n.sons[0].kind != nkEmpty: n.sons[0] = semExprWithType(c, n.sons[0]) if isEmptyType(n.sons[0].typ) or n.sons[0].typ.kind == tyNone or n.sons[0].kind == nkTypeOfExpr: - localError(n.info, errInvalidDiscard) + localError(c.config, n.info, errInvalidDiscard) proc semBreakOrContinue(c: PContext, n: PNode): PNode = result = n - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) if n.sons[0].kind != nkEmpty: if n.kind != nkContinueStmt: var s: PSym case n.sons[0].kind of nkIdent: s = lookUp(c, n.sons[0]) of nkSym: s = n.sons[0].sym - else: illFormedAst(n) + else: illFormedAst(n, c.config) s = getGenSym(c, s) if s.kind == skLabel and s.owner.id == c.p.owner.id: var x = newSymNode(s) @@ -39,22 +39,22 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode = suggestSym(x.info, s, c.graph.usageSym) styleCheckUse(x.info, s) else: - localError(n.info, errInvalidControlFlowX, s.name.s) + localError(c.config, n.info, errInvalidControlFlowX, s.name.s) else: - localError(n.info, errGenerated, "'continue' cannot have a label") + localError(c.config, n.info, errGenerated, "'continue' cannot have a label") elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): - localError(n.info, errInvalidControlFlowX, + localError(c.config, n.info, errInvalidControlFlowX, renderTree(n, {renderNoComments})) proc semAsm(con: PContext, n: PNode): PNode = - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) var marker = pragmaAsm(con, n.sons[0]) if marker == '\0': marker = '`' # default marker result = semAsmOrEmit(con, n, marker) proc semWhile(c: PContext, n: PNode): PNode = result = n - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) openScope(c) n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0])) inc(c.p.nestedLoopCounter) @@ -98,7 +98,7 @@ proc implicitlyDiscardable(n: PNode): bool = proc fixNilType(n: PNode) = if isAtom(n): if n.kind != nkNilLit and n.typ != nil: - localError(n.info, errDiscardValueX, n.typ.typeToString) + localError(c.config, n.info, errDiscardValueX, n.typ.typeToString) elif n.kind in {nkStmtList, nkStmtListExpr}: n.kind = nkStmtList for it in n: fixNilType(it) @@ -123,7 +123,7 @@ proc discardCheck(c: PContext, result: PNode) = s.add "; start of expression here: " & $result.info if result.typ.kind == tyProc: s.add "; for a function call use ()" - localError(n.info, s) + localError(c.config, n.info, s) proc semIf(c: PContext, n: PNode): PNode = result = n @@ -142,7 +142,7 @@ proc semIf(c: PContext, n: PNode): PNode = hasElse = true it.sons[0] = semExprBranchScope(c, it.sons[0]) typ = commonType(typ, it.sons[0]) - else: illFormedAst(it) + else: illFormedAst(it, c.config) if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse: for it in n: discardCheck(c, it.lastSon) result.kind = nkIfStmt @@ -158,7 +158,7 @@ proc semIf(c: PContext, n: PNode): PNode = proc semCase(c: PContext, n: PNode): PNode = result = n - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) openScope(c) n.sons[0] = semExprWithType(c, n.sons[0]) var chckCovered = false @@ -172,7 +172,7 @@ proc semCase(c: PContext, n: PNode): PNode = of tyFloat..tyFloat128, tyString, tyError: discard else: - localError(n.info, errSelectorMustBeOfCertainTypes) + localError(c.config, n.info, errSelectorMustBeOfCertainTypes) return for i in countup(1, sonsLen(n) - 1): var x = n.sons[i] @@ -181,14 +181,14 @@ proc semCase(c: PContext, n: PNode): PNode = suggestEnum(c, x, caseTyp) case x.kind of nkOfBranch: - checkMinSonsLen(x, 2) + checkMinSonsLen(x, 2, c.config) semCaseBranch(c, n, x, i, covered) var last = sonsLen(x)-1 x.sons[last] = semExprBranchScope(c, x.sons[last]) typ = commonType(typ, x.sons[last]) of nkElifBranch: chckCovered = false - checkSonsLen(x, 2) + checkSonsLen(x, 2, c.config) when newScopeForIf: openScope(c) x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0])) when not newScopeForIf: openScope(c) @@ -197,17 +197,17 @@ proc semCase(c: PContext, n: PNode): PNode = closeScope(c) of nkElse: chckCovered = false - checkSonsLen(x, 1) + checkSonsLen(x, 1, c.config) x.sons[0] = semExprBranchScope(c, x.sons[0]) typ = commonType(typ, x.sons[0]) hasElse = true else: - illFormedAst(x) + illFormedAst(x, c.config) if chckCovered: if covered == toCover(n.sons[0].typ): hasElse = true else: - localError(n.info, errNotAllCasesCovered) + localError(c.config, n.info, errNotAllCasesCovered) closeScope(c) if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse: for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) @@ -232,16 +232,16 @@ proc semTry(c: PContext, n: PNode): PNode = if isImportedException(typ): is_imported = true elif not isException(typ): - localError(typeNode.info, errExprCannotBeRaised) + localError(c.config, typeNode.info, errExprCannotBeRaised) if containsOrIncl(check, typ.id): - localError(typeNode.info, errExceptionAlreadyHandled) + localError(c.config, typeNode.info, errExceptionAlreadyHandled) typeNode = newNodeIT(nkType, typeNode.info, typ) is_imported result = n inc c.p.inTryStmt - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) var typ = commonTypeBegin n[0] = semExprBranchScope(c, n[0]) @@ -250,7 +250,7 @@ proc semTry(c: PContext, n: PNode): PNode = var last = sonsLen(n) - 1 for i in countup(1, last): let a = n.sons[i] - checkMinSonsLen(a, 1) + checkMinSonsLen(a, 1, c.config) openScope(c) if a.kind == nkExceptBranch: @@ -277,10 +277,10 @@ proc semTry(c: PContext, n: PNode): PNode = else: is_native = true if is_native and is_imported: - localError(a[0].info, "Mix of imported and native exception types is not allowed in one except branch") + localError(c.config, a[0].info, "Mix of imported and native exception types is not allowed in one except branch") elif a.kind != nkFinally: - illFormedAst(n) + illFormedAst(n, c.config) # last child of an nkExcept/nkFinally branch is a statement: a[^1] = semExprBranchScope(c, a[^1]) @@ -339,7 +339,7 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym = result = semIdentWithPragma(c, kind, n, {}) if result.owner.kind == skModule: incl(result.flags, sfGlobal) - suggestSym(n.info, result, c.graph.usageSym) + suggestSym(c.config, n.info, result, c.graph.usageSym) styleCheckDef(result) proc checkNilable(v: PSym) = @@ -369,13 +369,13 @@ proc isDiscardUnderscore(v: PSym): bool = proc semUsing(c: PContext; n: PNode): PNode = result = ast.emptyNode - if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "using") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "using") for i in countup(0, sonsLen(n)-1): var a = n.sons[i] if gCmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a) - checkMinSonsLen(a, 3) + if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a, c.config) + checkMinSonsLen(a, 3, c.config) var length = sonsLen(a) if a.sons[length-2].kind != nkEmpty: let typ = semTypeNode(c, a.sons[length-2], nil) @@ -384,10 +384,10 @@ proc semUsing(c: PContext; n: PNode): PNode = v.typ = typ strTableIncl(c.signatures, v) else: - localError(a.info, "'using' section must have a type") + localError(c.config, a.info, "'using' section must have a type") var def: PNode if a.sons[length-1].kind != nkEmpty: - localError(a.info, "'using' sections cannot contain assignments") + localError(c.config, a.info, "'using' sections cannot contain assignments") proc hasEmpty(typ: PType): bool = if typ.kind in {tySequence, tyArray, tySet}: @@ -416,7 +416,7 @@ proc makeDeref(n: PNode): PNode = proc fillPartialObject(c: PContext; n: PNode; typ: PType) = if n.len == 2: let x = semExprWithType(c, n[0]) - let y = considerQuotedIdent(n[1]) + let y = considerQuotedIdent(c.config, n[1]) let obj = x.typ.skipTypes(abstractPtrs) if obj.kind == tyObject and tfPartial in obj.flags: let field = newSym(skField, getIdent(y.s), obj.sym, n[1].info) @@ -427,14 +427,14 @@ proc fillPartialObject(c: PContext; n: PNode; typ: PType) = n.sons[1] = newSymNode(field) n.typ = field.typ else: - localError(n.info, "implicit object field construction " & + localError(c.config, n.info, "implicit object field construction " & "requires a .partial object, but got " & typeToString(obj)) else: - localError(n.info, "nkDotNode requires 2 children") + localError(c.config, n.info, "nkDotNode requires 2 children") proc setVarType(v: PSym, typ: PType) = if v.typ != nil and not sameTypeOrNil(v.typ, typ): - localError(v.info, "inconsistent typing for reintroduced symbol '" & + localError(c.config, v.info, "inconsistent typing for reintroduced symbol '" & v.name.s & "': previous type was: " & typeToString(v.typ) & "; new type is: " & typeToString(typ)) v.typ = typ @@ -447,8 +447,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var a = n.sons[i] if gCmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a) - checkMinSonsLen(a, 3) + if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a, c.config) + checkMinSonsLen(a, 3, c.config) var length = sonsLen(a) var typ: PType if a.sons[length-2].kind != nkEmpty: @@ -460,7 +460,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: # prevent the all too common 'var x = int' bug: - localError(def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?") + localError(c.config, def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?") def.typ = errorType(c) if typ != nil: if typ.isMetaType: @@ -476,12 +476,12 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass: typ = typ.lastSon if hasEmpty(typ): - localError(def.info, errCannotInferTypeOfTheLiteral, + localError(c.config, def.info, errCannotInferTypeOfTheLiteral, ($typ.kind).substr(2).toLowerAscii) elif typ.kind == tyProc and tfUnresolved in typ.flags: - localError(def.info, errProcHasNoConcreteType, def.renderTree) + localError(c.config, def.info, errProcHasNoConcreteType, def.renderTree) else: - if symkind == skLet: localError(a.info, errLetNeedsInit) + if symkind == skLet: localError(c.config, a.info, errLetNeedsInit) # this can only happen for errornous var statements: if typ == nil: continue @@ -490,9 +490,9 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink}) if a.kind == nkVarTuple: if tup.kind != tyTuple: - localError(a.info, errXExpected, "tuple") + localError(c.config, a.info, errXExpected, "tuple") elif length-2 != sonsLen(tup): - localError(a.info, errWrongNumberOfVariables) + localError(c.config, a.info, errWrongNumberOfVariables) b = newNodeI(nkVarTuple, a.info) newSons(b, length) b.sons[length-2] = a.sons[length-2] # keep type desc for doc generator @@ -527,10 +527,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if def.kind != nkEmpty: # this is needed for the evaluation pass and for the guard checking: v.ast = def - if sfThread in v.flags: localError(def.info, errThreadvarCannotInit) + if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit) setVarType(v, typ) b = newNodeI(nkIdentDefs, a.info) - if importantComments(): + if importantComments(c.config): # keep documentation information: b.comment = a.comment addSon(b, newSymNode(v)) @@ -554,15 +554,15 @@ proc semConst(c: PContext, n: PNode): PNode = var a = n.sons[i] if gCmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if (a.kind != nkConstDef): illFormedAst(a) - checkSonsLen(a, 3) + if a.kind != nkConstDef: illFormedAst(a, c.config) + checkSonsLen(a, 3, c.config) var v = semIdentDef(c, a.sons[0], skConst) var typ: PType = nil if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil) var def = semConstExpr(c, a.sons[2]) if def == nil: - localError(a.sons[2].info, errConstExprExpected) + localError(c.config, a.sons[2].info, errConstExprExpected) continue # check type compatibility between def.typ and typ: if typ != nil: @@ -570,10 +570,10 @@ proc semConst(c: PContext, n: PNode): PNode = else: typ = def.typ if typ == nil: - localError(a.sons[2].info, errConstExprExpected) + localError(c.config, a.sons[2].info, errConstExprExpected) continue if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit: - localError(a.info, "invalid type for const: " & typeToString(typ)) + localError(c.config, a.info, "invalid type for const: " & typeToString(typ)) continue setVarType(v, typ) v.ast = def # no need to copy @@ -619,9 +619,9 @@ proc semForVars(c: PContext, n: PNode): PNode = n.sons[0] = newSymNode(v) if sfGenSym notin v.flags: addForVarDecl(c, v) else: - localError(n.info, errWrongNumberOfVariables) + localError(c.config, n.info, errWrongNumberOfVariables) elif length-2 != sonsLen(iter): - localError(n.info, errWrongNumberOfVariables) + localError(c.config, n.info, errWrongNumberOfVariables) else: for i in countup(0, length - 3): var v = symForVar(c, n.sons[i]) @@ -671,7 +671,7 @@ proc handleForLoopMacro(c: PContext; n: PNode): PNode = if match == nil: match = symx else: - localError(n.info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ + localError(c.config, n.info, errAmbiguousCallXYZ % [ getProcHeader(match), getProcHeader(symx), $iterExpr]) symx = nextOverloadIter(o, c, headSymbol) @@ -685,7 +685,7 @@ proc handleForLoopMacro(c: PContext; n: PNode): PNode = else: result = nil proc semFor(c: PContext, n: PNode): PNode = - checkMinSonsLen(n, 3) + checkMinSonsLen(n, 3, c.config) var length = sonsLen(n) result = handleForLoopMacro(c, n) if result != nil: return result @@ -715,7 +715,7 @@ proc semFor(c: PContext, n: PNode): PNode = elif length == 4: n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2]) else: - localError(n.sons[length-2].info, errIteratorExpected) + localError(c.config, n.sons[length-2].info, errIteratorExpected) result = semForVars(c, n) else: result = semForVars(c, n) @@ -726,31 +726,31 @@ proc semFor(c: PContext, n: PNode): PNode = proc semRaise(c: PContext, n: PNode): PNode = result = n - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) if n[0].kind != nkEmpty: n[0] = semExprWithType(c, n[0]) let typ = n[0].typ if not isImportedException(typ): if typ.kind != tyRef or typ.lastSon.kind != tyObject: - localError(n.info, errExprCannotBeRaised) + localError(c.config, n.info, errExprCannotBeRaised) if not isException(typ.lastSon): - localError(n.info, "raised object of type $1 does not inherit from Exception", + localError(c.config, n.info, "raised object of type $1 does not inherit from Exception", [typeToString(typ)]) proc addGenericParamListToScope(c: PContext, n: PNode) = - if n.kind != nkGenericParams: illFormedAst(n) + if n.kind != nkGenericParams: illFormedAst(n, c.config) for i in countup(0, sonsLen(n)-1): var a = n.sons[i] if a.kind == nkSym: addDecl(c, a.sym) - else: illFormedAst(a) + else: illFormedAst(a, c.config) proc typeSectionTypeName(n: PNode): PNode = if n.kind == nkPragmaExpr: - if n.len == 0: illFormedAst(n) + if n.len == 0: illFormedAst(n, c.config) result = n.sons[0] else: result = n - if result.kind != nkSym: illFormedAst(n) + if result.kind != nkSym: illFormedAst(n, c.config) proc typeSectionLeftSidePass(c: PContext, n: PNode) = @@ -764,16 +764,16 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = suggestStmt(c, a) dec c.inTypeContext if a.kind == nkCommentStmt: continue - if a.kind != nkTypeDef: illFormedAst(a) - checkSonsLen(a, 3) + if a.kind != nkTypeDef: illFormedAst(a, c.config) + checkSonsLen(a, 3, c.config) let name = a.sons[0] var s: PSym if name.kind == nkDotExpr and a[2].kind == nkObjectTy: - let pkgName = considerQuotedIdent(name[0]) - let typName = considerQuotedIdent(name[1]) + let pkgName = considerQuotedIdent(c.config, name[0]) + let typName = considerQuotedIdent(c.config, name[1]) let pkg = c.graph.packageSyms.strTableGet(pkgName) if pkg.isNil or pkg.kind != skPackage: - localError(name.info, "unknown package name: " & pkgName.s) + localError(c.config, name.info, "unknown package name: " & pkgName.s) else: let typsym = pkg.tab.strTableGet(typName) if typsym.isNil: @@ -787,7 +787,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = s = typsym addInterfaceDecl(c, s) else: - localError(name.info, typsym.name.s & " is not a type that can be forwarded") + localError(c.config, name.info, typsym.name.s & " is not a type that can be forwarded") s = typsym else: s = semIdentDef(c, name, skType) @@ -799,7 +799,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = # check if the symbol already exists: let pkg = c.module.owner if not isTopLevel(c) or pkg.isNil: - localError(name.info, "only top level types in a package can be 'package'") + localError(c.config, name.info, "only top level types in a package can be 'package'") else: let typsym = pkg.tab.strTableGet(s.name) if typsym != nil: @@ -807,7 +807,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = typeCompleted(typsym) typsym.info = s.info else: - localError(name.info, "cannot complete type '" & s.name.s & "' twice; " & + localError(c.config, name.info, "cannot complete type '" & s.name.s & "' twice; " & "previous type completion was here: " & $typsym.info) s = typsym # add it here, so that recursive types are possible: @@ -822,7 +822,7 @@ proc checkCovariantParamsUsages(genericType: PType) = var body = genericType[^1] proc traverseSubTypes(t: PType): bool = - template error(msg) = localError(genericType.sym.info, msg) + template error(msg) = localError(c.config, genericType.sym.info, msg) result = false @@ -903,12 +903,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): illFormedAst(a) - checkSonsLen(a, 3) + if a.kind != nkTypeDef: illFormedAst(a, c.config) + checkSonsLen(a, 3, c.config) let name = typeSectionTypeName(a.sons[0]) var s = name.sym if s.magic == mNone and a.sons[2].kind == nkEmpty: - localError(a.info, errImplOfXexpected, s.name.s) + localError(c.config, a.info, errImplOfXexpected, s.name.s) if s.magic != mNone: processMagicType(c, s) if a.sons[1].kind != nkEmpty: # We have a generic type declaration here. In generic types, @@ -986,7 +986,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = proc checkForMetaFields(n: PNode) = template checkMeta(t) = if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: - localError(n.info, errTIsNotAConcreteType, t.typeToString) + localError(c.config, n.info, errTIsNotAConcreteType, t.typeToString) if n.isNil: return case n.kind @@ -1045,7 +1045,7 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode = var f = checkModuleName(n.sons[i]) if f != InvalidFileIDX: if containsOrIncl(c.includedFiles, f.int): - localError(n.info, errRecursiveDependencyX, f.toFilename) + localError(c.config, n.info, errRecursiveDependencyX, f.toFilename) else: let code = gIncludeFile(c.graph, c.module, f, c.cache) gatherStmts c, code, result @@ -1101,12 +1101,12 @@ proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = s.typ = semProcTypeNode(c, n, genericParams, nil, s.kind) if s.kind notin {skMacro, skTemplate}: if s.typ.sons[0] != nil and s.typ.sons[0].kind == tyStmt: - localError(n.info, errGenerated, "invalid return type: 'stmt'") + localError(c.config, n.info, "invalid return type: 'stmt'") proc addParams(c: PContext, n: PNode, kind: TSymKind) = for i in countup(1, sonsLen(n)-1): if n.sons[i].kind == nkSym: addParamOrResult(c, n.sons[i].sym, kind) - else: illFormedAst(n) + else: illFormedAst(n, c.config) proc semBorrow(c: PContext, n: PNode, s: PSym) = # search for the correct alias: @@ -1115,7 +1115,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) = # store the alias: n.sons[bodyPos] = newSymNode(b) else: - localError(n.info, errNoSymbolToBorrowFromFound) + localError(c.config, n.info, errNoSymbolToBorrowFromFound) proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) = if t != nil: @@ -1138,7 +1138,7 @@ proc lookupMacro(c: PContext, n: PNode): PSym = result = n.sym if result.kind notin {skMacro, skTemplate}: result = nil else: - result = searchInScopes(c, considerQuotedIdent(n), {skMacro, skTemplate}) + result = searchInScopes(c, considerQuotedIdent(c.config, n), {skMacro, skTemplate}) proc semProcAnnotation(c: PContext, prc: PNode; validPragmas: TSpecialWords): PNode = @@ -1150,11 +1150,11 @@ proc semProcAnnotation(c: PContext, prc: PNode; let m = lookupMacro(c, key) if m == nil: if key.kind == nkIdent and key.ident.id == ord(wDelegator): - if considerQuotedIdent(prc.sons[namePos]).s == "()": + if considerQuotedIdent(c.config, prc.sons[namePos]).s == "()": prc.sons[namePos] = newIdentNode(c.cache.idDelegator, prc.info) prc.sons[pragmasPos] = copyExcept(n, i) else: - localError(prc.info, errOnlyACallOpCanBeDelegator) + localError(c.config, prc.info, errOnlyACallOpCanBeDelegator) continue elif sfCustomPragma in m.flags: continue # semantic check for custom pragma happens later in semProcAux @@ -1199,7 +1199,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semProcAnnotation(c, n, lambdaPragmas) if result != nil: return result result = n - checkSonsLen(n, bodyPos + 1) + checkSonsLen(n, bodyPos + 1, c.config) var s: PSym if n[namePos].kind != nkSym: s = newSym(skProc, c.cache.idAnon, getCurrOwner(c), n.info) @@ -1228,7 +1228,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = s.options = gOptions if n.sons[bodyPos].kind != nkEmpty: if sfImportc in s.flags: - localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) + localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s) #if efDetermineType notin flags: # XXX not good enough; see tnamedparamanonproc.nim if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags): @@ -1239,10 +1239,10 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = n.sons[bodyPos] = transformBody(c.module, semBody, s) popProcCon(c) elif efOperand notin flags: - localError(n.info, errGenericLambdaNotAllowed) + localError(c.config, n.info, errGenericLambdaNotAllowed) sideEffectsCheck(c, s) else: - localError(n.info, errImplOfXexpected, s.name.s) + localError(c.config, n.info, errImplOfXexpected, s.name.s) closeScope(c) # close scope for parameters popOwner(c) result.typ = s.typ @@ -1267,7 +1267,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = for i in 1..= result.safeLen: return result @@ -1685,8 +1685,8 @@ proc semMethod(c: PContext, n: PNode): PNode = else: disp.ast[resultPos].sym.typ = ret proc semConverterDef(c: PContext, n: PNode): PNode = - if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "converter") - checkSonsLen(n, bodyPos + 1) + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "converter") + checkSonsLen(n, bodyPos + 1, c.config) result = semProcAux(c, n, skConverter, converterPragmas) # macros can transform converters to nothing: if namePos >= result.safeLen: return result @@ -1696,12 +1696,12 @@ proc semConverterDef(c: PContext, n: PNode): PNode = if result.kind != nkConverterDef: return var s = result.sons[namePos].sym var t = s.typ - if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "converter") - if sonsLen(t) != 2: localError(n.info, errXRequiresOneArgument, "converter") + if t.sons[0] == nil: localError(c.config, n.info, errXNeedsReturnType, "converter") + if sonsLen(t) != 2: localError(c.config, n.info, errXRequiresOneArgument, "converter") addConverter(c, s) proc semMacroDef(c: PContext, n: PNode): PNode = - checkSonsLen(n, bodyPos + 1) + checkSonsLen(n, bodyPos + 1, c.config) result = semProcAux(c, n, skMacro, macroPragmas) # macros can transform macros to nothing: if namePos >= result.safeLen: return result @@ -1716,18 +1716,18 @@ proc semMacroDef(c: PContext, n: PNode): PNode = let param = t.n.sons[i].sym if param.typ.kind != tyExpr: allUntyped = false if allUntyped: incl(s.flags, sfAllUntyped) - if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "macro") + if t.sons[0] == nil: localError(c.config, n.info, "macro needs a return type") if n.sons[bodyPos].kind == nkEmpty: - localError(n.info, errImplOfXexpected, s.name.s) + localError(c.config, n.info, errImplOfXexpected, s.name.s) proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) addSon(result, n) for i in countup(0, sonsLen(n) - 1): - var f = checkModuleName(n.sons[i]) + var f = checkModuleName(c.config, n.sons[i]) if f != InvalidFileIDX: if containsOrIncl(c.includedFiles, f.int): - localError(n.info, errRecursiveDependencyX, f.toFilename) + localError(c.config, n.info, errRecursiveDependencyX % f.toFilename) else: addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache))) excl(c.includedFiles, f.int) @@ -1777,7 +1777,7 @@ proc inferConceptStaticParam(c: PContext, inferred, n: PNode) = var typ = inferred.typ let res = semConstExpr(c, n) if not sameType(res.typ, typ.base): - localError(n.info, + localError(c.config, n.info, "cannot infer the concept parameter '%s', due to a type mismatch. " & "attempt to equate '%s' and '%s'.", [inferred.renderTree, $res.typ, $typ.base]) @@ -1818,7 +1818,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = let verdict = semConstExpr(c, n[i]) if verdict.intVal == 0: - localError(result.info, "concept predicate failed") + localError(c.config, result.info, "concept predicate failed") of tyUnknown: continue else: discard if n.sons[i].typ == enforceVoidContext: #or usesResult(n.sons[i]): @@ -1839,7 +1839,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = case n.sons[j].kind of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkBlockExpr, nkBlockStmt, nkState: discard - else: localError(n.sons[j].info, errStmtInvalidAfterReturn) + else: localError(c.config, n.sons[j].info, errStmtInvalidAfterReturn) else: discard if result.len == 1 and diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 454dadec0..352bc5c6b 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -26,6 +26,9 @@ discard """ a way to achieve lexical scoping at compile time. """ +const + errImplOfXNotAllowed = "implementation of '$1' is not allowed" + type TSymBinding = enum spNone, spGenSym, spInject @@ -60,7 +63,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = # (s.kind notin routineKinds or s.magic != mNone): # for instance 'nextTry' is both in tables.nim and astalgo.nim ... result = newSymNode(s, n.info) - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) else: # semantic checking requires a type; ``fitNode`` deals with it # appropriately @@ -91,20 +94,20 @@ proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode = else: for x in items(sc): toBind.incl(x.sym.id) else: - illFormedAst(a) + illFormedAst(a, c.config) result = newNodeI(nkEmpty, n.info) proc semMixinStmt(c: PContext, n: PNode, toMixin: var IntSet): PNode = for i in 0 ..< n.len: - toMixin.incl(considerQuotedIdent(n.sons[i]).id) + toMixin.incl(considerQuotedIdent(c.config, n.sons[i]).id) result = newNodeI(nkEmpty, n.info) -proc replaceIdentBySym(n: var PNode, s: PNode) = +proc replaceIdentBySym(c: PContext; n: var PNode, s: PNode) = case n.kind - of nkPostfix: replaceIdentBySym(n.sons[1], s) - of nkPragmaExpr: replaceIdentBySym(n.sons[0], s) + of nkPostfix: replaceIdentBySym(c, n.sons[1], s) + of nkPragmaExpr: replaceIdentBySym(c, n.sons[0], s) of nkIdent, nkAccQuoted, nkSym: n = s - else: illFormedAst(n) + else: illFormedAst(n, c.config) type TemplCtx = object @@ -129,7 +132,7 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode = result = newSymNode(s, n.info) of nkAccQuoted, nkSym: result = n else: - illFormedAst(n) + illFormedAst(n, c.c.config) result = n proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} = @@ -163,7 +166,7 @@ proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode = result.sons[i] = onlyReplaceParams(c, n.sons[i]) proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym = - result = newSym(kind, considerQuotedIdent(n), c.owner, n.info) + result = newSym(kind, considerQuotedIdent(c.c.config, n), c.owner, n.info) incl(result.flags, sfGenSym) incl(result.flags, sfShadowed) @@ -184,12 +187,12 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = n = onlyReplaceParams(c, n) return else: - illFormedAst(x) + illFormedAst(x, c.c.config) let ident = getIdentNode(c, x) if not isTemplParam(c, ident): c.toInject.incl(x.ident.id) else: - replaceIdentBySym(n, ident) + replaceIdentBySym(c.c, n, ident) else: let ident = getIdentNode(c, n) if not isTemplParam(c, ident): @@ -203,17 +206,17 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = # # We need to ensure that both 'a' produce the same gensym'ed symbol. # So we need only check the *current* scope. - let s = localSearchInScope(c.c, considerQuotedIdent ident) + let s = localSearchInScope(c.c, considerQuotedIdent(c.c.config, ident)) if s != nil and s.owner == c.owner and sfGenSym in s.flags: styleCheckUse(n.info, s) - replaceIdentBySym(n, newSymNode(s, n.info)) + replaceIdentBySym(c.c, n, newSymNode(s, n.info)) else: let local = newGenSym(k, ident, c) addPrelimDecl(c.c, local) styleCheckDef(n.info, local) - replaceIdentBySym(n, newSymNode(local, n.info)) + replaceIdentBySym(c.c, n, newSymNode(local, n.info)) else: - replaceIdentBySym(n, ident) + replaceIdentBySym(c.c, n, ident) proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = incl(s.flags, sfUsed) @@ -249,7 +252,7 @@ proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode = proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode = result = n - checkSonsLen(n, bodyPos + 1) + checkSonsLen(n, bodyPos + 1, c.c.config) # routines default to 'inject': if n.kind notin nkLambdaKinds and symBinding(n.sons[pragmasPos]) == spGenSym: let ident = getIdentNode(c, n.sons[namePos]) @@ -281,8 +284,8 @@ proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start=0) = for i in countup(start, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a) - checkMinSonsLen(a, 3) + if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.c.config) + checkMinSonsLen(a, 3, c.c.config) var L = sonsLen(a) when defined(nimsuggest): inc c.c.inTypeContext @@ -354,7 +357,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = n.sons[0] = semTemplBody(c, n.sons[0]) for i in countup(1, sonsLen(n)-1): var a = n.sons[i] - checkMinSonsLen(a, 1) + checkMinSonsLen(a, 1, c.c.config) var L = sonsLen(a) for j in countup(0, L-2): a.sons[j] = semTemplBody(c, a.sons[j]) @@ -371,7 +374,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = closeScope(c) closeScope(c) of nkBlockStmt, nkBlockExpr, nkBlockType: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.c.config) openScope(c) if n.sons[0].kind != nkEmpty: addLocalDecl(c, n.sons[0], skLabel) @@ -384,11 +387,11 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = n.sons[1] = semTemplBody(c, n.sons[1]) closeScope(c) of nkTryStmt: - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.c.config) n.sons[0] = semTemplBodyScope(c, n.sons[0]) for i in countup(1, sonsLen(n)-1): var a = n.sons[i] - checkMinSonsLen(a, 1) + checkMinSonsLen(a, 1, c.c.config) var L = sonsLen(a) openScope(c) for j in countup(0, L-2): @@ -402,15 +405,15 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkVarSection: semTemplSomeDecl(c, n, skVar) of nkLetSection: semTemplSomeDecl(c, n, skLet) of nkFormalParams: - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.c.config) n.sons[0] = semTemplBody(c, n.sons[0]) semTemplSomeDecl(c, n, skParam, 1) of nkConstSection: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkConstDef): illFormedAst(a) - checkSonsLen(a, 3) + if (a.kind != nkConstDef): illFormedAst(a, c.c.config) + checkSonsLen(a, 3, c.c.config) addLocalDecl(c, a.sons[0], skConst) a.sons[1] = semTemplBody(c, a.sons[1]) a.sons[2] = semTemplBody(c, a.sons[2]) @@ -418,14 +421,14 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): illFormedAst(a) - checkSonsLen(a, 3) + if (a.kind != nkTypeDef): illFormedAst(a, c.c.config) + checkSonsLen(a, 3, c.c.config) addLocalDecl(c, a.sons[0], skType) for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): illFormedAst(a) - checkSonsLen(a, 3) + if (a.kind != nkTypeDef): illFormedAst(a, c.c.config) + checkSonsLen(a, 3, c.c.config) if a.sons[1].kind != nkEmpty: openScope(c) a.sons[1] = semTemplBody(c, a.sons[1]) @@ -468,7 +471,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = for i in 0 ..< n.len: result.add(n[i]) result = semTemplBodySons(c, result) of nkAsgn, nkFastAsgn: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.c.config) let a = n.sons[0] let b = n.sons[1] @@ -610,9 +613,9 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = result = n if sfCustomPragma in s.flags: if n.sons[bodyPos].kind != nkEmpty: - localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) + localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s) elif n.sons[bodyPos].kind == nkEmpty: - localError(n.info, errImplOfXexpected, s.name.s) + localError(c.config, n.info, "implementation of '$1' expected" % s.name.s) var proto = searchForProc(c, c.currentScope, s) if proto == nil: addInterfaceOverloadableSymAt(c, c.currentScope, s) @@ -655,7 +658,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = if s != nil and s.owner == c.owner and s.kind == skParam: result = newParam(c, n, s) else: - localError(n.info, errInvalidExpression) + localError(c.c.config, n.info, "invalid expression") result = n proc stupidStmtListExpr(n: PNode): bool = @@ -675,7 +678,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = # we support '(pattern){x}' to bind a subpattern to a parameter 'x'; # '(pattern){|x}' does the same but the matches will be gathered in 'x' if n.len != 2: - localError(n.info, errInvalidExpression) + localError(c.c.config, n.info, "invalid expression") elif n.sons[1].kind == nkIdent: n.sons[0] = semPatternBody(c, n.sons[0]) n.sons[1] = expectParam(c, n.sons[1]) @@ -685,9 +688,9 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = n.sons[0] = semPatternBody(c, n.sons[0]) n.sons[1].sons[1] = expectParam(c, n.sons[1].sons[1]) else: - localError(n.info, errInvalidExpression) + localError(c.c.config, n.info, "invalid expression") else: - localError(n.info, errInvalidExpression) + localError(c.c.config, n.info, "invalid expression") of nkStmtList, nkStmtListExpr: if stupidStmtListExpr(n): result = semPatternBody(c, n.lastSon) @@ -759,5 +762,5 @@ proc semPattern(c: PContext, n: PNode): PNode = if result.len == 1: result = result.sons[0] elif result.len == 0: - localError(n.info, errInvalidExpression) + localError(c.config, n.info, "a pattern cannot be empty") closeScope(c) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 537319d66..f6d23403e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -10,6 +10,33 @@ # this module does the semantic checking of type declarations # included from sem.nim +const + errStringLiteralExpected = "string literal expected" + errIntLiteralExpected = "integer literal expected" + errWrongNumberOfVariables = "wrong number of variables" + errInvalidOrderInEnumX = "invalid order in enum '$1'" + errOrdinalTypeExpected = "ordinal type expected" + errSetTooBig = "set is too large" + errBaseTypeMustBeOrdinal = "base type of a set must be an ordinal" + errInheritanceOnlyWithNonFinalObjects = "inheritance only works with non-final objects" + errXExpectsOneTypeParam = "'$1' expects one type parameter" + errArrayExpectsTwoTypeParams = "array expects two type parameters" + errInvalidVisibilityX = "invalid visibility: '$1'" + errInitHereNotAllowed = "initialization not allowed here" + errXCannotBeAssignedTo = "'$1' cannot be assigned to" + errIteratorNotAllowed = "iterators can only be defined at the module's top level" + errXNeedsReturnType = "$1 needs a return type" + errNoReturnTypeDeclared = "no return type declared" + errTIsNotAConcreteType = "'$1' is not a concrete type" + errTypeExpected = "type expected" + errXOnlyAtModuleScope = "'$1' is only allowed at top level" + errDuplicateCaseLabel = "duplicate case label" + errMacroBodyDependsOnGenericTypes = "the macro body cannot be compiled, " & + "because the parameter '$1' has a generic type" + errIllegalRecursionInTypeX = "illegal recursion in type '$1'" + errNoGenericParamsAllowedForX = "no generic parameters allowed for $1" + errInOutFlagNotExtern = "the '$1' modifier can be used only with imported types" + proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType = if prev == nil: result = newTypeS(kind, c) @@ -34,11 +61,11 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = base = nil result = newOrPrevType(tyEnum, prev, c) result.n = newNodeI(nkEnumTy, n.info) - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) if n.sons[0].kind != nkEmpty: base = semTypeNode(c, n.sons[0].sons[0], nil) if base.kind != tyEnum: - localError(n.sons[0].info, errInheritanceOnlyWithEnums) + localError(c.config, n.sons[0].info, "inheritance only works with an enum") counter = lastOrd(base) + 1 rawAddSon(result, base) let isPure = result.sym != nil and sfPure in result.sym.flags @@ -58,9 +85,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}: x = getOrdValue(v.sons[0]) # first tuple part is the ordinal else: - localError(strVal.info, errStringLiteralExpected) + localError(c.config, strVal.info, errStringLiteralExpected) else: - localError(v.info, errWrongNumberOfVariables) + localError(c.config, v.info, errWrongNumberOfVariables) of tyString, tyCString: strVal = v x = counter @@ -69,7 +96,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if i != 1: if x != counter: incl(result.flags, tfEnumHasHoles) if x < counter: - localError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) + localError(c.config, n.sons[i].info, errInvalidOrderInEnumX % e.name.s) x = counter e.ast = strVal # might be nil counter = x @@ -78,7 +105,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = of nkIdent, nkAccQuoted: e = newSymS(skEnumField, n.sons[i], c) else: - illFormedAst(n[i]) + illFormedAst(n[i], c.config) e.typ = result e.position = int(counter) if e.position == 0: hasNull = true @@ -87,12 +114,13 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = incl(e.flags, sfExported) if not isPure: strTableAdd(c.module.tab, e) addSon(result.n, newSymNode(e)) + let conf = c.config styleCheckDef(e) if sfGenSym notin e.flags: if not isPure: addDecl(c, e) else: importPureEnumField(c, e) if isPure and strTableIncl(symbols, e): - wrongRedefinition(e.info, e.name.s) + wrongRedefinition(c, e.info, e.name.s) inc(counter) if not hasNull: incl(result.flags, tfNeedsInit) @@ -104,11 +132,11 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType = if base.kind in {tyGenericInst, tyAlias, tySink}: base = lastSon(base) if base.kind != tyGenericParam: if not isOrdinalType(base): - localError(n.info, errOrdinalTypeExpected) + localError(c.config, n.info, errOrdinalTypeExpected) elif lengthOrd(base) > MaxSetElements: - localError(n.info, errSetTooBig) + localError(c.config, n.info, errSetTooBig) else: - localError(n.info, errXExpectsOneTypeParam, "set") + localError(c.config, n.info, errXExpectsOneTypeParam % "set") addSonSkipIntLit(result, errorType(c)) proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, @@ -117,10 +145,10 @@ proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, if sonsLen(n) == 2: var base = semTypeNode(c, n.sons[1], nil) if base.kind == tyVoid: - localError(n.info, errTIsNotAConcreteType, typeToString(base)) + localError(c.config, n.info, errTIsNotAConcreteType % typeToString(base)) addSonSkipIntLit(result, base) else: - localError(n.info, errXExpectsOneTypeParam, kindStr) + localError(c.config, n.info, errXExpectsOneTypeParam % kindStr) addSonSkipIntLit(result, errorType(c)) proc semVarargs(c: PContext, n: PNode, prev: PType): PType = @@ -129,9 +157,9 @@ proc semVarargs(c: PContext, n: PNode, prev: PType): PType = var base = semTypeNode(c, n.sons[1], nil) addSonSkipIntLit(result, base) if sonsLen(n) == 3: - result.n = newIdentNode(considerQuotedIdent(n.sons[2]), n.sons[2].info) + result.n = newIdentNode(considerQuotedIdent(c.config, n.sons[2]), n.sons[2].info) else: - localError(n.info, errXExpectsOneTypeParam, "varargs") + localError(c.config, n.info, errXExpectsOneTypeParam % "varargs") addSonSkipIntLit(result, errorType(c)) proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = @@ -140,7 +168,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = else: let isCall = int ord(n.kind in nkCallKinds+{nkBracketExpr}) let n = if n[0].kind == nkBracket: n[0] else: n - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) var t = semTypeNode(c, n.lastSon, nil) if t.kind == tyTypeDesc and tfUnresolved notin t.flags: t = t.base @@ -155,7 +183,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = let region = semTypeNode(c, ni, nil) if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin { tyError, tyObject}: - message n[i].info, errGenerated, "region needs to be an object type" + message c.config, n[i].info, errGenerated, "region needs to be an object type" addSonSkipIntLit(result, region) addSonSkipIntLit(result, t) if tfPartial in result.flags: @@ -167,7 +195,7 @@ proc semVarType(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyVar, prev, c) var base = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc}) if base.kind == tyVar: - localError(n.info, errVarVarTypeNotAllowed) + localError(c.config, n.info, "type 'var var' is not allowed") base = base.sons[0] addSonSkipIntLit(result, base) else: @@ -181,7 +209,7 @@ proc semDistinct(c: PContext, n: PNode, prev: PType): PType = proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = assert isRange(n) - checkSonsLen(n, 3) + checkSonsLen(n, 3, c.config) result = newOrPrevType(tyRange, prev, c) result.n = newNodeI(nkRange, n.info) # always create a 'valid' range type, but overwrite it later @@ -189,7 +217,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = addSonSkipIntLit(result, errorType(c)) if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty): - localError(n.info, errRangeIsEmpty) + localError(c.config, n.info, "range is empty") var range: array[2, PNode] range[0] = semExprWithType(c, n[1], {efDetermineType}) @@ -204,11 +232,11 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = if not hasUnknownTypes: if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})): - localError(n.info, errPureTypeMismatch) + localError(c.config, n.info, "type mismatch") elif not rangeT[0].isOrdinalType: - localError(n.info, errOrdinalTypeExpected) + localError(c.config, n.info, "ordinal type expected") elif enumHasHoles(rangeT[0]): - localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s) + localError(c.config, n.info, "enum '$1' has holes" % typeToString(rangeT[0])) for i in 0..1: if hasGenericArguments(range[i]): @@ -218,7 +246,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = result.n.addSon semConstExpr(c, range[i]) if weakLeValue(result.n[0], result.n[1]) == impNo: - localError(n.info, errRangeIsEmpty) + localError(c.config, n.info, "range is empty") result[0] = rangeT[0] @@ -239,13 +267,13 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = n.sons[1].floatVal < 0.0: incl(result.flags, tfNeedsInit) else: - if n[1].kind == nkInfix and considerQuotedIdent(n[1][0]).s == "..<": - localError(n[0].info, "range types need to be constructed with '..', '..<' is not supported") + if n[1].kind == nkInfix and considerQuotedIdent(c.config, n[1][0]).s == "..<": + localError(c.config, n[0].info, "range types need to be constructed with '..', '..<' is not supported") else: - localError(n.sons[0].info, errRangeExpected) + localError(c.config, n.sons[0].info, "expected range") result = newOrPrevType(tyError, prev, c) else: - localError(n.info, errXExpectsOneTypeParam, "range") + localError(c.config, n.info, errXExpectsOneTypeParam % "range") result = newOrPrevType(tyError, prev, c) proc semArrayIndex(c: PContext, n: PNode): PType = @@ -257,7 +285,7 @@ proc semArrayIndex(c: PContext, n: PNode): PType = result = makeRangeWithStaticExpr(c, e.typ.n) elif e.kind in {nkIntLit..nkUInt64Lit}: if e.intVal < 0: - localError(n[1].info, + localError(c.config, n[1].info, "Array length can't be negative, but was " & $e.intVal) result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) elif e.kind == nkSym and e.typ.kind == tyStatic: @@ -265,12 +293,12 @@ proc semArrayIndex(c: PContext, n: PNode): PType = return semArrayIndex(c, e.sym.ast) if not isOrdinalType(e.typ.lastSon): let info = if n.safeLen > 1: n[1].info else: n.info - localError(info, errOrdinalTypeExpected) + localError(c.config, info, errOrdinalTypeExpected) result = makeRangeWithStaticExpr(c, e) if c.inGenericContext > 0: result.flags.incl tfUnresolved elif e.kind in nkCallKinds and hasGenericArguments(e): if not isOrdinalType(e.typ): - localError(n[1].info, errOrdinalTypeExpected) + localError(c.config, n[1].info, errOrdinalTypeExpected) # This is an int returning call, depending on an # yet unknown generic param (see tgenericshardcases). # We are going to construct a range type that will be @@ -286,7 +314,7 @@ proc semArrayIndex(c: PContext, n: PNode): PType = x.typ.skipTypes({tyTypeDesc})) else: result = x.typ.skipTypes({tyTypeDesc}) - #localError(n[1].info, errConstExprExpected) + #localError(c.config, n[1].info, errConstExprExpected) proc semArray(c: PContext, n: PNode, prev: PType): PType = var base: PType @@ -299,9 +327,9 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = if indxB.skipTypes({tyRange}).kind in {tyUInt, tyUInt64}: discard elif not isOrdinalType(indxB): - localError(n.sons[1].info, errOrdinalTypeExpected) + localError(c.config, n.sons[1].info, errOrdinalTypeExpected) elif enumHasHoles(indxB): - localError(n.sons[1].info, errEnumXHasHoles, + localError(c.config, n.sons[1].info, "enum '$1' has holes" % typeToString(indxB.skipTypes({tyRange}))) base = semTypeNode(c, n.sons[2], nil) # ensure we only construct a tyArray when there was no error (bug #3048): @@ -311,7 +339,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = rawAddSonNoPropagationOfTypeFlags(result, indx) addSonSkipIntLit(result, base) else: - localError(n.info, errArrayExpectsTwoTypeParams) + localError(c.config, n.info, errArrayExpectsTwoTypeParams) result = newOrPrevType(tyError, prev, c) proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = @@ -320,10 +348,10 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = var base = semTypeNode(c, n.sons[1], nil) if base.kind != tyGenericParam: if not isOrdinalType(base): - localError(n.sons[1].info, errOrdinalTypeExpected) + localError(c.config, n.sons[1].info, errOrdinalTypeExpected) addSonSkipIntLit(result, base) else: - localError(n.info, errXExpectsOneTypeParam, "ordinal") + localError(c.config, n.info, errXExpectsOneTypeParam % "ordinal") result = newOrPrevType(tyError, prev, c) proc semTypeIdent(c: PContext, n: PNode): PSym = @@ -334,7 +362,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = if result.isNil: result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if result != nil: - markUsed(n.info, result, c.graph.usageSym) + markUsed(c.config, n.info, result, c.graph.usageSym) styleCheckUse(n.info, result) if result.kind == skParam and result.typ.kind == tyTypeDesc: # This is a typedesc param. is it already bound? @@ -345,7 +373,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = if bound != nil: return bound return result if result.typ.sym == nil: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) return errorSym(c, n) result = result.typ.sym.copySym result.typ = copyType(result.typ, result.typ.owner, true) @@ -359,7 +387,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = result.typ.flags.excl tfWildcard return else: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) return errorSym(c, n) if result.kind != skType: @@ -370,7 +398,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = amb = nextOverloadIter(ov, c, n) if amb != nil: result = amb else: - if result.kind != skError: localError(n.info, errTypeExpected) + if result.kind != skError: localError(c.config, n.info, errTypeExpected) return errorSym(c, n) if result.typ.kind != tyGenericParam: # XXX get rid of this hack! @@ -385,12 +413,12 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = n.info = oldInfo n.typ = result.typ else: - localError(n.info, errIdentifierExpected) + localError(c.config, n.info, "identifier expected") result = errorSym(c, n) proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType = if sonsLen(n) == 0: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) result = newOrPrevType(tyTuple, prev, c) for it in n: addSonSkipIntLit(result, semTypeNode(c, it, nil)) @@ -403,23 +431,23 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = var counter = 0 for i in countup(ord(n.kind == nkBracketExpr), sonsLen(n) - 1): var a = n.sons[i] - if (a.kind != nkIdentDefs): illFormedAst(a) - checkMinSonsLen(a, 3) + if (a.kind != nkIdentDefs): illFormedAst(a, c.config) + checkMinSonsLen(a, 3, c.config) var length = sonsLen(a) if a.sons[length - 2].kind != nkEmpty: typ = semTypeNode(c, a.sons[length - 2], nil) else: - localError(a.info, errTypeExpected) + localError(c.config, a.info, errTypeExpected) typ = errorType(c) if a.sons[length - 1].kind != nkEmpty: - localError(a.sons[length - 1].info, errInitHereNotAllowed) + localError(c.config, a.sons[length - 1].info, errInitHereNotAllowed) for j in countup(0, length - 3): var field = newSymG(skField, a.sons[j], c) field.typ = typ field.position = counter inc(counter) if containsOrIncl(check, field.name.id): - localError(a.sons[j].info, errAttemptToRedefine, field.name.s) + localError(c.config, a.sons[j].info, "attempt to redefine: " & field.name.s) else: addSon(result.n, newSymNode(field)) addSonSkipIntLit(result, typ) @@ -434,23 +462,23 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, # for gensym'ed identifiers the identifier may already have been # transformed to a symbol and we need to use that here: result = newSymG(kind, n.sons[1], c) - var v = considerQuotedIdent(n.sons[0]) + var v = considerQuotedIdent(c.config, n.sons[0]) if sfExported in allowed and v.id == ord(wStar): incl(result.flags, sfExported) else: if not (sfExported in allowed): - localError(n.sons[0].info, errXOnlyAtModuleScope, "export") + localError(c.config, n.sons[0].info, errXOnlyAtModuleScope % "export") else: - localError(n.sons[0].info, errInvalidVisibilityX, renderTree(n[0])) + localError(c.config, n.sons[0].info, errInvalidVisibilityX % renderTree(n[0])) else: - illFormedAst(n) + illFormedAst(n, c.config) else: result = newSymG(kind, n, c) proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym = if n.kind == nkPragmaExpr: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) result = semIdentVis(c, kind, n.sons[0], allowed) case kind of skType: @@ -471,10 +499,10 @@ proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) = for j in countup(0, sonsLen(t.sons[i]) - 2): if i == branchIndex and j == currentEx: break if overlap(t.sons[i].sons[j].skipConv, ex): - localError(ex.info, errDuplicateCaseLabel) + localError(c.config, ex.info, errDuplicateCaseLabel) proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode = - checkMinSonsLen(t, 1) + checkMinSonsLen(t, 1, c.config) let ac = semConstExpr(c, a) let bc = semConstExpr(c, b) let at = fitNode(c, t.sons[0].typ, ac, ac.info).skipConvTakeType @@ -483,21 +511,21 @@ proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode result = newNodeI(nkRange, a.info) result.add(at) result.add(bt) - if emptyRange(ac, bc): localError(b.info, errRangeIsEmpty) + if emptyRange(ac, bc): localError(c.config, b.info, "range is empty") else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1 proc semCaseBranchRange(c: PContext, t, b: PNode, covered: var BiggestInt): PNode = - checkSonsLen(b, 3) + checkSonsLen(b, 3, c.config) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) proc semCaseBranchSetElem(c: PContext, t, b: PNode, covered: var BiggestInt): PNode = if isRange(b): - checkSonsLen(b, 3) + checkSonsLen(b, 3, c.config) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) elif b.kind == nkRange: - checkSonsLen(b, 2) + checkSonsLen(b, 2, c.config) result = semBranchRange(c, t, b.sons[0], b.sons[1], covered) else: result = fitNode(c, t.sons[0].typ, b, b.info) @@ -520,7 +548,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, delSon(branch, 0) return elif r.kind notin {nkCurly, nkBracket} or len(r) == 0: - checkMinSonsLen(t, 1) + checkMinSonsLen(t, 1, c.config) branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r, r.info)) inc(covered) else: @@ -546,37 +574,37 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) = var a = copyNode(n) - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) semRecordNodeAux(c, n.sons[0], check, pos, a, rectype) if a.sons[0].kind != nkSym: - internalError("semRecordCase: discriminant is no symbol") + internalError(c.config, "semRecordCase: discriminant is no symbol") return incl(a.sons[0].sym.flags, sfDiscriminant) var covered: BiggestInt = 0 var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc}) if not isOrdinalType(typ): - localError(n.info, errSelectorMustBeOrdinal) + localError(c.config, n.info, "selector must be of an ordinal type") elif firstOrd(typ) != 0: - localError(n.info, errGenerated, "low(" & $a.sons[0].sym.name.s & + localError(c.config, n.info, "low(" & $a.sons[0].sym.name.s & ") must be 0 for discriminant") elif lengthOrd(typ) > 0x00007FFF: - localError(n.info, errLenXinvalid, a.sons[0].sym.name.s) + localError(c.config, n.info, "len($1) must be less than 32768" % a.sons[0].sym.name.s) var chckCovered = true for i in countup(1, sonsLen(n) - 1): var b = copyTree(n.sons[i]) addSon(a, b) case n.sons[i].kind of nkOfBranch: - checkMinSonsLen(b, 2) + checkMinSonsLen(b, 2, c.config) semCaseBranch(c, a, b, i, covered) of nkElse: chckCovered = false - checkSonsLen(b, 1) - else: illFormedAst(n) + checkSonsLen(b, 1, c.config) + else: illFormedAst(n, c.config) delSon(b, sonsLen(b) - 1) semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype) - if chckCovered and (covered != lengthOrd(a.sons[0].typ)): - localError(a.info, errNotAllCasesCovered) + if chckCovered and covered != lengthOrd(a.sons[0].typ): + localError(c.config, a.info, "not all cases are covered") addSon(father, a) proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, @@ -587,22 +615,22 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, var branch: PNode = nil # the branch to take for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] - if it == nil: illFormedAst(n) + if it == nil: illFormedAst(n, c.config) var idx = 1 case it.kind of nkElifBranch: - checkSonsLen(it, 2) + checkSonsLen(it, 2, c.config) if c.inGenericContext == 0: var e = semConstBoolExpr(c, it.sons[0]) - if e.kind != nkIntLit: internalError(e.info, "semRecordNodeAux") + if e.kind != nkIntLit: internalError(c.config, e.info, "semRecordNodeAux") elif e.intVal != 0 and branch == nil: branch = it.sons[1] else: it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0])) of nkElse: - checkSonsLen(it, 1) + checkSonsLen(it, 1, c.config) if branch == nil: branch = it.sons[0] idx = 0 - else: illFormedAst(n) + else: illFormedAst(n, c.config) if c.inGenericContext > 0: # use a new check intset here for each branch: var newCheck: IntSet @@ -626,16 +654,16 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, semRecordNodeAux(c, n.sons[i], check, pos, a, rectype) if a != father: addSon(father, a) of nkIdentDefs: - checkMinSonsLen(n, 3) + checkMinSonsLen(n, 3, c.config) var length = sonsLen(n) var a: PNode if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info) else: a = ast.emptyNode if n.sons[length-1].kind != nkEmpty: - localError(n.sons[length-1].info, errInitHereNotAllowed) + localError(c.config, n.sons[length-1].info, errInitHereNotAllowed) var typ: PType if n.sons[length-2].kind == nkEmpty: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) typ = errorType(c) else: typ = semTypeNode(c, n.sons[length-2], nil) @@ -654,7 +682,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, f.flags = f.flags + ({sfImportc, sfExportc} * fieldOwner.flags) inc(pos) if containsOrIncl(check, f.name.id): - localError(n.sons[i].info, errAttemptToRedefine, f.name.s) + localError(c.config, n.sons[i].info, "attempt to redefine: " & f.name.s) if a.kind == nkEmpty: addSon(father, newSymNode(f)) else: addSon(a, newSymNode(f)) styleCheckDef(f) @@ -664,29 +692,29 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, # inherited from generic/partial specialized parent second check. # There is no branch validity check here if containsOrIncl(check, n.sym.name.id): - localError(n.info, errAttemptToRedefine, n.sym.name.s) + localError(c.config, n.info, "attempt to redefine: " & n.sym.name.s) addSon(father, n) of nkEmpty: discard - else: illFormedAst(n) + else: illFormedAst(n, c.config) proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, n: PNode) = case n.kind of nkRecCase: - if (n.sons[0].kind != nkSym): internalError(n.info, "addInheritedFieldsAux") + if (n.sons[0].kind != nkSym): internalError(c.config, n.info, "addInheritedFieldsAux") addInheritedFieldsAux(c, check, pos, n.sons[0]) for i in countup(1, sonsLen(n) - 1): case n.sons[i].kind of nkOfBranch, nkElse: addInheritedFieldsAux(c, check, pos, lastSon(n.sons[i])) - else: internalError(n.info, "addInheritedFieldsAux(record case branch)") + else: internalError(c.config, n.info, "addInheritedFieldsAux(record case branch)") of nkRecList: for i in countup(0, sonsLen(n) - 1): addInheritedFieldsAux(c, check, pos, n.sons[i]) of nkSym: incl(check, n.sym.name.id) inc(pos) - else: internalError(n.info, "addInheritedFieldsAux()") + else: internalError(c.config, n.info, "addInheritedFieldsAux()") proc skipGenericInvocation(t: PType): PType {.inline.} = result = t @@ -709,12 +737,12 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = var pos = 0 var base, realBase: PType = nil # n.sons[0] contains the pragmas (if any). We process these later... - checkSonsLen(n, 3) + checkSonsLen(n, 3, c.config) if n.sons[1].kind != nkEmpty: realBase = semTypeNode(c, n.sons[1].sons[0], nil) base = skipTypesOrNil(realBase, skipPtrs) if base.isNil: - localError(n.info, errIllegalRecursionInTypeX, "object") + localError(c.config, n.info, "cannot inherit from a type that is not an object type") else: var concreteBase = skipGenericInvocation(base) if concreteBase.kind in {tyObject, tyGenericParam, @@ -727,11 +755,11 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = addInheritedFields(c, check, pos, concreteBase) else: if concreteBase.kind != tyError: - localError(n.sons[1].info, "inheritance only works with non-final objects; " & + localError(c.config, n.sons[1].info, "inheritance only works with non-final objects; " & "to enable inheritance write '" & typeToString(realBase) & " of RootObj'") base = nil realBase = nil - if n.kind != nkObjectTy: internalError(n.info, "semObjectNode") + if n.kind != nkObjectTy: internalError(c.config, n.info, "semObjectNode") result = newOrPrevType(tyObject, prev, c) rawAddSon(result, realBase) if result.n.isNil: @@ -769,8 +797,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = addDecl(c, param) else: # within a macro, every param has the type NimNode! - let nn = if getCompilerProc("NimNode") != nil: getSysSym"NimNode" - else: getSysSym"PNimrodNode" + let nn = getSysSym(c.graph, param.info, "NimNode") var a = copySym(param) a.typ = nn.typ addDecl(c, a) @@ -780,7 +807,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = let typedescId = getIdent"typedesc" template shouldHaveMeta(t) = - internalAssert tfHasMeta in t.flags + internalAssert c.config, tfHasMeta in t.flags # result.lastSon.flags.incl tfHasMeta proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, @@ -838,7 +865,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if tfUnresolved in paramType.flags: return # already lifted let base = paramType.base.maybeLift if base.isMetaType and procKind == skMacro: - localError(info, errMacroBodyDependsOnGenericTypes, paramName) + localError(c.config, info, errMacroBodyDependsOnGenericTypes % paramName) result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base])) result.flags.incl({tfHasStatic, tfUnresolved}) @@ -870,7 +897,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, else: for i in 0 ..< paramType.len: if paramType.sons[i] == paramType: - globalError(info, errIllegalRecursionInTypeX, typeToString(paramType)) + globalError(c.config, info, errIllegalRecursionInTypeX % typeToString(paramType)) var lifted = liftingWalk(paramType.sons[i]) if lifted != nil: paramType.sons[i] = lifted @@ -939,7 +966,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result = addImplicitGeneric(copyType(paramType, getCurrOwner(c), false)) of tyGenericParam: - markUsed(info, paramType.sym, c.graph.usageSym) + markUsed(c.config, info, paramType.sym, c.graph.usageSym) styleCheckUse(info, paramType.sym) if tfWildcard in paramType.flags: paramType.flags.excl tfWildcard @@ -952,7 +979,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, proc semParamType(c: PContext, n: PNode, constraint: var PNode): PType = if n.kind == nkCurlyExpr: result = semTypeNode(c, n.sons[0], nil) - constraint = semNodeKindConstraints(n) + constraint = semNodeKindConstraints(n, c.config) else: result = semTypeNode(c, n, nil) @@ -971,7 +998,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, # for historical reasons (code grows) this is invoked for parameter # lists too and then 'isType' is false. var cl: IntSet - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) result = newProcType(c, n.info, prev) if genericParams != nil and sonsLen(genericParams) == 0: cl = initIntSet() @@ -985,8 +1012,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, # skip this parameter here. It'll then be re-generated in another LL # pass over this instantiation: if a.kind == nkSym and sfFromGeneric in a.sym.flags: continue - illFormedAst(a) - checkMinSonsLen(a, 3) + illFormedAst(a, c.config) + checkMinSonsLen(a, 3, c.config) var typ: PType = nil def: PNode = nil @@ -1009,7 +1036,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if not containsGenericType(typ): def = fitNode(c, typ, def, def.info) if not hasType and not hasDefault: - if isType: localError(a.info, "':' expected") + if isType: localError(c.config, a.info, "':' expected") if kind in {skTemplate, skMacro}: typ = newTypeS(tyExpr, c) elif skipTypes(typ, {tyGenericInst, tyAlias, tySink}).kind == tyVoid: @@ -1020,7 +1047,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, let param = strTableGet(c.signatures, arg.name) if param != nil: typ = param.typ else: - localError(a.info, "typeless parameters are obsolete") + localError(c.config, a.info, "typeless parameters are obsolete") typ = errorType(c) let lifted = liftParamType(c, kind, genericParams, typ, arg.name.s, arg.info) @@ -1031,7 +1058,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, inc(counter) if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def) if containsOrIncl(check, arg.name.id): - localError(a.sons[j].info, errAttemptToRedefine, arg.name.s) + localError(c.config, a.sons[j].info, "attempt to redefine: " & arg.name.s) addSon(result.n, newSymNode(arg)) rawAddSon(result, finalType) addParamOrResult(c, arg, kind) @@ -1085,7 +1112,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, n.sym.typ.flags.excl tfWildcard proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = - checkMinSonsLen(n, 1) + checkMinSonsLen(n, 1, c.config) var length = sonsLen(n) for i in countup(0, length - 2): n.sons[i] = semStmt(c, n.sons[i]) @@ -1098,7 +1125,7 @@ proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = proc semBlockType(c: PContext, n: PNode, prev: PType): PType = inc(c.p.nestedBlockCounter) - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) openScope(c) if n.sons[0].kind notin {nkEmpty, nkSym}: addDecl(c, newSymS(skLabel, n.sons[0], c)) @@ -1120,20 +1147,20 @@ proc semObjectTypeForInheritedGenericInst(c: PContext, n: PNode, t: PType) = realBase = t.sons[0] base = skipTypesOrNil(realBase, skipPtrs) if base.isNil: - localError(n.info, errIllegalRecursionInTypeX, "object") + localError(c.config, n.info, errIllegalRecursionInTypeX % "object") else: let concreteBase = skipGenericInvocation(base) if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: addInheritedFields(c, check, pos, concreteBase) else: if concreteBase.kind != tyError: - localError(n.info, errInheritanceOnlyWithNonFinalObjects) + localError(c.config, n.info, errInheritanceOnlyWithNonFinalObjects) var newf = newNodeI(nkRecList, n.info) semRecordNodeAux(c, t.n, check, pos, newf, t) proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if s.typ == nil: - localError(n.info, "cannot instantiate the '$1' $2" % + localError(c.config, n.info, "cannot instantiate the '$1' $2" % [s.name.s, ($s.kind).substr(2).toLowerAscii]) return newOrPrevType(tyError, prev, c) @@ -1146,7 +1173,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = template addToResult(typ) = if typ.isNil: - internalAssert false + internalAssert c.config, false rawAddSon(result, typ) else: addSonSkipIntLit(result, typ) @@ -1158,7 +1185,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = elif t.kind != tyGenericBody: # we likely got code of the form TypeA[TypeB] where TypeA is # not generic. - localError(n.info, errNoGenericParamsAllowedForX, s.name.s) + localError(c.config, n.info, errNoGenericParamsAllowedForX % s.name.s) return newOrPrevType(tyError, prev, c) else: var m = newCandidate(c, t) @@ -1169,7 +1196,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = let err = "cannot instantiate " & typeToString(t) & "\n" & "got: <" & describeArgs(c, n) & ">\n" & "but expected: <" & describeArgs(c, t.n, 0) & ">" - localError(n.info, errGenerated, err) + localError(c.config, n.info, errGenerated, err) return newOrPrevType(tyError, prev, c) var isConcrete = true @@ -1187,7 +1214,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if isConcrete: if s.ast == nil and s.typ.kind != tyCompositeTypeClass: # XXX: What kind of error is this? is it still relevant? - localError(n.info, errCannotInstantiateX, s.name.s) + localError(c.config, n.info, errCannotInstantiateX % s.name.s) result = newOrPrevType(tyError, prev, c) else: result = instGenericContainer(c, n.info, result, @@ -1197,7 +1224,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = # generic/partial specialized parent let tx = result.skipTypes(abstractPtrs, 50) if tx.isNil: - localError(n.info, "invalid recursion in type '$1'" % typeToString(result[0])) + localError(c.config, n.info, "invalid recursion in type '$1'" % typeToString(result[0])) return errorType(c) if tx != result and tx.kind == tyObject and tx.sons[0] != nil: semObjectTypeForInheritedGenericInst(c, n, tx) @@ -1226,7 +1253,7 @@ proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType = let alias = maybeAliasType(c, result, prev) if alias != nil: result = alias else: - localError(n.info, errTypeExpected, n.renderTree) + localError(c.config, n.info, "expected type, but got: " & n.renderTree) result = errorType(c) proc freshType(res, prev: PType): PType {.inline.} = @@ -1277,7 +1304,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType = dummyName = param dummyType = candidateTypeSlot - internalAssert dummyName.kind == nkIdent + internalAssert c.config, dummyName.kind == nkIdent var dummyParam = newSym(if modifier == tyTypeDesc: skType else: skVar, dummyName.ident, owner, param.info) dummyParam.typ = dummyType @@ -1289,7 +1316,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType = proc semProcTypeWithScope(c: PContext, n: PNode, prev: PType, kind: TSymKind): PType = - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) openScope(c) result = semProcTypeNode(c, n.sons[0], nil, prev, kind, isType=true) # start with 'ccClosure', but of course pragmas can overwrite this: @@ -1299,7 +1326,7 @@ proc semProcTypeWithScope(c: PContext, n: PNode, s.typ = result if n.sons[1].kind != nkEmpty and n.sons[1].len > 0: pragma(c, s, n.sons[1], procTypePragmas) - when useEffectSystem: setEffectsForProcType(result, n.sons[1]) + when useEffectSystem: setEffectsForProcType(c.graph, result, n.sons[1]) closeScope(c) proc maybeAliasType(c: PContext; typeExpr, prev: PType): PType = @@ -1320,7 +1347,7 @@ proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym = if n.kind == nkType: result = symFromType(n.typ, n.info) else: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) result = errorSym(c, n) proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = @@ -1332,7 +1359,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkEmpty: discard of nkTypeOfExpr: # for ``type(countup(1,3))``, see ``tests/ttoseq``. - checkSonsLen(n, 1) + checkSonsLen(n, 1, c.config) let typExpr = semExprWithType(c, n.sons[0], {efInTypeof}) fixupTypeOf(c, prev, typExpr) result = typExpr.typ @@ -1362,21 +1389,21 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = freshType(result, prev) result.flags.excl(tfNotNil) else: - localError(n.info, errGenerated, "invalid type") + localError(c.config, n.info, errGenerated, "invalid type") elif n[0].kind notin nkIdentKinds: result = semTypeExpr(c, n, prev) else: - let op = considerQuotedIdent(n.sons[0]) + let op = considerQuotedIdent(c.config, n.sons[0]) if op.id in {ord(wAnd), ord(wOr)} or op.s == "|": - checkSonsLen(n, 3) + checkSonsLen(n, 3, c.config) var t1 = semTypeNode(c, n.sons[1], nil) t2 = semTypeNode(c, n.sons[2], nil) if t1 == nil: - localError(n.sons[1].info, errTypeExpected) + localError(c.config, n.sons[1].info, errTypeExpected) result = newOrPrevType(tyError, prev, c) elif t2 == nil: - localError(n.sons[2].info, errTypeExpected) + localError(c.config, n.sons[2].info, errTypeExpected) result = newOrPrevType(tyError, prev, c) else: result = if op.id == ord(wAnd): makeAndType(c, t1, t2) @@ -1390,20 +1417,20 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = freshType(result, prev) result.flags.incl(tfNotNil) if notnil notin c.features: - localError(n.info, "enable the 'not nil' annotation with {.experimental: \"notnil\".}") + localError(c.config, n.info, "enable the 'not nil' annotation with {.experimental: \"notnil\".}") else: - localError(n.info, errGenerated, "invalid type") + localError(c.config, n.info, errGenerated, "invalid type") of 2: let negated = semTypeNode(c, n.sons[1], prev) result = makeNotType(c, negated) else: - localError(n.info, errGenerated, "invalid type") + localError(c.config, n.info, errGenerated, "invalid type") elif op.id == ord(wPtr): result = semAnyRef(c, n, tyPtr, prev) elif op.id == ord(wRef): result = semAnyRef(c, n, tyRef, prev) elif op.id == ord(wType): - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) let typExpr = semExprWithType(c, n.sons[1], {efInTypeof}) fixupTypeOf(c, prev, typExpr) result = typExpr.typ @@ -1417,7 +1444,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = if whenResult.kind == nkStmtList: whenResult.kind = nkStmtListType result = semTypeNode(c, whenResult, prev) of nkBracketExpr: - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) var head = n.sons[0] var s = if head.kind notin nkCallKinds: semTypeIdent(c, head) else: symFromExpectedTypeNode(c, semExpr(c, head)) @@ -1444,7 +1471,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyVar, prev, c) var base = semTypeNode(c, n.sons[1], nil) if base.kind in {tyVar, tyLent}: - localError(n.info, errVarVarTypeNotAllowed) + localError(c.config, n.info, "type 'var var' is not allowed") base = base.sons[0] addSonSkipIntLit(result, base) of mRef: result = semAnyRef(c, n, tyRef, prev) @@ -1454,13 +1481,13 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkDotExpr: let typeExpr = semExpr(c, n) if typeExpr.typ.isNil: - localError(n.info, "object constructor needs an object type;" & + localError(c.config, n.info, "object constructor needs an object type;" & " for named arguments use '=' instead of ':'") result = errorType(c) elif typeExpr.typ.kind == tyFromExpr: result = typeExpr.typ elif typeExpr.typ.kind != tyTypeDesc: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) result = errorType(c) else: result = typeExpr.typ.base @@ -1476,10 +1503,10 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkIdent, nkAccQuoted: var s = semTypeIdent(c, n) if s.typ == nil: - if s.kind != skError: localError(n.info, errTypeExpected) + if s.kind != skError: localError(c.config, n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) elif s.kind == skParam and s.typ.kind == tyTypeDesc: - internalAssert s.typ.base.kind != tyNone and prev == nil + internalAssert c.config, s.typ.base.kind != tyNone and prev == nil result = s.typ.base elif prev == nil: result = s.typ @@ -1506,10 +1533,10 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: assignType(prev, t) result = prev - markUsed(n.info, n.sym, c.graph.usageSym) + markUsed(c.config, n.info, n.sym, c.graph.usageSym) styleCheckUse(n.info, n.sym) else: - if s.kind != skError: localError(n.info, errTypeExpected) + if s.kind != skError: localError(c.config, n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) of nkObjectTy: result = semObjectNode(c, n, prev) of nkTupleTy: result = semTuple(c, n, prev) @@ -1547,7 +1574,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkStmtListType: result = semStmtListType(c, n, prev) of nkBlockType: result = semBlockType(c, n, prev) else: - localError(n.info, errTypeExpected) + localError(c.config, n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) n.typ = result dec c.inTypeContext @@ -1600,10 +1627,10 @@ proc processMagicType(c: PContext, m: PSym) = of mChar: setMagicType(m, tyChar, 1) of mString: setMagicType(m, tyString, ptrSize) - rawAddSon(m.typ, getSysType(tyChar)) + rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar)) of mCstring: setMagicType(m, tyCString, ptrSize) - rawAddSon(m.typ, getSysType(tyChar)) + rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar)) of mPointer: setMagicType(m, tyPointer, ptrSize) of mEmptySet: setMagicType(m, tySet, 1) @@ -1649,8 +1676,8 @@ proc processMagicType(c: PContext, m: PSym) = case m.name.s of "lent": setMagicType(m, tyLent, ptrSize) of "sink": setMagicType(m, tySink, 0) - else: localError(m.info, errTypeExpected) - else: localError(m.info, errTypeExpected) + else: localError(c.config, m.info, errTypeExpected) + else: localError(c.config, m.info, errTypeExpected) proc semGenericConstraints(c: PContext, x: PType): PType = result = newTypeWithSons(c, tyGenericParam, @[x]) @@ -1658,11 +1685,11 @@ proc semGenericConstraints(c: PContext, x: PType): PType = proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = result = copyNode(n) if n.kind != nkGenericParams: - illFormedAst(n) + illFormedAst(n, c.config) return for i in countup(0, sonsLen(n)-1): var a = n.sons[i] - if a.kind != nkIdentDefs: illFormedAst(n) + if a.kind != nkIdentDefs: illFormedAst(n, c.config) let L = a.len var def = a[^1] let constraint = a[^2] @@ -1708,7 +1735,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = if paramName.safeLen == 2: if not nimEnableCovariance or paramName[0].ident.s == "in": if father == nil or sfImportc notin father.sym.flags: - localError(paramName.info, errInOutFlagNotExtern, paramName[0].ident.s) + localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0]) covarianceFlag = if paramName[0].ident.s == "in": tfContravariant else: tfCovariant if father != nil: father.flags.incl tfCovariant diff --git a/compiler/vm.nim b/compiler/vm.nim index 84057e656..5aa1517e4 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1676,7 +1676,7 @@ proc myProcess(c: PPassContext, n: PNode): PNode = let c = PCtx(c) # don't eval errornous code: if c.oldErrorCount == c.config.errorCounter: - evalStmt(PCtx(c), n) + evalStmt(c, n) result = emptyNode else: result = n -- cgit 1.4.1-2-gfad0 From 050789a8f4c3649adbd588f96023d63a9aabce45 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 12 May 2018 21:30:42 +0200 Subject: sem pass compiles again --- compiler/ccgliterals.nim | 2 +- compiler/ccgmerge.nim | 34 +++--- compiler/cgen.nim | 10 +- compiler/cgendata.nim | 3 + compiler/configuration.nim | 18 +-- compiler/magicsys.nim | 9 +- compiler/modulegraphs.nim | 9 +- compiler/sem.nim | 44 +++---- compiler/semexprs.nim | 295 +++++++++++++++++++++++---------------------- compiler/semmagic.nim | 42 +++---- compiler/semobjconstr.nim | 62 +++++----- compiler/semstmts.nim | 4 +- 12 files changed, 269 insertions(+), 263 deletions(-) (limited to 'compiler/semobjconstr.nim') diff --git a/compiler/ccgliterals.nim b/compiler/ccgliterals.nim index b17a5eedd..0bd00a696 100644 --- a/compiler/ccgliterals.nim +++ b/compiler/ccgliterals.nim @@ -15,7 +15,7 @@ template detectVersion(field, corename) = if m.g.field == 0: - let core = getCompilerProc(corename) + let core = getCompilerProc(m.g. corename) if core == nil or core.kind != skConst: m.g.field = 1 else: diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index f667be70f..4b4f9c0e6 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -45,28 +45,28 @@ const ] NimMergeEndMark = "/*\tNIM_merge_END:*/" -proc genSectionStart*(fs: TCFileSection): Rope = - if compilationCachePresent: +proc genSectionStart*(fs: TCFileSection; conf: ConfigRef): Rope = + if compilationCachePresent(conf): result = rope(tnl) add(result, "/*\t") add(result, CFileSectionNames[fs]) add(result, ":*/") add(result, tnl) -proc genSectionEnd*(fs: TCFileSection): Rope = - if compilationCachePresent: +proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope = + if compilationCachePresent(conf): result = rope(NimMergeEndMark & tnl) -proc genSectionStart*(ps: TCProcSection): Rope = - if compilationCachePresent: +proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope = + if compilationCachePresent(conf): result = rope(tnl) add(result, "/*\t") add(result, CProcSectionNames[ps]) add(result, ":*/") add(result, tnl) -proc genSectionEnd*(ps: TCProcSection): Rope = - if compilationCachePresent: +proc genSectionEnd*(ps: TCProcSection; conf: ConfigRef): Rope = + if compilationCachePresent(conf): result = rope(NimMergeEndMark & tnl) proc writeTypeCache(a: TypeCache, s: var string) = @@ -96,7 +96,7 @@ proc writeIntSet(a: IntSet, s: var string) = s.add('}') proc genMergeInfo*(m: BModule): Rope = - if not compilationCachePresent: return nil + if not compilationCachePresent(m.config): return nil var s = "/*\tNIM_merge_INFO:" s.add(tnl) s.add("typeCache:{") @@ -161,7 +161,7 @@ proc readVerbatimSection(L: var TBaseLexer): Rope = buf = L.buf r.add(tnl) of '\0': - internalError("ccgmerge: expected: " & NimMergeEndMark) + doAssert(false, "ccgmerge: expected: " & NimMergeEndMark) break else: if atEndMark(buf, pos): @@ -179,7 +179,7 @@ proc readKey(L: var TBaseLexer, result: var string) = while buf[pos] in IdentChars: result.add(buf[pos]) inc pos - if buf[pos] != ':': internalError("ccgmerge: ':' expected") + if buf[pos] != ':': doAssert(false, "ccgmerge: ':' expected") L.bufpos = pos + 1 # skip ':' proc newFakeType(id: int): PType = @@ -187,12 +187,12 @@ proc newFakeType(id: int): PType = result.id = id proc readTypeCache(L: var TBaseLexer, result: var TypeCache) = - if ^L.bufpos != '{': internalError("ccgmerge: '{' expected") + if ^L.bufpos != '{': doAssert(false, "ccgmerge: '{' expected") inc L.bufpos while ^L.bufpos != '}': skipWhite(L) var key = decodeStr(L.buf, L.bufpos) - if ^L.bufpos != ':': internalError("ccgmerge: ':' expected") + if ^L.bufpos != ':': doAssert(false, "ccgmerge: ':' expected") inc L.bufpos var value = decodeStr(L.buf, L.bufpos) # XXX implement me @@ -201,7 +201,7 @@ proc readTypeCache(L: var TBaseLexer, result: var TypeCache) = inc L.bufpos proc readIntSet(L: var TBaseLexer, result: var IntSet) = - if ^L.bufpos != '{': internalError("ccgmerge: '{' expected") + if ^L.bufpos != '{': doAssert(false, "ccgmerge: '{' expected") inc L.bufpos while ^L.bufpos != '}': skipWhite(L) @@ -225,7 +225,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) = of "labels": m.labels = decodeVInt(L.buf, L.bufpos) of "flags": m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0) - else: internalError("ccgmerge: unknown key: " & k) + else: doAssert(false, "ccgmerge: unknown key: " & k) when not defined(nimhygiene): {.pragma: inject.} @@ -275,9 +275,9 @@ proc readMergeSections(cfilename: string, m: var TMergeSections) = if sectionB >= 0 and sectionB <= high(TCProcSection).int: m.p[TCProcSection(sectionB)] = verbatim else: - internalError("ccgmerge: unknown section: " & k) + doAssert(false, "ccgmerge: unknown section: " & k) else: - internalError("ccgmerge: '*/' expected") + doAssert(false, "ccgmerge: '*/' expected") proc mergeRequired*(m: BModule): bool = for i in cfsHeaders..cfsProcs: diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 693930fbc..78f6099ec 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -115,7 +115,7 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope = if i >= length or not (frmt[i] in {'0'..'9'}): break num = j if j > high(args) + 1: - internalError("ropes: invalid format string $" & $j) + internalError(m.config, "ropes: invalid format string $" & $j) add(result, args[j-1]) of 'n': if optLineDir notin gOptions: add(result, rnl) @@ -123,7 +123,7 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope = of 'N': add(result, rnl) inc(i) - else: internalError("ropes: invalid format string $" & frmt[i]) + else: internalError(m.config, "ropes: invalid format string $" & frmt[i]) elif frmt[i] == '#' and frmt[i+1] in IdentStartChars: inc(i) var j = i @@ -148,12 +148,10 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope = template rfmt(m: BModule, fmt: string, args: varargs[Rope]): untyped = ropecg(m, fmt, args) -var indent = "\t".rope - proc indentLine(p: BProc, r: Rope): Rope = result = r for i in countup(0, p.blocks.len-1): - prepend(result, indent) + prepend(result, "\t".rope) proc appcg(m: BModule, c: var Rope, frmt: FormatStr, args: varargs[Rope]) = @@ -214,7 +212,7 @@ proc genLineDir(p: BProc, t: PNode) = let line = tt.info.safeLineNm if optEmbedOrigSrc in gGlobalOptions: - add(p.s(cpsStmts), ~"//" & tt.info.sourceLine & rnl) + add(p.s(cpsStmts), ~"//" & sourceLine(p.config, tt.info) & rnl) genCLineDir(p.s(cpsStmts), tt.info.toFullPath, line) if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and (p.prc == nil or sfPure notin p.prc.flags): diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index f8167acdc..b43938132 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -148,6 +148,9 @@ type g*: BModuleList ndi*: NdiFile +template config*(m: BModule): ConfigRef = m.g.config +template config*(p: BProc): ConfigRef = p.module.g.config + proc includeHeader*(this: BModule; header: string) = if not this.headerFiles.contains header: this.headerFiles.add header diff --git a/compiler/configuration.nim b/compiler/configuration.nim index 86e3cabf2..fb28ef675 100644 --- a/compiler/configuration.nim +++ b/compiler/configuration.nim @@ -219,7 +219,7 @@ errExecutionOfProgramFailed: "execution of an external program failed: '$1'", errNotOverloadable: , errInvalidArgForX: "invalid argument for '$1'", errStmtHasNoEffect: "statement has no effect", -errXExpectsTypeOrValue: "'$1' expects a type or value", +, errXExpectsArrayType: "'$1' expects an array type", errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet", errExprXAmbiguous: "expression '$1' ambiguous in this context", @@ -229,19 +229,17 @@ errOverOrUnderflow: , errCannotEvalXBecauseIncompletelyDefined: , errChrExpectsRange0_255: "'chr' expects an int in the range 0..255", errDynlibRequiresExportc: "'dynlib' requires 'exportc'", -errUndeclaredFieldX: "undeclared field: '$1'", errNilAccess: "attempt to access a nil address", errIndexOutOfBounds: "index out of bounds", errIndexTypesDoNotMatch: "index types do not match", errBracketsInvalidForType: "'[]' operator invalid for this type", errValueOutOfSetBounds: "value out of set bounds", -errFieldInitTwice: "field initialized twice: '$1'", errFieldNotInit: "field '$1' not initialized", errExprXCannotBeCalled: "expression '$1' cannot be called", errExprHasNoType: "expression has no type", -errExprXHasNoType: "expression '$1' has no type (or is ambiguous)", +errExprXHasNoType:, errCastNotInSafeMode: "'cast' not allowed in safe mode", -errExprCannotBeCastToX: "expression cannot be cast to $1", +errExprCannotBeCastToX: , errCommaOrParRiExpected: "',' or ')' expected", errCurlyLeOrParLeExpected: "'{' or '(' expected", errSectionExpected: "section ('type', 'proc', etc.) expected", @@ -268,10 +266,6 @@ errSizeTooBig: "computing the type's size produced an overflow", errInheritanceOnlyWithEnums: "inheritance only works with an enum", errIllegalRecursionInTypeX:, errCannotInstantiateX: "cannot instantiate: '$1'", -errExprHasNoAddress: "expression has no address", -errXStackEscape: "address of '$1' may not escape its stack frame", -errVarForOutParamNeededX: "for a 'var' type a variable needs to be passed; but '$1' is immutable", -errPureTypeMismatch: "type mismatch", errTypeMismatch: "type mismatch: got <", errButExpected: "but expected one of: ", errButExpectedX: "but expected '$1'", @@ -285,7 +279,7 @@ errImplOfXexpected: , errIllegalConvFromXtoY: , errCannotBindXTwice: "cannot bind parameter '$1' twice", -errInvalidOrderInArrayConstructor: "invalid order in array constructor", +errInvalidOrderInArrayConstructor: , errInvalidOrderInEnumX: "invalid order in enum '$1'", errEnumXHasHoles: "enum '$1' has holes", errExceptExpected: "'except' or 'finally' expected", @@ -310,8 +304,7 @@ errCircumNeedsPointer: "'[]' needs a pointer or reference type", errInvalidExpression: "invalid expression", errInvalidExpressionX: "invalid expression: '$1'", errEnumHasNoValueX: "enum has no value '$1'", -errNamedExprExpected: "named expression expected", -errNamedExprNotAllowed: "named expression not allowed here", +, errNoCommand: "no command given", errInvalidCommandX: "invalid command: '$1'", errXNeedsParamObjectType: , @@ -347,7 +340,6 @@ errXcanNeverBeOfThisSubtype: "'$1' can never be of this subtype", errTooManyIterations: "interpretation requires too many iterations; " & "if you are sure this is not a bug in your code edit " & "compiler/vmdef.MaxLoopIterations and rebuild the compiler", -errCannotInterpretNodeX: "cannot evaluate '$1'", errFieldXNotFound: "field '$1' cannot be found", errInvalidConversionFromTypeX: "invalid conversion from type '$1'", errAssertionFailed: "assertion failed", diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 75026d5f4..aabcfd7a6 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -13,6 +13,8 @@ import ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread, modulegraphs +export createMagic + proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt] proc registerSysType*(g: ModuleGraph; t: PType) = @@ -32,9 +34,10 @@ proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym = if result.kind == skStub: loadStub(result) if result.kind == skAlias: result = result.owner -proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym = - result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) - result.magic = m +when false: + proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym = + result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) + result.magic = m when false: let diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index 5f741a3b3..da3965186 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -25,7 +25,7 @@ ## - Its dependent module stays the same. ## -import ast, intsets, tables, options, rod, msgs, hashes +import ast, intsets, tables, options, rod, msgs, hashes, idents type ModuleGraph* = ref object @@ -49,6 +49,7 @@ type compilerprocs*: TStrTable exposed*: TStrTable intTypeCache*: array[-5..64, PType] + opContains*, opNot*: PSym proc hash*(x: FileIndex): Hash {.borrow.} @@ -57,6 +58,10 @@ proc hash*(x: FileIndex): Hash {.borrow.} proc stopCompile*(g: ModuleGraph): bool {.inline.} = result = doStopCompile != nil and doStopCompile() +proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym = + result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) + result.magic = m + proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph = result = ModuleGraph() initStrTable(result.packageSyms) @@ -72,6 +77,8 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph = result.methods = @[] initStrTable(result.compilerprocs) initStrTable(result.exposed) + result.opNot = createMagic(result, "not", mNot) + result.opContains = createMagic(result, "contains", mInSet) proc resetAllModules*(g: ModuleGraph) = initStrTable(packageSyms) diff --git a/compiler/sem.nim b/compiler/sem.nim index de0b2d306..8cb233a05 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -33,7 +33,7 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc semProcBody(c: PContext, n: PNode): PNode proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode -proc changeType(n: PNode, newType: PType, check: bool) +proc changeType(c: PContext; n: PNode, newType: PType, check: bool) proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode proc semTypeNode(c: PContext, n: PNode, prev: PType): PType @@ -86,7 +86,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode = else: let x = result.skipConv if x.kind in {nkPar, nkTupleConstr} and formal.kind != tyExpr: - changeType(x, formal, check=true) + changeType(c, x, formal, check=true) else: result = skipHiddenSubConv(result) #result.typ = takeType(formal, arg.typ) @@ -476,7 +476,7 @@ proc addCodeForGenerics(c: PContext, n: PNode) = var prc = c.generics[i].inst.sym if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone: if prc.ast == nil or prc.ast.sons[bodyPos] == nil: - internalError(prc.info, "no code for " & prc.name.s) + internalError(c.config, prc.info, "no code for " & prc.name.s) else: addSon(n, prc.ast) c.lastGenericIdx = c.generics.len @@ -501,14 +501,14 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = c.importTable = openScope(c) c.importTable.addSym(module) # a module knows itself if sfSystemModule in module.flags: - magicsys.systemModule = module # set global variable! + graph.systemModule = module c.topLevelScope = openScope(c) # don't be verbose unless the module belongs to the main package: if module.owner.id == gMainPackageId: - gNotes = gMainPackageNotes + graph.config.notes = graph.config.mainPackageNotes else: - if gMainPackageNotes == {}: gMainPackageNotes = gNotes - gNotes = ForeignPackageNotes + if graph.config.mainPackageNotes == {}: graph.config.mainPackageNotes = graph.config.notes + graph.config.notes = graph.config.foreignPackageNotes result = c proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext = @@ -517,30 +517,30 @@ proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContex proc replayMethodDefs(graph: ModuleGraph; rd: PRodReader) = for m in items(rd.methods): methodDef(graph, m, true) -proc isImportSystemStmt(n: PNode): bool = - if magicsys.systemModule == nil: return false +proc isImportSystemStmt(g: ModuleGraph; n: PNode): bool = + if g.systemModule == nil: return false case n.kind of nkImportStmt: for x in n: if x.kind == nkIdent: - let f = checkModuleName(x, false) - if f == magicsys.systemModule.info.fileIndex: + let f = checkModuleName(g.config, x, false) + if f == g.systemModule.info.fileIndex: return true of nkImportExceptStmt, nkFromStmt: if n[0].kind == nkIdent: - let f = checkModuleName(n[0], false) - if f == magicsys.systemModule.info.fileIndex: + let f = checkModuleName(g.config, n[0], false) + if f == g.systemModule.info.fileIndex: return true else: discard proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = if n.kind == nkDefer: localError(c.config, n.info, "defer statement not supported at top level") - if c.topStmts == 0 and not isImportSystemStmt(n): + if c.topStmts == 0 and not isImportSystemStmt(c.graph, n): if sfSystemModule notin c.module.flags and n.kind notin {nkEmpty, nkCommentStmt}: - c.importTable.addSym magicsys.systemModule # import the "System" identifier - importAllSymbols(c, magicsys.systemModule) + c.importTable.addSym c.graph.systemModule # import the "System" identifier + importAllSymbols(c, c.graph.systemModule) inc c.topStmts else: inc c.topStmts @@ -566,7 +566,7 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = result = buildEchoStmt(c, result) if gCmd == cmdIdeTools: appendToModule(c.module, result) - result = transformStmt(c.module, result) + result = transformStmt(c.graph, c.module, result) proc recoverContext(c: PContext) = # clean up in case of a semantic error: We clean up the stacks, etc. This is @@ -579,7 +579,7 @@ proc recoverContext(c: PContext) = proc myProcess(context: PPassContext, n: PNode): PNode = var c = PContext(context) # no need for an expensive 'try' if we stop after the first error anyway: - if msgs.gErrorMax <= 1: + if c.config.errorMax <= 1: result = semStmtAndGenerateGenerics(c, n) else: let oldContextLen = msgs.getInfoContextLen() @@ -602,9 +602,9 @@ proc testExamples(c: PContext) = let inp = toFullPath(c.module.info) let outp = inp.changeFileExt"" & "_examples.nim" renderModule(c.runnableExamples, inp, outp) - let backend = if isDefined("js"): "js" - elif isDefined("cpp"): "cpp" - elif isDefined("objc"): "objc" + let backend = if isDefined(c.config, "js"): "js" + elif isDefined(c.config, "cpp"): "cpp" + elif isDefined(c.config, "objc"): "objc" else: "c" if os.execShellCmd("nim " & backend & " -r " & outp) != 0: quit "[Examples] failed" @@ -618,7 +618,7 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = rawCloseScope(c) # imported symbols; don't check for unused ones! result = newNode(nkStmtList) if n != nil: - internalError(n.info, "n is not nil") #result := n; + internalError(c.config, n.info, "n is not nil") #result := n; addCodeForGenerics(c, result) if c.module.ast != nil: result.add(c.module.ast) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 0ca3fcd4c..5b5c7f80c 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -10,12 +10,24 @@ # this module does the semantic checking for expressions # included from sem.nim +const + errExprXHasNoType = "expression '$1' has no type (or is ambiguous)" + errXExpectsTypeOrValue = "'$1' expects a type or value" + errVarForOutParamNeededX = "for a 'var' type a variable needs to be passed; but '$1' is immutable" + errXStackEscape = "address of '$1' may not escape its stack frame" + errExprHasNoAddress = "expression has no address; maybe use 'unsafeAddr'" + errCannotInterpretNodeX = "cannot evaluate '$1'" + errNamedExprExpected = "named expression expected" + errNamedExprNotAllowed = "named expression not allowed here" + errFieldInitTwice = "field initialized twice: '$1'" + errUndeclaredFieldX = "undeclared field: '$1'" + proc semTemplateExpr(c: PContext, n: PNode, s: PSym, flags: TExprFlags = {}): PNode = - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) pushInfoContext(n.info) - result = evalTemplate(n, s, getCurrOwner(c), efFromHlo in flags) + result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in flags) if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags) popInfoContext() @@ -31,12 +43,12 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.typ != nil: # XXX tyGenericInst here? if result.typ.kind == tyProc and tfUnresolved in result.typ.flags: - localError(c.config, n.info, errProcHasNoConcreteType, n.renderTree) + localError(c.config, n.info, errProcHasNoConcreteType % n.renderTree) if result.typ.kind in {tyVar, tyLent}: result = newDeref(result) elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyVoid, c) else: - localError(c.config, n.info, errExprXHasNoType, + localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -47,7 +59,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = #raiseRecoverableError("") result = errorNode(c, n) if result.typ == nil or result.typ == enforceVoidContext: - localError(c.config, n.info, errExprXHasNoType, + localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.typ = errorType(c) else: @@ -59,14 +71,14 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: result = errorNode(c, n) if result.typ == nil: - localError(c.config, n.info, errExprXHasNoType, + localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.typ = errorType(c) proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s, scClosed) -proc inlineConst(n: PNode, s: PSym): PNode {.inline.} = +proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} = result = copyTree(s.ast) if result.isNil: localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value") @@ -172,7 +184,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) = proc semConv(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - localError(c.config, n.info, errConvNeedsOneArg) + localError(c.config, n.info, "a type conversion takes exactly one argument") return n result = newNodeI(nkConv, n.info) @@ -219,14 +231,14 @@ proc semConv(c: PContext, n: PNode): PNode = of convNotLegal: result = fitNode(c, result.typ, result.sons[1], result.info) if result == nil: - localError(c.config, n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% + localError(c.config, n.info, "illegal conversion from '$1' to '$2'" % [op.typ.typeToString, result.typ.typeToString]) else: for i in countup(0, sonsLen(op) - 1): let it = op.sons[i] let status = checkConvertible(c, result.typ, it.typ) if status in {convOK, convNotNeedeed}: - markUsed(n.info, it.sym, c.graph.usageSym) + markUsed(c.config, n.info, it.sym, c.graph.usageSym) styleCheckUse(n.info, it.sym) markIndirect(c, it.sym) return it @@ -238,12 +250,12 @@ proc semCast(c: PContext, n: PNode): PNode = let targetType = semTypeNode(c, n.sons[0], nil) let castedExpr = semExprWithType(c, n.sons[1]) if tfHasMeta in targetType.flags: - localError(c.config, n.sons[0].info, errCastToANonConcreteType, $targetType) + localError(c.config, n.sons[0].info, "cannot cast to a non concrete type: '$1'" % $targetType) if not isCastable(targetType, castedExpr.typ): let tar = $targetType let alt = typeToString(targetType, preferDesc) let msg = if tar != alt: tar & "=" & alt else: tar - localError(c.config, n.info, errExprCannotBeCastToX, msg) + localError(c.config, n.info, "expression cannot be cast to " & msg) result = newNodeI(nkCast, n.info) result.typ = targetType addSon(result, copyTree(n.sons[0])) @@ -253,13 +265,13 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const opToStr: array[mLow..mHigh, string] = ["low", "high"] if sonsLen(n) != 2: - localError(c.config, n.info, errXExpectsTypeOrValue, opToStr[m]) + localError(c.config, n.info, errXExpectsTypeOrValue % opToStr[m]) else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc}) case typ.kind of tySequence, tyString, tyCString, tyOpenArray, tyVarargs: - n.typ = getSysType(tyInt) + n.typ = getSysType(c.graph, n.info, tyInt) of tyArray: n.typ = typ.sons[0] # indextype of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32: @@ -271,20 +283,20 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = # that could easily turn into an infinite recursion in semtypinst n.typ = makeTypeFromExpr(c, n.copyTree) else: - localError(c.config, n.info, errInvalidArgForX, opToStr[m]) + localError(c.config, n.info, "invalid argument for: " & opToStr[m]) result = n proc semSizeof(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - localError(c.config, n.info, errXExpectsTypeOrValue, "sizeof") + localError(c.config, n.info, errXExpectsTypeOrValue % "sizeof") else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) #restoreOldStyleType(n.sons[1]) - n.typ = getSysType(tyInt) + n.typ = getSysType(c.graph, n.info, tyInt) result = n proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = - internalAssert n.sonsLen == 3 and + internalAssert c.config, n.sonsLen == 3 and n[1].typ != nil and n[1].typ.kind == tyTypeDesc and n[2].kind in {nkStrLit..nkTripleStrLit, nkType} @@ -315,10 +327,10 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode = if sonsLen(n) != 3: - localError(c.config, n.info, errXExpectsTwoArguments, "is") + localError(c.config, n.info, "'is' operator takes 2 arguments") result = n - n.typ = getSysType(tyBool) + n.typ = getSysType(c.graph, n.info, tyBool) n.sons[1] = semExprWithType(c, n[1], {efDetermineType, efWantIterator}) if n[2].kind notin {nkStrLit..nkTripleStrLit}: @@ -340,8 +352,8 @@ proc semOpAux(c: PContext, n: PNode) = for i in countup(1, n.sonsLen-1): var a = n.sons[i] if a.kind == nkExprEqExpr and sonsLen(a) == 2: - var info = a.sons[0].info - a.sons[0] = newIdentNode(considerQuotedIdent(a.sons[0], a), info) + let info = a.sons[0].info + a.sons[0] = newIdentNode(considerQuotedIdent(c.config, a.sons[0], a), info) a.sons[1] = semExprWithType(c, a.sons[1], flags) a.typ = a.sons[1].typ else: @@ -358,34 +370,34 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): addSon(result, n.sons[i]) result = semExpr(c, result) -proc changeType(n: PNode, newType: PType, check: bool) = +proc changeType(c: PContext; n: PNode, newType: PType, check: bool) = case n.kind of nkCurly, nkBracket: for i in countup(0, sonsLen(n) - 1): - changeType(n.sons[i], elemType(newType), check) + changeType(c, n.sons[i], elemType(newType), check) of nkPar, nkTupleConstr: let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink}) if tup.kind != tyTuple: if tup.kind == tyObject: return - globalError(n.info, "no tuple type for constructor") + globalError(c.config, n.info, "no tuple type for constructor") elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: # named tuple? for i in countup(0, sonsLen(n) - 1): var m = n.sons[i].sons[0] if m.kind != nkSym: - globalError(m.info, "invalid tuple constructor") + globalError(c.config, m.info, "invalid tuple constructor") return if tup.n != nil: var f = getSymFromList(tup.n, m.sym.name) if f == nil: - globalError(m.info, "unknown identifier: " & m.sym.name.s) + globalError(c.config, m.info, "unknown identifier: " & m.sym.name.s) return - changeType(n.sons[i].sons[1], f.typ, check) + changeType(c, n.sons[i].sons[1], f.typ, check) else: - changeType(n.sons[i].sons[1], tup.sons[i], check) + changeType(c, n.sons[i].sons[1], tup.sons[i], check) else: for i in countup(0, sonsLen(n) - 1): - changeType(n.sons[i], tup.sons[i], check) + changeType(c, n.sons[i], tup.sons[i], check) when false: var m = n.sons[i] var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) @@ -396,7 +408,7 @@ proc changeType(n: PNode, newType: PType, check: bool) = if check and n.kind != nkUInt64Lit: let value = n.intVal if value < firstOrd(newType) or value > lastOrd(newType): - localError(c.config, n.info, errGenerated, "cannot convert " & $value & + localError(c.config, n.info, "cannot convert " & $value & " to " & typeToString(newType)) else: discard n.typ = newType @@ -421,7 +433,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = else: var x = n.sons[0] var lastIndex: BiggestInt = 0 - var indexType = getSysType(tyInt) + var indexType = getSysType(c.graph, n.info, tyInt) if x.kind == nkExprColonExpr and sonsLen(x) == 2: var idx = semConstExpr(c, x.sons[0]) lastIndex = getOrdValue(idx) @@ -438,7 +450,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var idx = semConstExpr(c, x.sons[0]) idx = fitNode(c, indexType, idx, x.info) if lastIndex+1 != getOrdValue(idx): - localError(c.config, x.info, errInvalidOrderInArrayConstructor) + localError(c.config, x.info, "invalid order in array constructor") x = x.sons[1] let xx = semExprWithType(c, x, flags*{efAllowDestructor}) @@ -462,7 +474,7 @@ proc fixAbstractType(c: PContext, n: PNode) = {tyNil, tyTuple, tySet} or it[1].isArrayConstr: var s = skipTypes(it.typ, abstractVar) if s.kind != tyExpr: - changeType(it.sons[1], s, check=true) + changeType(c, it.sons[1], s, check=true) n.sons[i] = it.sons[1] proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult = @@ -477,7 +489,7 @@ proc newHiddenAddrTaken(c: PContext, n: PNode): PNode = result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ)) addSon(result, n) if isAssignable(c, n) notin {arLValue, arLocalLValue}: - localError(c.config, n.info, errVarForOutParamNeededX, renderNotLValue(n)) + localError(c.config, n.info, errVarForOutParamNeededX % renderNotLValue(n)) proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = n @@ -491,7 +503,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = of nkDotExpr: checkSonsLen(n, 2, c.config) if n.sons[1].kind != nkSym: - internalError(n.info, "analyseIfAddressTaken") + internalError(c.config, n.info, "analyseIfAddressTaken") return if skipTypes(n.sons[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}: incl(n.sons[1].sym.flags, sfAddrTaken) @@ -600,17 +612,17 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = var call = newNodeIT(nkCall, n.info, n.typ) call.add(n.sons[0]) for i in 1 ..< n.len: - let a = getConstExpr(c.module, n.sons[i]) + let a = getConstExpr(c.module, n.sons[i], c.graph) if a == nil: return n call.add(a) #echo "NOW evaluating at compile time: ", call.renderTree if sfCompileTime in callee.flags: - result = evalStaticExpr(c.module, c.cache, c.graph.config, call, c.p.owner) + result = evalStaticExpr(c.module, c.cache, c.graph, call, c.p.owner) if result.isNil: - localError(c.config, n.info, errCannotInterpretNodeX, renderTree(call)) + localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call)) else: result = fixupTypeAfterEval(c, result, n) else: - result = evalConstExpr(c.module, c.cache, c.graph.config, call) + result = evalConstExpr(c.module, c.cache, c.graph, call) if result.isNil: result = n else: result = fixupTypeAfterEval(c, result, n) #if result != n: @@ -619,9 +631,9 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = proc semStaticExpr(c: PContext, n: PNode): PNode = let a = semExpr(c, n.sons[0]) if a.findUnresolvedStatic != nil: return a - result = evalStaticExpr(c.module, c.cache, c.graph.config, a, c.p.owner) + result = evalStaticExpr(c.module, c.cache, c.graph, a, c.p.owner) if result.isNil: - localError(c.config, n.info, errCannotInterpretNodeX, renderTree(n)) + localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n)) result = emptyNode else: result = fixupTypeAfterEval(c, result, a) @@ -641,14 +653,14 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, if result != nil: if result.sons[0].kind != nkSym: - internalError("semOverloadedCallAnalyseEffects") + internalError(c.config, "semOverloadedCallAnalyseEffects") return let callee = result.sons[0].sym case callee.kind of skMacro, skTemplate: discard else: if callee.kind == skIterator and callee.id == c.p.owner.id: - localError(c.config, n.info, errRecursiveDependencyX, callee.name.s) + localError(c.config, n.info, errRecursiveDependencyX % callee.name.s) # error correction, prevents endless for loop elimination in transf. # See bug #2051: result.sons[0] = newSymNode(errorSym(c, n)) @@ -736,7 +748,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = return emptyNode else: var hasErrorType = false - var msg = msgKindToString(errTypeMismatch) + var msg = "type mismatch: got <" for i in countup(1, sonsLen(n) - 1): if i > 1: add(msg, ", ") let nt = n.sons[i].typ @@ -745,7 +757,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = hasErrorType = true break if not hasErrorType: - add(msg, ">\n" & msgKindToString(errButExpected) & "\n" & + add(msg, ">\nbut expected one of: \n" & typeToString(n.sons[0].typ)) localError(c.config, n.info, msg) return errorNode(c, n) @@ -790,7 +802,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = proc buildEchoStmt(c: PContext, n: PNode): PNode = # we MUST not check 'n' for semantics again here! But for now we give up: result = newNodeI(nkCall, n.info) - var e = strTableGet(magicsys.systemModule.tab, getIdent"echo") + var e = strTableGet(c.graph.systemModule.tab, getIdent"echo") if e != nil: add(result, newSymNode(e)) else: @@ -857,8 +869,8 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, addSon(check, ast.emptyNode) # make space for access node s = newNodeIT(nkCurly, n.info, setType) for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j])) - var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool)) - addSon(inExpr, newSymNode(opContains, n.info)) + var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) + addSon(inExpr, newSymNode(c.graph.opContains, n.info)) addSon(inExpr, s) addSon(inExpr, copyTree(r.sons[0])) addSon(check, inExpr) @@ -870,12 +882,12 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) addSon(check, ast.emptyNode) # make space for access node - var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool)) - addSon(inExpr, newSymNode(opContains, n.info)) + var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) + addSon(inExpr, newSymNode(c.graph.opContains, n.info)) addSon(inExpr, s) addSon(inExpr, copyTree(r.sons[0])) - var notExpr = newNodeIT(nkCall, n.info, getSysType(tyBool)) - addSon(notExpr, newSymNode(opNot, n.info)) + var notExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) + addSon(notExpr, newSymNode(c.graph.opNot, n.info)) addSon(notExpr, inExpr) addSon(check, notExpr) return @@ -937,12 +949,12 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = let s = getGenSym(c, sym) case s.kind of skConst: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128, tyTuple, tySet, tyUInt..tyUInt64: - if s.magic == mNone: result = inlineConst(n, s) + if s.magic == mNone: result = inlineConst(c, n, s) else: result = newSymNode(s, n.info) of tyArray, tySequence: # Consider:: @@ -955,13 +967,13 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = # It is clear that ``[]`` means two totally different things. Thus, we # copy `x`'s AST into each context, so that the type fixup phase can # deal with two different ``[]``. - if s.ast.len == 0: result = inlineConst(n, s) + if s.ast.len == 0: result = inlineConst(c, n, s) else: result = newSymNode(s, n.info) else: result = newSymNode(s, n.info) of skMacro: if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(s, n.info) else: @@ -969,13 +981,13 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = of skTemplate: if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or sfCustomPragma in sym.flags: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(s, n.info) else: result = semTemplateExpr(c, n, s, flags) of skParam: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) if s.typ != nil and s.typ.kind == tyStatic and s.typ.n != nil: # XXX see the hack in sigmatch.nim ... @@ -985,19 +997,19 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = # gensym'ed parameters that nevertheless have been forward declared # need a special fixup: let realParam = c.p.owner.typ.n[s.position+1] - internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam + internalAssert c.config, realParam.kind == nkSym and realParam.sym.kind == skParam return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info) elif c.p.owner.kind == skMacro: # gensym'ed macro parameters need a similar hack (see bug #1944): var u = searchInScopes(c, s.name) - internalAssert u != nil and u.kind == skParam and u.owner == s.owner + internalAssert c.config, u != nil and u.kind == skParam and u.owner == s.owner return newSymNode(u, n.info) result = newSymNode(s, n.info) of skVar, skLet, skResult, skForVar: if s.magic == mNimvm: localError(c.config, n.info, "illegal context for 'nimvm' magic") - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(s, n.info) # We cannot check for access to outer vars for example because it's still @@ -1015,7 +1027,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = n.typ = s.typ return n of skType: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) if s.typ.kind == tyStatic and s.typ.n != nil: return s.typ.n @@ -1037,7 +1049,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = if f != nil and fieldVisible(c, f): # is the access to a public field or in the same module or in a friend? doAssert f == s - markUsed(n.info, f, c.graph.usageSym) + markUsed(c.config, n.info, f, c.graph.usageSym) styleCheckUse(n.info, f) result = newNodeIT(nkDotExpr, n.info, f.typ) result.add makeDeref(newSymNode(p.selfSym)) @@ -1050,11 +1062,11 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = if ty.sons[0] == nil: break ty = skipTypes(ty.sons[0], skipPtrs) # old code, not sure if it's live code: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(s, n.info) else: - markUsed(n.info, s, c.graph.usageSym) + markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(s, n.info) @@ -1076,14 +1088,14 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result = symChoice(c, n, s, scClosed) if result.kind == nkSym: result = semSym(c, n, s, flags) else: - markUsed(n.sons[1].info, s, c.graph.usageSym) + markUsed(c.config, n.sons[1].info, s, c.graph.usageSym) result = semSym(c, n, s, flags) styleCheckUse(n.sons[1].info, s) return n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType}) #restoreOldStyleType(n.sons[0]) - var i = considerQuotedIdent(n.sons[1], n) + var i = considerQuotedIdent(c.config, n.sons[1], n) var ty = n.sons[0].typ var f: PSym = nil result = nil @@ -1140,7 +1152,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result = newSymNode(f) result.info = n.info result.typ = ty - markUsed(n.info, f, c.graph.usageSym) + markUsed(c.config, n.info, f, c.graph.usageSym) styleCheckUse(n.info, f) return of tyObject, tyTuple: @@ -1171,7 +1183,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = if f != nil: if fieldVisible(c, f): # is the access to a public field or in the same module or in a friend? - markUsed(n.sons[1].info, f, c.graph.usageSym) + markUsed(c.config, n.sons[1].info, f, c.graph.usageSym) styleCheckUse(n.sons[1].info, f) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) # we now have the correct field @@ -1185,7 +1197,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = elif ty.kind == tyTuple and ty.n != nil: f = getSymFromList(ty.n, i) if f != nil: - markUsed(n.sons[1].info, f, c.graph.usageSym) + markUsed(c.config, n.sons[1].info, f, c.graph.usageSym) styleCheckUse(n.sons[1].info, f) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) @@ -1203,7 +1215,7 @@ proc dotTransformation(c: PContext, n: PNode): PNode = addSon(result, n.sons[1]) addSon(result, copyTree(n[0])) else: - var i = considerQuotedIdent(n.sons[1], n) + var i = considerQuotedIdent(c.config, n.sons[1], n) result = newNodeI(nkDotCall, n.info) result.flags.incl nfDotField addSon(result, newIdentNode(i, n[1].info)) @@ -1254,7 +1266,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = for i in countup(1, sonsLen(n) - 1): n.sons[i] = semExprWithType(c, n.sons[i], flags*{efInTypeof, efDetermineType}) - var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(tyInt) + var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(c.graph, n.info, tyInt) var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1]) if arg != nil: n.sons[1] = arg @@ -1277,7 +1289,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = {tyInt..tyInt64}: var idx = getOrdValue(n.sons[1]) if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)] - else: localError(c.config, n.info, errInvalidIndexValueForTuple) + else: localError(c.config, n.info, "invalid index value for tuple subscript") result = n else: result = nil @@ -1317,7 +1329,7 @@ proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]")) proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode = - var id = considerQuotedIdent(a[1], a) + var id = considerQuotedIdent(c.config, a[1], a) var setterId = newIdentNode(getIdent(id.s & '='), n.info) # a[0] is already checked for semantics, that does ``builtinFieldAccess`` # this is ugly. XXX Semantic checking should use the ``nfSem`` flag for @@ -1354,7 +1366,7 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode = let valid = isAssignable(c, n) if valid != arLValue: if valid == arLocalLValue: - localError(c.config, n.info, errXStackEscape, renderTree(n, {renderNoComments})) + localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments})) elif not isLent: localError(c.config, n.info, errExprHasNoAddress) result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ)) @@ -1426,7 +1438,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = isAssignable(c, a) == arNone) or skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}: # Direct assignment to a discriminant is allowed! - localError(c.config, a.info, errXCannotBeAssignedTo, + localError(c.config, a.info, errXCannotBeAssignedTo % renderTree(a, {renderNoComments})) else: let @@ -1442,12 +1454,12 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass: rhsTyp = rhsTyp.lastSon if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}: - internalAssert c.p.resultSym != nil + internalAssert c.config, c.p.resultSym != nil lhs.typ = rhsTyp c.p.resultSym.typ = rhsTyp c.p.owner.typ.sons[0] = rhsTyp else: - typeMismatch(n.info, lhs.typ, rhsTyp) + typeMismatch(c.config, n.info, lhs.typ, rhsTyp) n.sons[1] = fitNode(c, le, rhs, n.info) if destructor notin c.features: @@ -1479,7 +1491,7 @@ proc semReturn(c: PContext, n: PNode): PNode = else: localError(c.config, n.info, errNoReturnTypeDeclared) else: - localError(c.config, n.info, errXNotAllowedHere, "\'return\'") + localError(c.config, n.info, "'return' not allowed here") proc semProcBody(c: PContext, n: PNode): PNode = openScope(c) @@ -1551,7 +1563,7 @@ proc semYield(c: PContext, n: PNode): PNode = if restype != nil: if restype.kind != tyExpr: n.sons[0] = fitNode(c, restype, n.sons[0], n.info) - if n.sons[0].typ == nil: internalError(n.info, "semYield") + if n.sons[0].typ == nil: internalError(c.config, n.info, "semYield") if resultTypeIsInferrable(restype): let inferred = n.sons[0].typ @@ -1579,19 +1591,19 @@ proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = checkSonsLen(n, 2, c.config) var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope) if m != nil and m.kind == skModule: - let ident = considerQuotedIdent(n[1], n) + let ident = considerQuotedIdent(c.config, n[1], n) if m == c.module: result = strTableGet(c.topLevelScope.symbols, ident) else: result = strTableGet(m.tab, ident) of nkAccQuoted: - result = lookUpForDefined(c, considerQuotedIdent(n), onlyCurrentScope) + result = lookUpForDefined(c, considerQuotedIdent(c.config, n), onlyCurrentScope) of nkSym: result = n.sym of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym else: - localError(c.config, n.info, errIdentifierExpected, renderTree(n)) + localError(c.config, n.info, "identifier expected, but got: " & renderTree(n)) result = nil proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = @@ -1601,12 +1613,12 @@ proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = if not onlyCurrentScope and considerQuotedIdent(c.config, n[0], n).s == "defined": if n.sons[1].kind != nkIdent: localError(c.config, n.info, "obsolete usage of 'defined', use 'declared' instead") - elif condsyms.isDefined(n.sons[1].ident): + elif isDefined(c.config, n.sons[1].ident.s): result.intVal = 1 elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil: result.intVal = 1 result.info = n.info - result.typ = getSysType(tyBool) + result.typ = getSysType(c.graph, n.info, tyBool) proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym = ## The argument to the proc should be nkCall(...) or similar @@ -1618,12 +1630,12 @@ proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym = return errorSym(c, n[0]) if expandedSym.kind notin {skMacro, skTemplate}: - localError(c.config, n.info, errXisNoMacroOrTemplate, expandedSym.name.s) + localError(c.config, n.info, "'$1' is not a macro or template" % expandedSym.name.s) return errorSym(c, n[0]) result = expandedSym else: - localError(c.config, n.info, errXisNoMacroOrTemplate, n.renderTree) + localError(c.config, n.info, "'$1' is not a macro or template" % n.renderTree) result = errorSym(c, n) proc expectString(c: PContext, n: PNode): string = @@ -1633,10 +1645,6 @@ proc expectString(c: PContext, n: PNode): string = else: localError(c.config, n.info, errStringLiteralExpected) -proc getMagicSym(magic: TMagic): PSym = - result = newSym(skProc, getIdent($magic), systemModule, gCodegenLineInfo) - result.magic = magic - proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym = result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info) result.flags = {sfGenSym} @@ -1649,7 +1657,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = if expandedSym.kind == skError: return n macroCall.sons[0] = newSymNode(expandedSym, macroCall.info) - markUsed(n.info, expandedSym, c.graph.usageSym) + markUsed(c.config, n.info, expandedSym, c.graph.usageSym) styleCheckUse(n.info, expandedSym) if isCallExpr(macroCall): @@ -1674,7 +1682,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = else: let info = macroCall.sons[0].info macroCall.sons[0] = newSymNode(cand, info) - markUsed(info, cand, c.graph.usageSym) + markUsed(c.config, info, cand, c.graph.usageSym) styleCheckUse(info, cand) # we just perform overloading resolution here: @@ -1682,12 +1690,11 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = else: localError(c.config, n.info, "getAst takes a call, but got " & n.renderTree) # Preserve the magic symbol in order to be handled in evals.nim - internalAssert n.sons[0].sym.magic == mExpandToAst + internalAssert c.config, n.sons[0].sym.magic == mExpandToAst #n.typ = getSysSym("NimNode").typ # expandedSym.getReturnType if n.kind == nkStmtList and n.len == 1: result = n[0] else: result = n - result.typ = if getCompilerProc("NimNode") != nil: sysTypeFromName"NimNode" - else: sysTypeFromName"PNimrodNode" + result.typ = sysTypeFromName(c.graph, n.info, "NimNode") proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, flags: TExprFlags = {}): PNode = @@ -1697,7 +1704,7 @@ proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, else: result = semDirectOp(c, n, flags) -proc processQuotations(n: var PNode, op: string, +proc processQuotations(c: PContext; n: var PNode, op: string, quotes: var seq[PNode], ids: var seq[PNode]) = template returnQuote(q) = @@ -1718,10 +1725,10 @@ proc processQuotations(n: var PNode, op: string, returnQuote n[0] for i in 0 ..< n.safeLen: - processQuotations(n.sons[i], op, quotes, ids) + processQuotations(c, n.sons[i], op, quotes, ids) proc semQuoteAst(c: PContext, n: PNode): PNode = - internalAssert n.len == 2 or n.len == 3 + internalAssert c.config, n.len == 2 or n.len == 3 # We transform the do block into a template with a param for # each interpolation. We'll pass this template to getAst. var @@ -1736,7 +1743,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = if quotedBlock.kind != nkStmtList: localError(c.config, n.info, errXExpected, "block") - processQuotations(quotedBlock, op, quotes, ids) + processQuotations(c, quotedBlock, op, quotes, ids) var dummyTemplate = newProcNode( nkTemplateDef, quotedBlock.info, quotedBlock, @@ -1744,27 +1751,27 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = if ids.len > 0: dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info) - dummyTemplate[paramsPos].add getSysSym("typed").newSymNode # return type - ids.add getSysSym("untyped").newSymNode # params type + dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "typed").newSymNode # return type + ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type ids.add emptyNode # no default value dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids) var tmpl = semTemplateDef(c, dummyTemplate) quotes[0] = tmpl[namePos] result = newNode(nkCall, n.info, @[ - getMagicSym(mExpandToAst).newSymNode, + createMagic(c.graph, "getAst", mExpandToAst).newSymNode, newNode(nkCall, n.info, quotes)]) result = semExpandToAst(c, result) proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # watch out, hacks ahead: - let oldErrorCount = msgs.gErrorCounter - let oldErrorMax = msgs.gErrorMax + let oldErrorCount = c.config.errorCounter + let oldErrorMax = c.config.errorMax let oldCompilesId = c.compilesContextId inc c.compilesContextIdGenerator c.compilesContextId = c.compilesContextIdGenerator # do not halt after first error: - msgs.gErrorMax = high(int) + c.config.errorMax = high(int) # open a scope for temporary symbol inclusions: let oldScope = c.currentScope @@ -1783,7 +1790,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = var err: string try: result = semExpr(c, n, flags) - if msgs.gErrorCounter != oldErrorCount: result = nil + if c.config.errorCounter != oldErrorCount: result = nil except ERecoverableError: discard # undo symbol table changes (as far as it's possible): @@ -1797,8 +1804,8 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = setLen(c.graph.owners, oldOwnerLen) c.currentScope = oldScope errorOutputs = oldErrorOutputs - msgs.gErrorCounter = oldErrorCount - msgs.gErrorMax = oldErrorMax + c.config.errorCounter = oldErrorCount + c.config.errorMax = oldErrorMax proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = # we replace this node by a 'true' or 'false' node: @@ -1806,7 +1813,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil)) result.info = n.info - result.typ = getSysType(tyBool) + result.typ = getSysType(c.graph, n.info, tyBool) proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode = if sonsLen(n) == 3: @@ -1821,15 +1828,15 @@ proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode = proc createFlowVar(c: PContext; t: PType; info: TLineInfo): PType = result = newType(tyGenericInvocation, c.module) - addSonSkipIntLit(result, magicsys.getCompilerProc("FlowVar").typ) + addSonSkipIntLit(result, magicsys.getCompilerProc(c.graph, "FlowVar").typ) addSonSkipIntLit(result, t) result = instGenericContainer(c, info, result, allowMetaTypes = false) proc instantiateCreateFlowVarCall(c: PContext; t: PType; info: TLineInfo): PSym = - let sym = magicsys.getCompilerProc("nimCreateFlowVar") + let sym = magicsys.getCompilerProc(c.graph, "nimCreateFlowVar") if sym == nil: - localError(c.config, info, errSystemNeeds, "nimCreateFlowVar") + localError(c.config, info, "system needs: nimCreateFlowVar") var bindings: TIdTable initIdTable(bindings) bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t) @@ -1879,8 +1886,8 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mQuoteAst: result = semQuoteAst(c, n) of mAstToStr: checkSonsLen(n, 2, c.config) - result = newStrNodeT(renderTree(n[1], {renderNoComments}), n) - result.typ = getSysType(tyString) + result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph) + result.typ = getSysType(c.graph, n.info, tyString) of mParallel: if parallel notin c.features: localError(c.config, n.info, "use the {.experimental.} pragma to enable 'parallel'") @@ -2072,7 +2079,7 @@ type TParKind = enum paNone, paSingle, paTupleFields, paTuplePositions -proc checkPar(n: PNode): TParKind = +proc checkPar(c: PContext; n: PNode): TParKind = var length = sonsLen(n) if length == 0: result = paTuplePositions # () @@ -2106,7 +2113,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = if n.sons[i].sons[0].kind == nkIdent: id = n.sons[i].sons[0].ident else: id = n.sons[i].sons[0].sym.name if containsOrIncl(ids, id.id): - localError(c.config, n.sons[i].info, errFieldInitTwice, id.s) + localError(c.config, n.sons[i].info, errFieldInitTwice % id.s) n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1], flags*{efAllowDestructor}) var f = newSymS(skField, n.sons[i].sons[0], c) @@ -2225,39 +2232,39 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkEmpty, nkNone, nkCommentStmt, nkType: discard of nkNilLit: - if result.typ == nil: result.typ = getSysType(tyNil) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyNil) of nkIntLit: - if result.typ == nil: setIntLitType(result) + if result.typ == nil: setIntLitType(c.graph, result) of nkInt8Lit: - if result.typ == nil: result.typ = getSysType(tyInt8) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt8) of nkInt16Lit: - if result.typ == nil: result.typ = getSysType(tyInt16) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt16) of nkInt32Lit: - if result.typ == nil: result.typ = getSysType(tyInt32) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt32) of nkInt64Lit: - if result.typ == nil: result.typ = getSysType(tyInt64) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt64) of nkUIntLit: - if result.typ == nil: result.typ = getSysType(tyUInt) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt) of nkUInt8Lit: - if result.typ == nil: result.typ = getSysType(tyUInt8) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt8) of nkUInt16Lit: - if result.typ == nil: result.typ = getSysType(tyUInt16) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt16) of nkUInt32Lit: - if result.typ == nil: result.typ = getSysType(tyUInt32) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt32) of nkUInt64Lit: - if result.typ == nil: result.typ = getSysType(tyUInt64) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt64) #of nkFloatLit: # if result.typ == nil: result.typ = getFloatLitType(result) of nkFloat32Lit: - if result.typ == nil: result.typ = getSysType(tyFloat32) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat32) of nkFloat64Lit, nkFloatLit: - if result.typ == nil: result.typ = getSysType(tyFloat64) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat64) of nkFloat128Lit: - if result.typ == nil: result.typ = getSysType(tyFloat128) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat128) of nkStrLit..nkTripleStrLit: - if result.typ == nil: result.typ = getSysType(tyString) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyString) of nkCharLit: - if result.typ == nil: result.typ = getSysType(tyChar) + if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyChar) of nkDotExpr: result = semFieldAccess(c, n, flags) if result.kind == nkDotCall: @@ -2341,7 +2348,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = var expr = n[0] pragma = n[1] - pragmaName = considerQuotedIdent(pragma[0]) + pragmaName = considerQuotedIdent(c.config, pragma[0]) flags = flags case whichKeyword(pragmaName) @@ -2349,11 +2356,11 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = flags.incl efExplain else: # what other pragmas are allowed for expressions? `likely`, `unlikely` - invalidPragma(n) + invalidPragma(c, n) result = semExpr(c, n[0], flags) of nkPar, nkTupleConstr: - case checkPar(n) + case checkPar(c, n) of paNone: result = errorNode(c, n) of paTuplePositions: var tupexp = semTuplePositionsConstr(c, n, flags) @@ -2433,19 +2440,19 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # # works: if c.currentScope.depthLevel > 2 + c.compilesContextId: - localError(c.config, n.info, errXOnlyAtModuleScope, "import") + localError(c.config, n.info, errXOnlyAtModuleScope % "import") result = evalImport(c, n) of nkImportExceptStmt: - if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "import") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "import") result = evalImportExcept(c, n) of nkFromStmt: - if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "from") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "from") result = evalFrom(c, n) of nkIncludeStmt: - #if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "include") + #if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "include") result = evalInclude(c, n) of nkExportStmt, nkExportExceptStmt: - if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "export") + if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "export") result = semExport(c, n) of nkPragmaBlock: result = semPragmaBlock(c, n) @@ -2454,7 +2461,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkDefer: n.sons[0] = semExpr(c, n.sons[0]) if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]): - localError(c.config, n.info, errGenerated, "'defer' takes a 'void' expression") + localError(c.config, n.info, "'defer' takes a 'void' expression") #localError(c.config, n.info, errGenerated, "'defer' not allowed in this context") of nkGotoState, nkState: if n.len != 1 and n.len != 2: illFormedAst(n, c.config) @@ -2462,6 +2469,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = n.sons[i] = semExpr(c, n.sons[i]) of nkComesFrom: discard "ignore the comes from information for now" else: - localError(c.config, n.info, errInvalidExpressionX, + localError(c.config, n.info, "invalid expression: " & renderTree(n, {renderNoComments})) if result != nil: incl(result.flags, nfSem) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 49dfb58f9..93d56b603 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -64,7 +64,7 @@ proc semAsgnOpr(c: PContext; n: PNode): PNode = proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode = var r = isPartOf(n[1], n[2]) - result = newIntNodeT(ord(r), n) + result = newIntNodeT(ord(r), n, c.graph) proc expectIntLit(c: PContext, n: PNode): int = let x = c.semConstExpr(c, n) @@ -77,11 +77,11 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode = let idx = expectIntLit(c, n.sons[1]) let useFullPaths = expectIntLit(c, n.sons[2]) let info = getInfoContext(idx) - var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString)) + var filename = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString)) filename.strVal = if useFullPaths != 0: info.toFullPath else: info.toFilename - var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt)) + var line = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt)) line.intVal = toLinenumber(info) - var column = newNodeIT(nkIntLit, n.info, getSysType(tyInt)) + var column = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt)) column.intVal = toColumn(info) result.add(filename) result.add(line) @@ -110,10 +110,10 @@ proc uninstantiate(t: PType): PType = of tyCompositeTypeClass: uninstantiate t.sons[1] else: t -proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode = +proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym): PNode = const skippedTypes = {tyTypeDesc, tyAlias, tySink} let trait = traitCall[0] - internalAssert trait.kind == nkSym + internalAssert c.config, trait.kind == nkSym var operand = operand.skipTypes(skippedTypes) template operand2: PType = @@ -151,19 +151,19 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode = let t = operand.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred}) let complexObj = containsGarbageCollectedRef(t) or hasDestructor(t) - result = newIntNodeT(ord(not complexObj), traitCall) + result = newIntNodeT(ord(not complexObj), traitCall, c.graph) else: localError(c.config, traitCall.info, "unknown trait") result = emptyNode proc semTypeTraits(c: PContext, n: PNode): PNode = - checkMinSonsLen(n, 2) + checkMinSonsLen(n, 2, c.config) let t = n.sons[1].typ - internalAssert t != nil and t.kind == tyTypeDesc + internalAssert c.config, t != nil and t.kind == tyTypeDesc if t.sonsLen > 0: # This is either a type known to sem or a typedesc # param to a regular proc (again, known at instantiation) - result = evalTypeTrait(n, t, getCurrOwner(c)) + result = evalTypeTrait(c, n, t, getCurrOwner(c)) else: # a typedesc variable, pass unmodified to evals result = n @@ -221,9 +221,9 @@ proc semOf(c: PContext, n: PNode): PNode = let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc}) if x.kind == tyTypeDesc or y.kind != tyTypeDesc: - localError(c.config, n.info, errXExpectsObjectTypes, "of") + localError(c.config, n.info, "'of' takes object types") elif b.kind != tyObject or a.kind != tyObject: - localError(c.config, n.info, errXExpectsObjectTypes, "of") + localError(c.config, n.info, "'of' takes object types") else: let diff = inheritanceDiff(a, b) # | returns: 0 iff `a` == `b` @@ -232,26 +232,26 @@ proc semOf(c: PContext, n: PNode): PNode = # | returns: `maxint` iff `a` and `b` are not compatible at all if diff <= 0: # optimize to true: - message(n.info, hintConditionAlwaysTrue, renderTree(n)) + message(c.config, n.info, hintConditionAlwaysTrue, renderTree(n)) result = newIntNode(nkIntLit, 1) result.info = n.info - result.typ = getSysType(tyBool) + result.typ = getSysType(c.graph, n.info, tyBool) return result elif diff == high(int): - localError(c.config, n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) + localError(c.config, n.info, "'$1' cannot be of this subtype" % typeToString(a)) else: - localError(c.config, n.info, errXExpectsTwoArguments, "of") - n.typ = getSysType(tyBool) + localError(c.config, n.info, "'of' takes 2 arguments") + n.typ = getSysType(c.graph, n.info, tyBool) result = n proc magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags): PNode = case n[0].sym.magic of mAddr: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) result = semAddr(c, n.sons[1], n[0].sym.name.s == "unsafeAddr") of mTypeOf: - checkSonsLen(n, 2) + checkSonsLen(n, 2, c.config) result = semTypeOf(c, n.sons[1]) of mArrGet: result = semArrGet(c, n, flags) of mArrPut: result = semArrPut(c, n, flags) @@ -263,8 +263,8 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mIsPartOf: result = semIsPartOf(c, n, flags) of mTypeTrait: result = semTypeTraits(c, n) of mAstToStr: - result = newStrNodeT(renderTree(n[1], {renderNoComments}), n) - result.typ = getSysType(tyString) + result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph) + result.typ = getSysType(c.graph, n.info, tyString) of mInstantiationInfo: result = semInstantiationInfo(c, n) of mOrd: result = semOrd(c, n) of mOf: result = semOf(c, n) diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index a47bc24ed..1e0802953 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -39,32 +39,32 @@ proc mergeInitStatus(existing: var InitStatus, newStatus: InitStatus) = of initUnknown: discard -proc invalidObjConstr(n: PNode) = +proc invalidObjConstr(c: PContext, n: PNode) = if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s[0] == ':': localError(c.config, n.info, "incorrect object construction syntax; use a space after the colon") else: localError(c.config, n.info, "incorrect object construction syntax") -proc locateFieldInInitExpr(field: PSym, initExpr: PNode): PNode = +proc locateFieldInInitExpr(c: PContext, field: PSym, initExpr: PNode): PNode = # Returns the assignment nkExprColonExpr node or nil let fieldId = field.name.id for i in 1 ..< initExpr.len: let assignment = initExpr[i] if assignment.kind != nkExprColonExpr: - invalidObjConstr(assignment) + invalidObjConstr(c, assignment) continue - if fieldId == considerQuotedIdent(assignment[0]).id: + if fieldId == considerQuotedIdent(c.config, assignment[0]).id: return assignment proc semConstrField(c: PContext, flags: TExprFlags, field: PSym, initExpr: PNode): PNode = - let assignment = locateFieldInInitExpr(field, initExpr) + let assignment = locateFieldInInitExpr(c, field, initExpr) if assignment != nil: if nfSem in assignment.flags: return assignment[1] if not fieldVisible(c, field): localError(c.config, initExpr.info, - "the field '$1' is not accessible.", [field.name.s]) + "the field '$1' is not accessible." % [field.name.s]) return var initValue = semExprFlagDispatched(c, assignment[1], flags) @@ -101,25 +101,25 @@ iterator directFieldsInRecList(recList: PNode): PNode = if recList.kind == nkSym: yield recList else: - internalAssert recList.kind == nkRecList + doAssert recList.kind == nkRecList for field in recList: if field.kind != nkSym: continue yield field template quoteStr(s: string): string = "'" & s & "'" -proc fieldsPresentInInitExpr(fieldsRecList, initExpr: PNode): string = +proc fieldsPresentInInitExpr(c: PContext, fieldsRecList, initExpr: PNode): string = result = "" for field in directFieldsInRecList(fieldsRecList): - let assignment = locateFieldInInitExpr(field.sym, initExpr) + let assignment = locateFieldInInitExpr(c, field.sym, initExpr) if assignment != nil: if result.len != 0: result.add ", " result.add field.sym.name.s.quoteStr -proc missingMandatoryFields(fieldsRecList, initExpr: PNode): string = +proc missingMandatoryFields(c: PContext, fieldsRecList, initExpr: PNode): string = for r in directFieldsInRecList(fieldsRecList): if {tfNotNil, tfNeedsInit} * r.sym.typ.flags != {}: - let assignment = locateFieldInInitExpr(r.sym, initExpr) + let assignment = locateFieldInInitExpr(c, r.sym, initExpr) if assignment == nil: if result == nil: result = r.sym.name.s @@ -127,8 +127,8 @@ proc missingMandatoryFields(fieldsRecList, initExpr: PNode): string = result.add ", " result.add r.sym.name.s -proc checkForMissingFields(recList, initExpr: PNode) = - let missing = missingMandatoryFields(recList, initExpr) +proc checkForMissingFields(c: PContext, recList, initExpr: PNode) = + let missing = missingMandatoryFields(c, recList, initExpr) if missing != nil: localError(c.config, initExpr.info, "fields not initialized: $1.", [missing]) @@ -146,14 +146,14 @@ proc semConstructFields(c: PContext, recNode: PNode, template fieldsPresentInBranch(branchIdx: int): string = let branch = recNode[branchIdx] let fields = branch[branch.len - 1] - fieldsPresentInInitExpr(fields, initExpr) + fieldsPresentInInitExpr(c, fields, initExpr) template checkMissingFields(branchNode: PNode) = let fields = branchNode[branchNode.len - 1] - checkForMissingFields(fields, initExpr) + checkForMissingFields(c, fields, initExpr) - let discriminator = recNode.sons[0]; - internalAssert discriminator.kind == nkSym + let discriminator = recNode.sons[0] + internalAssert c.config, discriminator.kind == nkSym var selectedBranch = -1 for i in 1 ..< recNode.len: @@ -165,8 +165,8 @@ proc semConstructFields(c: PContext, recNode: PNode, let prevFields = fieldsPresentInBranch(selectedBranch) let currentFields = fieldsPresentInBranch(i) localError(c.config, initExpr.info, - "The fields ($1) and ($2) cannot be initialized together, " & - "because they are from conflicting branches in the case object.", + ("The fields '$1' and '$2' cannot be initialized together, " & + "because they are from conflicting branches in the case object.") % [prevFields, currentFields]) result = initConflict else: @@ -180,8 +180,8 @@ proc semConstructFields(c: PContext, recNode: PNode, if discriminatorVal == nil: let fields = fieldsPresentInBranch(selectedBranch) localError(c.config, initExpr.info, - "you must provide a compile-time value for the discriminator '$1' " & - "in order to prove that it's safe to initialize $2.", + ("you must provide a compile-time value for the discriminator '$1' " & + "in order to prove that it's safe to initialize $2.") % [discriminator.sym.name.s, fields]) mergeInitStatus(result, initNone) else: @@ -219,7 +219,7 @@ proc semConstructFields(c: PContext, recNode: PNode, # value was given to the discrimator. We can assume that it will be # initialized to zero and this will select a particular branch as # a result: - let matchedBranch = recNode.pickCaseBranch newIntLit(0) + let matchedBranch = recNode.pickCaseBranch newIntLit(c.graph, initExpr.info, 0) checkMissingFields matchedBranch else: result = initPartial @@ -239,20 +239,17 @@ proc semConstructFields(c: PContext, recNode: PNode, result = if e != nil: initFull else: initNone else: - internalAssert false + internalAssert c.config, false proc semConstructType(c: PContext, initExpr: PNode, t: PType, flags: TExprFlags): InitStatus = var t = t result = initUnknown - while true: let status = semConstructFields(c, t.n, initExpr, flags) mergeInitStatus(result, status) - if status in {initPartial, initNone, initUnknown}: - checkForMissingFields t.n, initExpr - + checkForMissingFields c, t.n, initExpr let base = t.sons[0] if base == nil: break t = skipTypes(base, skipPtrs) @@ -296,17 +293,16 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = let field = result[i] if nfSem notin field.flags: if field.kind != nkExprColonExpr: - invalidObjConstr(field) + invalidObjConstr(c, field) continue - let id = considerQuotedIdent(field[0]) + let id = considerQuotedIdent(c.config, field[0]) # This node was not processed. There are two possible reasons: # 1) It was shadowed by a field with the same name on the left for j in 1 ..< i: - let prevId = considerQuotedIdent(result[j][0]) + let prevId = considerQuotedIdent(c.config, result[j][0]) if prevId.id == id.id: - localError(c.config, field.info, errFieldInitTwice, id.s) + localError(c.config, field.info, errFieldInitTwice % id.s) return # 2) No such field exists in the constructed type - localError(c.config, field.info, errUndeclaredFieldX, id.s) + localError(c.config, field.info, errUndeclaredFieldX % id.s) return - diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f09fad588..0df3ee1c4 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -338,10 +338,10 @@ proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode = result.info = n.info result.typ = typ else: - changeType(r1, typ, check=true) + changeType(c, r1, typ, check=true) result = r1 elif not sameType(result.typ, typ): - changeType(result, typ, check=false) + changeType(c, result, typ, check=false) proc findShadowedVar(c: PContext, v: PSym): PSym = for scope in walkScopes(c.currentScope.parent): -- cgit 1.4.1-2-gfad0