diff options
Diffstat (limited to 'compiler/msgs.nim')
-rw-r--r-- | compiler/msgs.nim | 169 |
1 files changed, 94 insertions, 75 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 895ba71f3..a63fbca7f 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -67,7 +67,7 @@ type errAmbiguousCallXYZ, errWrongNumberOfArguments, errXCannotBePassedToProcVar, errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProc, errImplOfXNotAllowed, - errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValue, + errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValueX, errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice, errInvalidOrderInArrayConstructor, errInvalidOrderInEnumX, errEnumXHasHoles, errExceptExpected, errInvalidTry, @@ -88,13 +88,16 @@ type errTemplateInstantiationTooNested, errInstantiationFrom, errInvalidIndexValueForTuple, errCommandExpectsFilename, errMainModuleMustBeSpecified, - errXExpected, + errXExpected, + errTIsNotAConcreteType, errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely, errOnlyACallOpCanBeDelegator, errUsingNoSymbol, - - errXExpectsTwoArguments, + errMacroBodyDependsOnGenericTypes, + errDestructorNotGenericEnough, + errInlineIteratorsAsProcParams, + errXExpectsTwoArguments, errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX, errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument, @@ -102,6 +105,10 @@ type errXhasSideEffects, errIteratorExpected, errLetNeedsInit, errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX, errXCannotBeClosure, errXMustBeCompileTime, + errCannotInferTypeOfTheLiteral, + errCannotInferReturnType, + errGenericLambdaNotAllowed, + errCompilerDoesntSupportTarget, errUser, warnCannotOpenFile, warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit, @@ -112,7 +119,7 @@ type warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitClosure, warnEachIdentIsTuple, warnShadowIdent, warnProveInit, warnProveField, warnProveIndex, - warnUninit, warnUser, + warnUninit, warnGcMem, warnUser, hintSuccess, hintSuccessX, hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, @@ -195,7 +202,7 @@ const 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: "constant division by zero", + errConstantDivisionByZero: "division by zero", errOrdinalTypeExpected: "ordinal type expected", errOrdinalOrFloatTypeExpected: "ordinal or float type expected", errOverOrUnderflow: "over- or underflow", @@ -262,7 +269,7 @@ const errImplOfXNotAllowed: "implementation of \'$1\' is not allowed", errImplOfXexpected: "implementation of \'$1\' expected", errNoSymbolToBorrowFromFound: "no symbol to borrow from found", - errDiscardValue: "value returned by statement has to be discarded", + errDiscardValueX: "value of type '$1' has to be discarded", errInvalidDiscard: "statement returns no value that can be discarded", errIllegalConvFromXtoY: "conversion from $1 to $2 is invalid", errCannotBindXTwice: "cannot bind parameter \'$1\' twice", @@ -311,6 +318,7 @@ const 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.", errInvalidSectionStart: "invalid section start", errGridTableNotImplemented: "grid table is not implemented", errGeneralParseError: "general parse error", @@ -322,6 +330,12 @@ const errInstantiateXExplicitely: "instantiate '$1' explicitely", errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", + errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " & + "because the parameter '$1' has a generic type", + errDestructorNotGenericEnough: "Destructor signarue is too specific. " & + "A destructor must be associated will all instantiations of a generic type", + errInlineIteratorsAsProcParams: "inline iterators can be used as parameters only for " & + "templates, macros and other inline iterators", errXExpectsTwoArguments: "\'$1\' expects two arguments", errXExpectsObjectTypes: "\'$1\' expects object types", errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", @@ -343,6 +357,12 @@ const errIllegalCaptureX: "illegal capture '$1'", errXCannotBeClosure: "'$1' cannot have 'closure' calling convention", errXMustBeCompileTime: "'$1' can only be used in compile-time context", + errCannotInferTypeOfTheLiteral: "cannot infer the type of the $1", + errCannotInferReturnType: "cannot infer the return type of the proc", + 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 infered from the expected signature.", + errCompilerDoesntSupportTarget: "The current compiler \'$1\' doesn't support the requested compilation target", errUser: "$1", warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]", warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]", @@ -367,6 +387,7 @@ const warnProveField: "cannot prove that field '$1' is accessible [ProveField]", warnProveIndex: "cannot prove index '$1' is valid [ProveIndex]", warnUninit: "'$1' might not have been initialized [Uninit]", + warnGcMem: "'$1' uses GC'ed memory [GcMem]", warnUser: "$1 [User]", hintSuccess: "operation successful [Success]", hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]", @@ -386,7 +407,7 @@ const hintUser: "$1 [User]"] const - WarningsToStr*: array[0..23, string] = ["CannotOpenFile", "OctalEscape", + WarningsToStr*: array[0..24, string] = ["CannotOpenFile", "OctalEscape", "XIsNeverRead", "XmightNotBeenInit", "Deprecated", "ConfigDeprecated", "SmallLshouldNotBeUsed", "UnknownMagic", @@ -394,7 +415,7 @@ const "CommentXIgnored", "NilStmt", "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "ImplicitClosure", "EachIdentIsTuple", "ShadowIdent", - "ProveInit", "ProveField", "ProveIndex", "Uninit", "User"] + "ProveInit", "ProveField", "ProveIndex", "Uninit", "GcMem", "User"] HintsToStr*: array[0..15, string] = ["Success", "SuccessX", "LineTooLong", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", @@ -445,7 +466,7 @@ type TErrorOutputs* = set[TErrorOutput] ERecoverableError* = object of EInvalidValue - ESuggestDone* = object of EBase + ESuggestDone* = object of E_Base const InvalidFileIDX* = int32(-1) @@ -453,9 +474,9 @@ const var filenameToIndexTbl = initTable[string, int32]() fileInfos*: seq[TFileInfo] = @[] - SystemFileIdx*: int32 + systemFileIdx*: int32 -proc toCChar*(c: Char): string = +proc toCChar*(c: char): string = case c of '\0'..'\x1F', '\x80'..'\xFF': result = '\\' & toOctal(c) of '\'', '\"', '\\': result = '\\' & c @@ -474,7 +495,7 @@ proc makeCString*(s: string): PRope = add(res, '\"') add(res, tnl) app(result, toRope(res)) # reset: - setlen(res, 1) + setLen(res, 1) res[0] = '\"' add(res, toCChar(s[i])) add(res, '\"') @@ -545,14 +566,14 @@ var when useCaas: var stdoutSocket*: TSocket -proc UnknownLineInfo*(): TLineInfo = +proc unknownLineInfo*(): TLineInfo = result.line = int16(-1) result.col = int16(-1) result.fileIndex = -1 var msgContext: seq[TLineInfo] = @[] - lastError = UnknownLineInfo() + lastError = unknownLineInfo() bufferedMsgs*: seq[string] errorOutputs* = {eStdOut, eStdErr} @@ -560,20 +581,20 @@ var proc clearBufferedMsgs* = bufferedMsgs = nil -proc SuggestWriteln*(s: string) = +proc suggestWriteln*(s: string) = if eStdOut in errorOutputs: when useCaas: - if isNil(stdoutSocket): Writeln(stdout, s) + if isNil(stdoutSocket): writeln(stdout, s) else: - Writeln(stdout, s) + writeln(stdout, s) stdoutSocket.send(s & "\c\L") else: - Writeln(stdout, s) + writeln(stdout, s) if eInMemory in errorOutputs: bufferedMsgs.safeAdd(s) -proc SuggestQuit*() = +proc suggestQuit*() = if not isServing: quit(0) elif isWorkingWithDirtyBuffer: @@ -601,12 +622,12 @@ proc pushInfoContext*(info: TLineInfo) = msgContext.add(info) proc popInfoContext*() = - setlen(msgContext, len(msgContext) - 1) + setLen(msgContext, len(msgContext) - 1) proc getInfoContext*(index: int): TLineInfo = let L = msgContext.len let i = if index < 0: L + index else: index - if i >=% L: result = UnknownLineInfo() + if i >=% L: result = unknownLineInfo() else: result = msgContext[i] proc toFilename*(fileIdx: int32): string = @@ -643,6 +664,8 @@ proc toFileLine*(info: TLineInfo): string {.inline.} = proc toFileLineCol*(info: TLineInfo): string {.inline.} = result = info.toFilename & "(" & $info.line & "," & $info.col & ")" +template `$`*(info: TLineInfo): expr = toFileLineCol(info) + proc `??`* (info: TLineInfo, filename: string): bool = # only for debugging purposes result = filename in info.toFilename @@ -656,18 +679,18 @@ proc addCheckpoint*(info: TLineInfo) = proc addCheckpoint*(filename: string, line: int) = addCheckpoint(newLineInfo(filename, line, - 1)) -proc OutWriteln*(s: string) = +proc outWriteln*(s: string) = ## Writes to stdout. Always. - if eStdOut in errorOutputs: Writeln(stdout, s) + if eStdOut in errorOutputs: writeln(stdout, s) -proc MsgWriteln*(s: string) = +proc msgWriteln*(s: string) = ## Writes to stdout. If --stdout option is given, writes to stderr instead. if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return if optStdout in gGlobalOptions: - if eStdErr in errorOutputs: Writeln(stderr, s) + if eStdErr in errorOutputs: writeln(stderr, s) else: - if eStdOut in errorOutputs: Writeln(stdout, s) + if eStdOut in errorOutputs: writeln(stdout, s) if eInMemory in errorOutputs: bufferedMsgs.safeAdd(s) @@ -675,9 +698,9 @@ proc coordToStr(coord: int): string = if coord == -1: result = "???" else: result = $coord -proc MsgKindToString*(kind: TMsgKind): string = +proc msgKindToString*(kind: TMsgKind): string = # later versions may provide translated error messages - result = msgKindToStr[kind] + result = MsgKindToStr[kind] proc getMessageStr(msg: TMsgKind, arg: string): string = result = msgKindToString(msg) % [arg] @@ -699,58 +722,55 @@ type TErrorHandling = enum doNothing, doAbort, doRaise proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = - template maybeTrace = - if defined(debug) or gVerbosity >= 3: + template quit = + if defined(debug) or gVerbosity >= 3 or msg == errInternal: writeStackTrace() + quit 1 - if msg == errInternal: - writeStackTrace() # we always want a stack trace here - if msg >= fatalMin and msg <= fatalMax: - maybeTrace() - quit(1) - if msg >= errMin and msg <= errMax: - maybeTrace() + if msg >= fatalMin and msg <= fatalMax: + quit() + if msg >= errMin and msg <= errMax: inc(gErrorCounter) options.gExitcode = 1'i8 - if gErrorCounter >= gErrorMax: - quit(1) + if gErrorCounter >= gErrorMax: + quit() elif eh == doAbort and gCmd != cmdIdeTools: - quit(1) + quit() elif eh == doRaise: raiseRecoverableError(s) -proc `==`*(a, b: TLineInfo): bool = +proc `==`*(a, b: TLineInfo): bool = result = a.line == b.line and a.fileIndex == b.fileIndex proc writeContext(lastinfo: TLineInfo) = - var info = lastInfo + var info = lastinfo for i in countup(0, len(msgContext) - 1): - if msgContext[i] != lastInfo and msgContext[i] != info: - MsgWriteln(posContextFormat % [toMsgFilename(msgContext[i]), + if msgContext[i] != lastinfo and msgContext[i] != info: + msgWriteln(PosContextFormat % [toMsgFilename(msgContext[i]), coordToStr(msgContext[i].line), coordToStr(msgContext[i].col), getMessageStr(errInstantiationFrom, "")]) info = msgContext[i] -proc rawMessage*(msg: TMsgKind, args: openarray[string]) = +proc rawMessage*(msg: TMsgKind, args: openArray[string]) = var frmt: string case msg of errMin..errMax: writeContext(unknownLineInfo()) - frmt = rawErrorFormat + frmt = RawErrorFormat of warnMin..warnMax: if optWarns notin gOptions: return if msg notin gNotes: return writeContext(unknownLineInfo()) - frmt = rawWarningFormat + frmt = RawWarningFormat inc(gWarnCounter) of hintMin..hintMax: if optHints notin gOptions: return if msg notin gNotes: return - frmt = rawHintFormat + frmt = RawHintFormat inc(gHintCounter) let s = `%`(frmt, `%`(msgKindToString(msg), args)) - MsgWriteln(s) + msgWriteln(s) handleError(msg, doAbort, s) proc rawMessage*(msg: TMsgKind, arg: string) = @@ -758,8 +778,8 @@ proc rawMessage*(msg: TMsgKind, arg: string) = proc writeSurroundingSrc(info: TLineInfo) = const indent = " " - MsgWriteln(indent & info.sourceLine.ropeToStr) - MsgWriteln(indent & repeatChar(info.col, ' ') & '^') + msgWriteln(indent & info.sourceLine.ropeToStr) + msgWriteln(indent & repeatChar(info.col, ' ') & '^') proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, eh: TErrorHandling) = @@ -768,7 +788,7 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, case msg of errMin..errMax: writeContext(info) - frmt = posErrorFormat + frmt = PosErrorFormat # we try to filter error messages so that not two error message # in the same file and line are produced: #ignoreMsg = lastError == info and eh != doAbort @@ -776,54 +796,54 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, of warnMin..warnMax: ignoreMsg = optWarns notin gOptions or msg notin gNotes if not ignoreMsg: writeContext(info) - frmt = posWarningFormat + frmt = PosWarningFormat inc(gWarnCounter) of hintMin..hintMax: ignoreMsg = optHints notin gOptions or msg notin gNotes - frmt = posHintFormat + frmt = PosHintFormat inc(gHintCounter) let s = frmt % [toMsgFilename(info), coordToStr(info.line), coordToStr(info.col), getMessageStr(msg, arg)] if not ignoreMsg: - MsgWriteln(s) + msgWriteln(s) if optPrintSurroundingSrc and msg in errMin..errMax: info.writeSurroundingSrc handleError(msg, eh, s) -proc Fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doAbort) -proc GlobalError*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc globalError*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doRaise) -proc GlobalError*(info: TLineInfo, arg: string) = +proc globalError*(info: TLineInfo, arg: string) = liMessage(info, errGenerated, arg, doRaise) -proc LocalError*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc localError*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doNothing) -proc LocalError*(info: TLineInfo, arg: string) = +proc localError*(info: TLineInfo, arg: string) = liMessage(info, errGenerated, arg, doNothing) -proc Message*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc message*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doNothing) -proc InternalError*(info: TLineInfo, errMsg: string) = +proc internalError*(info: TLineInfo, errMsg: string) = if gCmd == cmdIdeTools: return writeContext(info) liMessage(info, errInternal, errMsg, doAbort) -proc InternalError*(errMsg: string) = +proc internalError*(errMsg: string) = if gCmd == cmdIdeTools: return - writeContext(UnknownLineInfo()) + writeContext(unknownLineInfo()) rawMessage(errInternal, errMsg) -template AssertNotNil*(e: expr): expr = - if e == nil: InternalError($InstantiationInfo()) +template assertNotNil*(e: expr): expr = + if e == nil: internalError($instantiationInfo()) e -template InternalAssert*(e: bool): stmt = - if not e: InternalError($InstantiationInfo()) +template internalAssert*(e: bool): stmt = + if not e: internalError($instantiationInfo()) proc addSourceLine*(fileIdx: int32, line: string) = fileInfos[fileIdx].lines.add line.toRope @@ -837,23 +857,22 @@ proc sourceLine*(i: TLineInfo): PRope = addSourceLine i.fileIndex, line.string except EIO: discard - InternalAssert i.fileIndex < fileInfos.len + internalAssert i.fileIndex < fileInfos.len # can happen if the error points to EOF: if i.line > fileInfos[i.fileIndex].lines.len: return nil result = fileInfos[i.fileIndex].lines[i.line-1] proc quotedFilename*(i: TLineInfo): PRope = - InternalAssert i.fileIndex >= 0 + internalAssert i.fileIndex >= 0 result = fileInfos[i.fileIndex].quotedName -ropes.ErrorHandler = proc (err: TRopesError, msg: string, useWarning: bool) = +ropes.errorHandler = proc (err: TRopesError, msg: string, useWarning: bool) = case err of rInvalidFormatStr: internalError("ropes: invalid format string: " & msg) of rTokenTooLong: internalError("ropes: token too long: " & msg) of rCannotOpenFile: - rawMessage(if useWarning: warnCannotOpenFile else: errCannotOpenFile, - msg) - + rawMessage(if useWarning: warnCannotOpenFile else: errCannotOpenFile, msg) + |