mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-26 12:55:06 +00:00
better error handling for better idetools support
This commit is contained in:
@@ -918,18 +918,17 @@ proc expectString(n: PNode) =
|
||||
|
||||
proc evalSlurp*(e: PNode, module: PSym): PNode =
|
||||
expectString(e)
|
||||
result = newNodeIT(nkStrLit, e.info, getSysType(tyString))
|
||||
try:
|
||||
var filename = e.strVal.FindFile
|
||||
var content = readFile(filename)
|
||||
result = newStrNode(nkStrLit, content)
|
||||
result.typ = getSysType(tyString)
|
||||
result.info = e.info
|
||||
result.strVal = readFile(filename)
|
||||
# we produce a fake include statement for every slurped filename, so that
|
||||
# the module dependencies are accurate:
|
||||
appendToModule(module, newNode(nkIncludeStmt, e.info, @[
|
||||
newStrNode(nkStrLit, filename)]))
|
||||
except EIO:
|
||||
GlobalError(e.info, errCannotOpenFile, e.strVal)
|
||||
result.strVal = ""
|
||||
LocalError(e.info, errCannotOpenFile, e.strVal)
|
||||
|
||||
proc readOutput(p: PProcess): string =
|
||||
result = ""
|
||||
|
||||
@@ -76,21 +76,23 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||
proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
|
||||
let ident = lookups.considerAcc(n)
|
||||
let s = StrTableGet(fromMod.tab, ident)
|
||||
if s == nil: GlobalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
if s.kind == skStub: loadStub(s)
|
||||
if s.Kind notin ExportableSymKinds:
|
||||
InternalError(n.info, "importSymbol: 2")
|
||||
# for an enumeration we have to add all identifiers
|
||||
case s.Kind
|
||||
of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter:
|
||||
# for a overloadable syms add all overloaded routines
|
||||
var it: TIdentIter
|
||||
var e = InitIdentIter(it, fromMod.tab, s.name)
|
||||
while e != nil:
|
||||
if e.name.id != s.Name.id: InternalError(n.info, "importSymbol: 3")
|
||||
rawImportSymbol(c, e)
|
||||
e = NextIdentIter(it, fromMod.tab)
|
||||
else: rawImportSymbol(c, s)
|
||||
if s == nil:
|
||||
LocalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
else:
|
||||
if s.kind == skStub: loadStub(s)
|
||||
if s.Kind notin ExportableSymKinds:
|
||||
InternalError(n.info, "importSymbol: 2")
|
||||
# for an enumeration we have to add all identifiers
|
||||
case s.Kind
|
||||
of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter:
|
||||
# for a overloadable syms add all overloaded routines
|
||||
var it: TIdentIter
|
||||
var e = InitIdentIter(it, fromMod.tab, s.name)
|
||||
while e != nil:
|
||||
if e.name.id != s.Name.id: InternalError(n.info, "importSymbol: 3")
|
||||
rawImportSymbol(c, e)
|
||||
e = NextIdentIter(it, fromMod.tab)
|
||||
else: rawImportSymbol(c, s)
|
||||
|
||||
proc importAllSymbols(c: PContext, fromMod: PSym) =
|
||||
var i: TTabIter
|
||||
|
||||
@@ -36,6 +36,11 @@ proc considerAcc*(n: PNode): PIdent =
|
||||
result = getIdent(id)
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
|
||||
proc errorSym*(n: PNode): PSym =
|
||||
## creates an error symbol to avoid cascading errors (for IDE support)
|
||||
result = newSym(skUnknown, considerAcc(n), getCurrOwner())
|
||||
result.info = n.info
|
||||
|
||||
type
|
||||
TOverloadIterMode* = enum
|
||||
@@ -122,13 +127,17 @@ proc lookUp*(c: PContext, n: PNode): PSym =
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
result = SymtabGet(c.Tab, n.ident)
|
||||
if result == nil: GlobalError(n.info, errUndeclaredIdentifier, n.ident.s)
|
||||
if result == nil:
|
||||
LocalError(n.info, errUndeclaredIdentifier, n.ident.s)
|
||||
result = errorSym(n)
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
of nkAccQuoted:
|
||||
var ident = considerAcc(n)
|
||||
result = SymtabGet(c.Tab, ident)
|
||||
if result == nil: GlobalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
if result == nil:
|
||||
LocalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
result = errorSym(n)
|
||||
else: InternalError(n.info, "lookUp")
|
||||
if Contains(c.AmbiguousSymbols, result.id):
|
||||
LocalError(n.info, errUseQualifier, result.name.s)
|
||||
@@ -144,7 +153,8 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||
var ident = considerAcc(n)
|
||||
result = SymtabGet(c.Tab, ident)
|
||||
if result == nil and checkUndeclared in flags:
|
||||
GlobalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
LocalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
result = errorSym(n)
|
||||
elif checkAmbiguity in flags and result != nil and
|
||||
Contains(c.AmbiguousSymbols, result.id):
|
||||
LocalError(n.info, errUseQualifier, ident.s)
|
||||
@@ -167,10 +177,12 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||
else:
|
||||
result = StrTableGet(m.tab, ident)
|
||||
if result == nil and checkUndeclared in flags:
|
||||
GlobalError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
|
||||
elif checkUndeclared in flags:
|
||||
GlobalError(n.sons[1].info, errIdentifierExpected,
|
||||
renderTree(n.sons[1]))
|
||||
LocalError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
|
||||
result = errorSym(n.sons[1])
|
||||
elif checkUndeclared in flags:
|
||||
LocalError(n.sons[1].info, errIdentifierExpected,
|
||||
renderTree(n.sons[1]))
|
||||
result = errorSym(n.sons[1])
|
||||
else:
|
||||
result = nil
|
||||
if result != nil and result.kind == skStub: loadStub(result)
|
||||
@@ -205,8 +217,9 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
else:
|
||||
result = InitIdentIter(o.it, o.m.tab, ident)
|
||||
else:
|
||||
GlobalError(n.sons[1].info, errIdentifierExpected,
|
||||
renderTree(n.sons[1]))
|
||||
LocalError(n.sons[1].info, errIdentifierExpected,
|
||||
renderTree(n.sons[1]))
|
||||
result = errorSym(n.sons[1])
|
||||
of nkSymChoice:
|
||||
o.mode = oimSymChoice
|
||||
result = n.sons[0].sym
|
||||
|
||||
@@ -576,7 +576,7 @@ proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
|
||||
assert(false) # we want a stack trace here
|
||||
if msg >= fatalMin and msg <= fatalMax:
|
||||
if gVerbosity >= 3: assert(false)
|
||||
quit(1)
|
||||
if gCmd != cmdIdeTools: quit(1)
|
||||
if msg >= errMin and msg <= errMax:
|
||||
if gVerbosity >= 3: assert(false)
|
||||
inc(gErrorCounter)
|
||||
|
||||
@@ -109,14 +109,23 @@ proc processImportObjC(s: PSym, extname: string) =
|
||||
incl(s.flags, sfNamedParamCall)
|
||||
excl(s.flags, sfForward)
|
||||
|
||||
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
|
||||
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
||||
result.strVal = ""
|
||||
|
||||
proc getStrLitNode(c: PContext, n: PNode): PNode =
|
||||
if n.kind != nkExprColonExpr:
|
||||
GlobalError(n.info, errStringLiteralExpected)
|
||||
else:
|
||||
LocalError(n.info, errStringLiteralExpected)
|
||||
# error correction:
|
||||
result = newEmptyStrNode(n)
|
||||
else:
|
||||
n.sons[1] = c.semConstExpr(c, n.sons[1])
|
||||
case n.sons[1].kind
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1]
|
||||
else: GlobalError(n.info, errStringLiteralExpected)
|
||||
else:
|
||||
LocalError(n.info, errStringLiteralExpected)
|
||||
# error correction:
|
||||
result = newEmptyStrNode(n)
|
||||
|
||||
proc expectStrLit(c: PContext, n: PNode): string =
|
||||
result = getStrLitNode(c, n).strVal
|
||||
@@ -190,13 +199,17 @@ proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib =
|
||||
Append(c.libs, result)
|
||||
|
||||
proc expectDynlibNode(c: PContext, n: PNode): PNode =
|
||||
if n.kind != nkExprColonExpr: GlobalError(n.info, errStringLiteralExpected)
|
||||
else:
|
||||
if n.kind != nkExprColonExpr:
|
||||
LocalError(n.info, errStringLiteralExpected)
|
||||
# error correction:
|
||||
result = newEmptyStrNode(n)
|
||||
else:
|
||||
result = c.semExpr(c, n.sons[1])
|
||||
if result.kind == nkSym and result.sym.kind == skConst:
|
||||
result = result.sym.ast # look it up
|
||||
if result.typ == nil or result.typ.kind != tyString:
|
||||
GlobalError(n.info, errStringLiteralExpected)
|
||||
LocalError(n.info, errStringLiteralExpected)
|
||||
result = newEmptyStrNode(n)
|
||||
|
||||
proc processDynLib(c: PContext, n: PNode, sym: PSym) =
|
||||
if (sym == nil) or (sym.kind == skModule):
|
||||
@@ -359,7 +372,9 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||
result = copyNode(n)
|
||||
var str = n.sons[1].strVal
|
||||
if str == "": GlobalError(n.info, errEmptyAsm)
|
||||
if str == "":
|
||||
LocalError(n.info, errEmptyAsm)
|
||||
return
|
||||
# now parse the string literal and substitute symbols:
|
||||
var a = 0
|
||||
while true:
|
||||
@@ -405,15 +420,20 @@ proc PragmaLine(c: PContext, n: PNode) =
|
||||
if n.kind == nkExprColonExpr:
|
||||
n.sons[1] = c.semConstExpr(c, n.sons[1])
|
||||
let a = n.sons[1]
|
||||
if a.kind != nkPar: GlobalError(n.info, errXExpected, "tuple")
|
||||
var x = a.sons[0]
|
||||
var y = a.sons[1]
|
||||
if x.kind == nkExprColonExpr: x = x.sons[1]
|
||||
if y.kind == nkExprColonExpr: y = y.sons[1]
|
||||
if x.kind != nkStrLit: GlobalError(n.info, errStringLiteralExpected)
|
||||
if y.kind != nkIntLit: GlobalError(n.info, errIntLiteralExpected)
|
||||
n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
|
||||
n.info.line = int16(y.intVal)
|
||||
if a.kind == nkPar:
|
||||
var x = a.sons[0]
|
||||
var y = a.sons[1]
|
||||
if x.kind == nkExprColonExpr: x = x.sons[1]
|
||||
if y.kind == nkExprColonExpr: y = y.sons[1]
|
||||
if x.kind != nkStrLit:
|
||||
LocalError(n.info, errStringLiteralExpected)
|
||||
elif y.kind != nkIntLit:
|
||||
LocalError(n.info, errIntLiteralExpected)
|
||||
else:
|
||||
n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
|
||||
n.info.line = int16(y.intVal)
|
||||
else:
|
||||
LocalError(n.info, errXExpected, "tuple")
|
||||
else:
|
||||
# sensible default:
|
||||
n.info = getInfoContext(-1)
|
||||
|
||||
@@ -37,7 +37,7 @@ proc addResultNode(c: PContext, n: PNode)
|
||||
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
|
||||
|
||||
proc typeMismatch(n: PNode, formal, actual: PType) =
|
||||
GlobalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &
|
||||
LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &
|
||||
typeToString(actual) & ") " &
|
||||
`%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
|
||||
|
||||
@@ -45,6 +45,9 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
|
||||
result = IndexTypesMatch(c, formal, arg.typ, arg)
|
||||
if result == nil:
|
||||
typeMismatch(arg, formal, arg.typ)
|
||||
# error correction:
|
||||
result = copyNode(arg)
|
||||
result.typ = formal
|
||||
|
||||
proc isTopLevel(c: PContext): bool {.inline.} =
|
||||
result = c.tab.tos <= 2
|
||||
@@ -62,7 +65,7 @@ proc semStmtScope(c: PContext, n: PNode): PNode
|
||||
|
||||
proc ParamsTypeCheck(c: PContext, typ: PType) {.inline.} =
|
||||
if not typeAllowed(typ, skConst):
|
||||
GlobalError(typ.n.info, errXisNoType, typeToString(typ))
|
||||
LocalError(typ.n.info, errXisNoType, typeToString(typ))
|
||||
|
||||
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym
|
||||
|
||||
@@ -80,13 +83,15 @@ proc evalTypedExpr(c: PContext, e: PNode): PNode =
|
||||
if result == nil:
|
||||
result = evalConstExpr(c.module, e)
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
GlobalError(e.info, errConstExprExpected)
|
||||
LocalError(e.info, errConstExprExpected)
|
||||
# error correction:
|
||||
result = e
|
||||
|
||||
proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||
var e = semExprWithType(c, n)
|
||||
if e == nil:
|
||||
GlobalError(n.info, errConstExprExpected)
|
||||
return nil
|
||||
LocalError(n.info, errConstExprExpected)
|
||||
return n
|
||||
result = evalTypedExpr(c, e)
|
||||
|
||||
include seminst, semcall
|
||||
@@ -129,12 +134,15 @@ proc forceBool(c: PContext, n: PNode): PNode =
|
||||
if result == nil: result = n
|
||||
|
||||
proc semConstBoolExpr(c: PContext, n: PNode): PNode =
|
||||
result = fitNode(c, getSysType(tyBool), semExprWithType(c, n))
|
||||
if result == nil:
|
||||
GlobalError(n.info, errConstExprExpected)
|
||||
return
|
||||
let nn = semExprWithType(c, n)
|
||||
result = fitNode(c, getSysType(tyBool), nn)
|
||||
if result == nil:
|
||||
LocalError(n.info, errConstExprExpected)
|
||||
return nn
|
||||
result = getConstExpr(c.module, result)
|
||||
if result == nil: GlobalError(n.info, errConstExprExpected)
|
||||
if result == nil:
|
||||
LocalError(n.info, errConstExprExpected)
|
||||
result = nn
|
||||
|
||||
include semtypes, semexprs, semgnrc, semstmts
|
||||
|
||||
|
||||
@@ -224,6 +224,10 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||
proc newTypeS(kind: TTypeKind, c: PContext): PType =
|
||||
result = newType(kind, getCurrOwner())
|
||||
|
||||
proc errorType*(c: PContext): PType =
|
||||
## creates a type representing an error state
|
||||
result = newTypeS(tyEmpty, c)
|
||||
|
||||
proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
|
||||
dest.kind = kind
|
||||
dest.owner = getCurrOwner()
|
||||
|
||||
@@ -42,8 +42,9 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
if result.typ != nil:
|
||||
if result.typ.kind == tyVar: result = newDeref(result)
|
||||
else:
|
||||
GlobalError(n.info, errExprXHasNoType,
|
||||
renderTree(result, {renderNoComments}))
|
||||
LocalError(n.info, errExprXHasNoType,
|
||||
renderTree(result, {renderNoComments}))
|
||||
result.typ = errorType(c)
|
||||
|
||||
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
result = semExpr(c, n, flags)
|
||||
@@ -51,8 +52,9 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
# do not produce another redundant error message:
|
||||
raiseRecoverableError("")
|
||||
if result.typ == nil:
|
||||
GlobalError(n.info, errExprXHasNoType,
|
||||
renderTree(result, {renderNoComments}))
|
||||
LocalError(n.info, errExprXHasNoType,
|
||||
renderTree(result, {renderNoComments}))
|
||||
result.typ = errorType(c)
|
||||
|
||||
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||
result = symChoice(c, n, s)
|
||||
@@ -113,7 +115,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||
c.p.owner.typ.callConv = ccClosure
|
||||
if illegalCapture(s) or c.p.next.owner != s.owner:
|
||||
# Currently captures are restricted to a single level of nesting:
|
||||
GlobalError(n.info, errIllegalCaptureX, s.name.s)
|
||||
LocalError(n.info, errIllegalCaptureX, s.name.s)
|
||||
result = newSymNode(s, n.info)
|
||||
of skGenericParam:
|
||||
if s.ast == nil: InternalError(n.info, "no default for")
|
||||
@@ -129,7 +131,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||
proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) =
|
||||
var diff = inheritanceDiff(castDest, src)
|
||||
if diff == high(int):
|
||||
GlobalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [
|
||||
LocalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [
|
||||
src.typeToString, castDest.typeToString])
|
||||
|
||||
const
|
||||
@@ -147,7 +149,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) =
|
||||
d = base(d)
|
||||
s = base(s)
|
||||
if d == nil:
|
||||
GlobalError(info, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [
|
||||
LocalError(info, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [
|
||||
src.typeToString, castDest.typeToString])
|
||||
elif d.Kind == tyObject and s.Kind == tyObject:
|
||||
checkConversionBetweenObjects(info, d, s)
|
||||
@@ -159,7 +161,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) =
|
||||
case cmpTypes(d, s)
|
||||
of isNone, isGeneric:
|
||||
if not compareTypes(castDest, src, dcEqIgnoreDistinct):
|
||||
GlobalError(info, errGenerated, `%`(
|
||||
LocalError(info, errGenerated, `%`(
|
||||
MsgKindToString(errIllegalConvFromXtoY),
|
||||
[typeToString(src), typeToString(castDest)]))
|
||||
else:
|
||||
@@ -184,7 +186,9 @@ proc isCastable(dst, src: PType): bool =
|
||||
(skipTypes(src, abstractInst).kind in IntegralTypes)
|
||||
|
||||
proc semConv(c: PContext, n: PNode, s: PSym): PNode =
|
||||
if sonsLen(n) != 2: GlobalError(n.info, errConvNeedsOneArg)
|
||||
if sonsLen(n) != 2:
|
||||
LocalError(n.info, errConvNeedsOneArg)
|
||||
return n
|
||||
result = newNodeI(nkConv, n.info)
|
||||
result.typ = semTypeNode(c, n.sons[0], nil)
|
||||
addSon(result, copyTree(n.sons[0]))
|
||||
@@ -210,14 +214,14 @@ proc semCast(c: PContext, n: PNode): PNode =
|
||||
addSon(result, copyTree(n.sons[0]))
|
||||
addSon(result, semExprWithType(c, n.sons[1]))
|
||||
if not isCastable(result.typ, result.sons[1].Typ):
|
||||
GlobalError(result.info, errExprCannotBeCastedToX,
|
||||
typeToString(result.Typ))
|
||||
LocalError(result.info, errExprCannotBeCastedToX,
|
||||
typeToString(result.Typ))
|
||||
|
||||
proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
const
|
||||
opToStr: array[mLow..mHigh, string] = ["low", "high"]
|
||||
if sonsLen(n) != 2:
|
||||
GlobalError(n.info, errXExpectsTypeOrValue, opToStr[m])
|
||||
LocalError(n.info, errXExpectsTypeOrValue, opToStr[m])
|
||||
else:
|
||||
n.sons[1] = semExprWithType(c, n.sons[1])
|
||||
restoreOldStyleType(n.sons[1])
|
||||
@@ -229,12 +233,12 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
n.typ = n.sons[1].typ.sons[0] # indextype
|
||||
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
|
||||
n.typ = n.sons[1].typ
|
||||
else: GlobalError(n.info, errInvalidArgForX, opToStr[m])
|
||||
else: LocalError(n.info, errInvalidArgForX, opToStr[m])
|
||||
result = n
|
||||
|
||||
proc semSizeof(c: PContext, n: PNode): PNode =
|
||||
if sonsLen(n) != 2:
|
||||
GlobalError(n.info, errXExpectsTypeOrValue, "sizeof")
|
||||
LocalError(n.info, errXExpectsTypeOrValue, "sizeof")
|
||||
else:
|
||||
n.sons[1] = semExprWithType(c, n.sons[1])
|
||||
restoreOldStyleType(n.sons[1])
|
||||
@@ -253,26 +257,27 @@ proc semOf(c: PContext, n: PNode): PNode =
|
||||
let y = skipTypes(n.sons[2].typ, abstractPtrs)
|
||||
|
||||
if x.kind == tyTypeDesc or y.kind != tyTypeDesc:
|
||||
GlobalError(n.info, errXExpectsObjectTypes, "of")
|
||||
LocalError(n.info, errXExpectsObjectTypes, "of")
|
||||
elif b.kind != tyObject or a.kind != tyObject:
|
||||
GlobalError(n.info, errXExpectsObjectTypes, "of")
|
||||
let diff = inheritanceDiff(a, b)
|
||||
# | returns: 0 iff `a` == `b`
|
||||
# | returns: -x iff `a` is the x'th direct superclass of `b`
|
||||
# | returns: +x iff `a` is the x'th direct subclass of `b`
|
||||
# | returns: `maxint` iff `a` and `b` are not compatible at all
|
||||
if diff <= 0:
|
||||
# optimize to true:
|
||||
Message(n.info, hintConditionAlwaysTrue, renderTree(n))
|
||||
result = newIntNode(nkIntLit, 1)
|
||||
result.info = n.info
|
||||
result.typ = getSysType(tyBool)
|
||||
return result
|
||||
elif diff == high(int):
|
||||
GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
|
||||
n.typ = getSysType(tyBool)
|
||||
else:
|
||||
GlobalError(n.info, errXExpectsTwoArguments, "of")
|
||||
LocalError(n.info, errXExpectsObjectTypes, "of")
|
||||
else:
|
||||
let diff = inheritanceDiff(a, b)
|
||||
# | returns: 0 iff `a` == `b`
|
||||
# | returns: -x iff `a` is the x'th direct superclass of `b`
|
||||
# | returns: +x iff `a` is the x'th direct subclass of `b`
|
||||
# | returns: `maxint` iff `a` and `b` are not compatible at all
|
||||
if diff <= 0:
|
||||
# optimize to true:
|
||||
Message(n.info, hintConditionAlwaysTrue, renderTree(n))
|
||||
result = newIntNode(nkIntLit, 1)
|
||||
result.info = n.info
|
||||
result.typ = getSysType(tyBool)
|
||||
return result
|
||||
elif diff == high(int):
|
||||
LocalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
|
||||
else:
|
||||
LocalError(n.info, errXExpectsTwoArguments, "of")
|
||||
n.typ = getSysType(tyBool)
|
||||
result = n
|
||||
|
||||
proc semIs(c: PContext, n: PNode): PNode =
|
||||
@@ -283,9 +288,9 @@ proc semIs(c: PContext, n: PNode): PNode =
|
||||
if n[2].kind notin {nkStrLit..nkTripleStrLit}:
|
||||
let b = semTypeNode(c, n[2], nil)
|
||||
n.sons[2] = newNodeIT(nkType, n[2].info, b)
|
||||
result = n
|
||||
else:
|
||||
GlobalError(n.info, errXExpectsTwoArguments, "is")
|
||||
LocalError(n.info, errXExpectsTwoArguments, "is")
|
||||
result = n
|
||||
|
||||
proc semOpAux(c: PContext, n: PNode) =
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
@@ -590,7 +595,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||
of skMacro, skTemplate: nil
|
||||
else:
|
||||
if (callee.kind == skIterator) and (callee.id == c.p.owner.id):
|
||||
GlobalError(n.info, errRecursiveDependencyX, callee.name.s)
|
||||
LocalError(n.info, errRecursiveDependencyX, callee.name.s)
|
||||
if sfNoSideEffect notin callee.flags:
|
||||
if {sfImportc, sfSideEffect} * callee.flags != {}:
|
||||
incl(c.p.owner.flags, sfSideEffect)
|
||||
@@ -625,7 +630,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
if m.state != csMatch:
|
||||
if c.inCompilesContext > 0:
|
||||
# speed up error generation:
|
||||
GlobalError(n.Info, errTypeMismatch, "")
|
||||
LocalError(n.Info, errTypeMismatch, "")
|
||||
return emptyNode
|
||||
else:
|
||||
var msg = msgKindToString(errTypeMismatch)
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
@@ -633,7 +639,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
add(msg, typeToString(n.sons[i].typ))
|
||||
add(msg, ")\n" & msgKindToString(errButExpected) & "\n" &
|
||||
typeToString(n.sons[0].typ))
|
||||
GlobalError(n.Info, errGenerated, msg)
|
||||
LocalError(n.Info, errGenerated, msg)
|
||||
return emptyNode
|
||||
result = nil
|
||||
else:
|
||||
result = m.call
|
||||
@@ -649,8 +656,9 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
nOrig.sons[0] = prc
|
||||
result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
|
||||
if result == nil:
|
||||
GlobalError(n.info, errExprXCannotBeCalled,
|
||||
renderTree(n, {renderNoComments}))
|
||||
LocalError(n.info, errExprXCannotBeCalled,
|
||||
renderTree(n, {renderNoComments}))
|
||||
return emptyNode
|
||||
fixAbstractType(c, result)
|
||||
analyseIfAddressTakenInCall(c, result)
|
||||
if result.sons[0].kind == nkSym and result.sons[0].sym.magic != mNone:
|
||||
@@ -664,7 +672,9 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
|
||||
if result == nil:
|
||||
result = overloadedCallOpr(c, n)
|
||||
if result == nil: GlobalError(n.Info, errGenerated, getNotFoundError(c, n))
|
||||
if result == nil:
|
||||
LocalError(n.Info, errGenerated, getNotFoundError(c, n))
|
||||
return emptyNode
|
||||
let callee = result.sons[0].sym
|
||||
case callee.kind
|
||||
of skMacro: result = semMacroExpr(c, nOrig, callee)
|
||||
@@ -696,8 +706,11 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode =
|
||||
# we MUST not check 'n' for semantics again here!
|
||||
result = newNodeI(nkCall, n.info)
|
||||
var e = StrTableGet(magicsys.systemModule.Tab, getIdent"echo")
|
||||
if e == nil: GlobalError(n.info, errSystemNeeds, "echo")
|
||||
addSon(result, newSymNode(e))
|
||||
if e != nil:
|
||||
addSon(result, newSymNode(e))
|
||||
else:
|
||||
LocalError(n.info, errSystemNeeds, "echo")
|
||||
addSon(result, emptyNode)
|
||||
var arg = buildStringify(c, n)
|
||||
# problem is: implicit '$' is not checked for semantics yet. So we give up
|
||||
# and check 'arg' for semantics again:
|
||||
@@ -890,7 +903,8 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
addSon(result, newIdentNode(i, n.info))
|
||||
addSon(result, copyTree(n[0]))
|
||||
else:
|
||||
GlobalError(n.Info, errUndeclaredFieldX, i.s)
|
||||
LocalError(n.Info, errUndeclaredFieldX, i.s)
|
||||
result = emptyNode
|
||||
|
||||
proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
|
||||
result = newNodeI(nkCall, n.info)
|
||||
@@ -946,9 +960,9 @@ 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: GlobalError(n.info, errInvalidIndexValueForTuple)
|
||||
else: LocalError(n.info, errInvalidIndexValueForTuple)
|
||||
else:
|
||||
GlobalError(n.info, errIndexTypesDoNotMatch)
|
||||
LocalError(n.info, errIndexTypesDoNotMatch)
|
||||
result = n
|
||||
else: nil
|
||||
|
||||
@@ -972,7 +986,7 @@ proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
||||
fixAbstractType(c, result)
|
||||
analyseIfAddressTakenInCall(c, result)
|
||||
else:
|
||||
globalError(n.Info, errUndeclaredFieldX, id.s)
|
||||
LocalError(n.Info, errUndeclaredFieldX, id.s)
|
||||
|
||||
proc takeImplicitAddr(c: PContext, n: PNode): PNode =
|
||||
case n.kind
|
||||
@@ -984,9 +998,9 @@ proc takeImplicitAddr(c: PContext, n: PNode): PNode =
|
||||
var valid = isAssignable(c, n)
|
||||
if valid != arLValue:
|
||||
if valid == arLocalLValue:
|
||||
GlobalError(n.info, errXStackEscape, renderTree(n, {renderNoComments}))
|
||||
LocalError(n.info, errXStackEscape, renderTree(n, {renderNoComments}))
|
||||
else:
|
||||
GlobalError(n.info, errExprHasNoAddress)
|
||||
LocalError(n.info, errExprHasNoAddress)
|
||||
result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ))
|
||||
result.add(n)
|
||||
|
||||
@@ -1062,13 +1076,13 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
|
||||
else:
|
||||
result = StrTableGet(m.tab, ident)
|
||||
else:
|
||||
GlobalError(n.sons[1].info, errIdentifierExpected, "")
|
||||
LocalError(n.sons[1].info, errIdentifierExpected, "")
|
||||
of nkAccQuoted:
|
||||
result = lookupForDefined(c, considerAcc(n), onlyCurrentScope)
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
LocalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
result = nil
|
||||
|
||||
proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
|
||||
@@ -1091,17 +1105,20 @@ proc setMs(n: PNode, s: PSym): PNode =
|
||||
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym =
|
||||
## The argument to the proc should be nkCall(...) or similar
|
||||
## Returns the macro/template symbol
|
||||
if not isCallExpr(n):
|
||||
GlobalError(n.info, errXisNoMacroOrTemplate, n.renderTree)
|
||||
if isCallExpr(n):
|
||||
var expandedSym = qualifiedLookup(c, n[0], {checkUndeclared})
|
||||
if expandedSym == nil:
|
||||
LocalError(n.info, errUndeclaredIdentifier, n[0].renderTree)
|
||||
return errorSym(n[0])
|
||||
|
||||
var expandedSym = qualifiedLookup(c, n[0], {checkUndeclared})
|
||||
if expandedSym == nil:
|
||||
GlobalError(n.info, errUndeclaredIdentifier, n[0].renderTree)
|
||||
if expandedSym.kind notin {skMacro, skTemplate}:
|
||||
LocalError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s)
|
||||
return errorSym(n[0])
|
||||
|
||||
if expandedSym.kind notin {skMacro, skTemplate}:
|
||||
GlobalError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s)
|
||||
|
||||
result = expandedSym
|
||||
result = expandedSym
|
||||
else:
|
||||
LocalError(n.info, errXisNoMacroOrTemplate, n.renderTree)
|
||||
result = errorSym(n)
|
||||
|
||||
proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,
|
||||
flags: TExprFlags): PNode =
|
||||
@@ -1240,7 +1257,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
|
||||
if typ == nil:
|
||||
typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal})
|
||||
if not isOrdinalType(typ):
|
||||
GlobalError(n.info, errOrdinalTypeExpected)
|
||||
LocalError(n.info, errOrdinalTypeExpected)
|
||||
return
|
||||
if lengthOrd(typ) > MaxSetElements:
|
||||
typ = makeRangeType(c, 0, MaxSetElements - 1, n.info)
|
||||
@@ -1288,11 +1305,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}):
|
||||
GlobalError(n.sons[i].info, errNamedExprExpected)
|
||||
LocalError(n.sons[i].info, errNamedExprExpected)
|
||||
return paNone
|
||||
else:
|
||||
if n.sons[i].kind == nkExprColonExpr:
|
||||
GlobalError(n.sons[i].info, errNamedExprNotAllowed)
|
||||
LocalError(n.sons[i].info, errNamedExprNotAllowed)
|
||||
return paNone
|
||||
|
||||
proc semTupleFieldsConstr(c: PContext, n: PNode): PNode =
|
||||
@@ -1369,10 +1386,13 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode =
|
||||
addSon(result, n.sons[0].sons[i])
|
||||
for i in countup(1, sonsLen(n) - 1): addSon(result, n.sons[i])
|
||||
result = semTemplateExpr(c, result, s, semCheck)
|
||||
else: GlobalError(n.info, errXisNoMacroOrTemplate, s.name.s)
|
||||
else:
|
||||
GlobalError(n.info, errInvalidExpressionX,
|
||||
renderTree(a, {renderNoComments}))
|
||||
else:
|
||||
LocalError(n.info, errXisNoMacroOrTemplate, s.name.s)
|
||||
result = emptyNode
|
||||
else:
|
||||
LocalError(n.info, errInvalidExpressionX,
|
||||
renderTree(a, {renderNoComments}))
|
||||
result = emptyNode
|
||||
|
||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
result = n
|
||||
@@ -1505,7 +1525,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
checkSonsLen(n, 1)
|
||||
n.sons[0] = semExprWithType(c, n.sons[0])
|
||||
if isAssignable(c, n.sons[0]) notin {arLValue, arLocalLValue}:
|
||||
GlobalError(n.info, errExprHasNoAddress)
|
||||
LocalError(n.info, errExprHasNoAddress)
|
||||
n.typ = makePtrType(c, n.sons[0].typ)
|
||||
of nkHiddenAddr, nkHiddenDeref:
|
||||
checkSonsLen(n, 1)
|
||||
@@ -1525,10 +1545,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
of nkTableConstr:
|
||||
result = semTableConstr(c, n)
|
||||
of nkSymChoice:
|
||||
GlobalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments}))
|
||||
LocalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments}))
|
||||
# error correction: Pick first element:
|
||||
result = n.sons[0]
|
||||
of nkStaticExpr:
|
||||
result = semStaticExpr(c, n)
|
||||
else:
|
||||
GlobalError(n.info, errInvalidExpressionX,
|
||||
renderTree(n, {renderNoComments}))
|
||||
LocalError(n.info, errInvalidExpressionX,
|
||||
renderTree(n, {renderNoComments}))
|
||||
incl(result.flags, nfSem)
|
||||
|
||||
@@ -18,7 +18,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: GlobalError(n.info, errIntLiteralExpected)
|
||||
else: LocalError(n.info, errIntLiteralExpected)
|
||||
|
||||
proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
||||
result = newNodeIT(nkPar, n.info, n.typ)
|
||||
|
||||
@@ -163,18 +163,20 @@ proc SemReturn(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkSonsLen(n, 1)
|
||||
if c.p.owner.kind notin {skConverter, skMethod, skProc, skMacro}:
|
||||
globalError(n.info, errXNotAllowedHere, "\'return\'")
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
LocalError(n.info, errXNotAllowedHere, "\'return\'")
|
||||
elif n.sons[0].kind != nkEmpty:
|
||||
# transform ``return expr`` to ``result = expr; return``
|
||||
if c.p.resultSym == nil: globalError(n.info, errNoReturnTypeDeclared)
|
||||
var a = newNodeI(nkAsgn, n.sons[0].info)
|
||||
addSon(a, newSymNode(c.p.resultSym))
|
||||
addSon(a, n.sons[0])
|
||||
n.sons[0] = semAsgn(c, a)
|
||||
# optimize away ``result = result``:
|
||||
if n[0][1].kind == nkSym and n[0][1].sym.kind == skResult:
|
||||
n.sons[0] = ast.emptyNode
|
||||
|
||||
if c.p.resultSym != nil:
|
||||
var a = newNodeI(nkAsgn, n.sons[0].info)
|
||||
addSon(a, newSymNode(c.p.resultSym))
|
||||
addSon(a, n.sons[0])
|
||||
n.sons[0] = semAsgn(c, a)
|
||||
# optimize away ``result = result``:
|
||||
if n[0][1].kind == nkSym and n[0][1].sym.kind == skResult:
|
||||
n.sons[0] = ast.emptyNode
|
||||
else:
|
||||
LocalError(n.info, errNoReturnTypeDeclared)
|
||||
|
||||
proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
||||
var t = skipTypes(restype, {tyGenericInst})
|
||||
case t.kind
|
||||
@@ -198,8 +200,8 @@ proc SemYield(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkSonsLen(n, 1)
|
||||
if c.p.owner == nil or c.p.owner.kind != skIterator:
|
||||
GlobalError(n.info, errYieldNotAllowedHere)
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
LocalError(n.info, errYieldNotAllowedHere)
|
||||
elif n.sons[0].kind != nkEmpty:
|
||||
n.sons[0] = SemExprWithType(c, n.sons[0]) # check for type compatibility:
|
||||
var restype = c.p.owner.typ.sons[0]
|
||||
if restype != nil:
|
||||
@@ -254,22 +256,24 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
else: typ = skipIntLit(def.typ)
|
||||
else:
|
||||
def = ast.emptyNode
|
||||
if symkind == skLet: GlobalError(a.info, errLetNeedsInit)
|
||||
if symkind == skLet: LocalError(a.info, errLetNeedsInit)
|
||||
|
||||
# this can only happen for errornous var statements:
|
||||
if typ == nil: continue
|
||||
if not typeAllowed(typ, symkind):
|
||||
GlobalError(a.info, errXisNoType, typeToString(typ))
|
||||
LocalError(a.info, errXisNoType, typeToString(typ))
|
||||
var tup = skipTypes(typ, {tyGenericInst})
|
||||
if a.kind == nkVarTuple:
|
||||
if tup.kind != tyTuple: GlobalError(a.info, errXExpected, "tuple")
|
||||
if length-2 != sonsLen(tup):
|
||||
GlobalError(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
|
||||
b.sons[length-1] = def
|
||||
addSon(result, b)
|
||||
if tup.kind != tyTuple:
|
||||
localError(a.info, errXExpected, "tuple")
|
||||
elif length-2 != sonsLen(tup):
|
||||
localError(a.info, errWrongNumberOfVariables)
|
||||
else:
|
||||
b = newNodeI(nkVarTuple, a.info)
|
||||
newSons(b, length)
|
||||
b.sons[length-2] = a.sons[length-2] # keep type desc for doc generator
|
||||
b.sons[length-1] = def
|
||||
addSon(result, b)
|
||||
elif tup.kind == tyTuple and def.kind == nkPar and
|
||||
a.kind == nkIdentDefs and a.len > 3:
|
||||
Message(a.info, warnEachIdentIsTuple)
|
||||
@@ -308,33 +312,19 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||
var typ: PType = nil
|
||||
if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
|
||||
|
||||
when true:
|
||||
var def = semConstExpr(c, a.sons[2])
|
||||
if def == nil: GlobalError(a.sons[2].info, errConstExprExpected)
|
||||
# check type compatibility between def.typ and typ:
|
||||
if typ != nil:
|
||||
def = fitRemoveHiddenConv(c, typ, def)
|
||||
else:
|
||||
typ = def.typ
|
||||
if not typeAllowed(typ, skConst):
|
||||
GlobalError(a.info, errXisNoType, typeToString(typ))
|
||||
var def = semConstExpr(c, a.sons[2])
|
||||
if def == nil:
|
||||
LocalError(a.sons[2].info, errConstExprExpected)
|
||||
continue
|
||||
# check type compatibility between def.typ and typ:
|
||||
if typ != nil:
|
||||
def = fitRemoveHiddenConv(c, typ, def)
|
||||
else:
|
||||
var e = semExprWithType(c, a.sons[2])
|
||||
if e == nil: GlobalError(a.sons[2].info, errConstExprExpected)
|
||||
var def = getConstExpr(c.module, e)
|
||||
if def == nil:
|
||||
v.flags.incl(sfFakeConst)
|
||||
def = evalConstExpr(c.module, e)
|
||||
if def == nil or def.kind == nkEmpty: def = e
|
||||
# check type compatibility between def.typ and typ:
|
||||
if typ != nil:
|
||||
def = fitRemoveHiddenConv(c, typ, def)
|
||||
else:
|
||||
typ = def.typ
|
||||
if not typeAllowed(typ, skConst):
|
||||
v.flags.incl(sfFakeConst)
|
||||
if not typeAllowed(typ, skVar):
|
||||
GlobalError(a.info, errXisNoType, typeToString(typ))
|
||||
typ = def.typ
|
||||
if typ == nil: continue
|
||||
if not typeAllowed(typ, skConst):
|
||||
LocalError(a.info, errXisNoType, typeToString(typ))
|
||||
continue
|
||||
v.typ = typ
|
||||
v.ast = def # no need to copy
|
||||
addInterfaceDecl(c, v)
|
||||
@@ -382,7 +372,10 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
# a 'while true: stmt; break' loop ...
|
||||
result = newNodeI(nkWhileStmt, n.info)
|
||||
var trueSymbol = StrTableGet(magicsys.systemModule.Tab, getIdent"true")
|
||||
if trueSymbol == nil: GlobalError(n.info, errSystemNeeds, "true")
|
||||
if trueSymbol == nil:
|
||||
LocalError(n.info, errSystemNeeds, "true")
|
||||
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner())
|
||||
trueSymbol.typ = getSysType(tyBool)
|
||||
|
||||
result.add(newSymNode(trueSymbol, n.info))
|
||||
var stmts = newNodeI(nkStmtList, n.info)
|
||||
@@ -391,7 +384,8 @@ 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):
|
||||
GlobalError(n.info, errWrongNumberOfVariables)
|
||||
LocalError(n.info, errWrongNumberOfVariables)
|
||||
return result
|
||||
|
||||
var tupleTypeA = skipTypes(call.sons[1].typ, abstractVar)
|
||||
if tupleTypeA.kind != tyTuple: InternalError(n.info, "no tuple type!")
|
||||
@@ -422,18 +416,20 @@ proc semForVars(c: PContext, n: PNode): PNode =
|
||||
# length == 3 means that there is one for loop variable
|
||||
# and thus no tuple unpacking:
|
||||
if iter.kind != tyTuple or length == 3:
|
||||
if length != 3: GlobalError(n.info, errWrongNumberOfVariables)
|
||||
var v = newSymS(skForVar, n.sons[0], c)
|
||||
if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
|
||||
# BUGFIX: don't use `iter` here as that would strip away
|
||||
# the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
|
||||
# for an example:
|
||||
v.typ = n.sons[length-2].typ
|
||||
n.sons[0] = newSymNode(v)
|
||||
addDecl(c, v)
|
||||
else:
|
||||
if length-2 != sonsLen(iter):
|
||||
GlobalError(n.info, errWrongNumberOfVariables)
|
||||
if length == 3:
|
||||
var v = newSymS(skForVar, n.sons[0], c)
|
||||
if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
|
||||
# BUGFIX: don't use `iter` here as that would strip away
|
||||
# the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
|
||||
# for an example:
|
||||
v.typ = n.sons[length-2].typ
|
||||
n.sons[0] = newSymNode(v)
|
||||
addDecl(c, v)
|
||||
else:
|
||||
LocalError(n.info, errWrongNumberOfVariables)
|
||||
elif length-2 != sonsLen(iter):
|
||||
LocalError(n.info, errWrongNumberOfVariables)
|
||||
else:
|
||||
for i in countup(0, length - 3):
|
||||
var v = newSymS(skForVar, n.sons[i], c)
|
||||
if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
|
||||
@@ -461,12 +457,11 @@ proc semFor(c: PContext, n: PNode): PNode =
|
||||
call.sons[0].sym.kind != skIterator:
|
||||
if length == 3:
|
||||
n.sons[length-2] = implicitIterator(c, "items", n.sons[length-2])
|
||||
result = semForVars(c, n)
|
||||
elif length == 4:
|
||||
n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2])
|
||||
result = semForVars(c, n)
|
||||
else:
|
||||
GlobalError(n.sons[length - 2].info, errIteratorExpected)
|
||||
LocalError(n.sons[length-2].info, errIteratorExpected)
|
||||
result = semForVars(c, n)
|
||||
elif call.sons[0].sym.magic != mNone:
|
||||
if call.sons[0].sym.magic == mOmpParFor:
|
||||
result = semForVars(c, n)
|
||||
@@ -504,7 +499,7 @@ proc semTry(c: PContext, n: PNode): PNode =
|
||||
var typ = semTypeNode(c, a.sons[j], nil)
|
||||
if typ.kind == tyRef: typ = typ.sons[0]
|
||||
if typ.kind != tyObject:
|
||||
GlobalError(a.sons[j].info, errExprCannotBeRaised)
|
||||
LocalError(a.sons[j].info, errExprCannotBeRaised)
|
||||
a.sons[j] = newNodeI(nkType, a.sons[j].info)
|
||||
a.sons[j].typ = typ
|
||||
if ContainsOrIncl(check, typ.id):
|
||||
@@ -549,7 +544,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
if (a.sons[0].kind != nkSym): IllFormedAst(a)
|
||||
var s = a.sons[0].sym
|
||||
if s.magic == mNone and a.sons[2].kind == nkEmpty:
|
||||
GlobalError(a.info, errImplOfXexpected, s.name.s)
|
||||
LocalError(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,
|
||||
@@ -901,9 +896,10 @@ proc evalInclude(c: PContext, n: PNode): PNode =
|
||||
var f = checkModuleName(n.sons[i])
|
||||
var fileIndex = f.fileInfoIdx
|
||||
if ContainsOrIncl(c.includedFiles, fileIndex):
|
||||
GlobalError(n.info, errRecursiveDependencyX, f.extractFilename)
|
||||
addSon(result, semStmt(c, gIncludeFile(f)))
|
||||
Excl(c.includedFiles, fileIndex)
|
||||
LocalError(n.info, errRecursiveDependencyX, f.extractFilename)
|
||||
else:
|
||||
addSon(result, semStmt(c, gIncludeFile(f)))
|
||||
Excl(c.includedFiles, fileIndex)
|
||||
|
||||
proc setLine(n: PNode, info: TLineInfo) =
|
||||
for i in 0 .. <safeLen(n): setLine(n.sons[i], info)
|
||||
|
||||
@@ -46,11 +46,14 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
var strVal: PNode = nil
|
||||
case skipTypes(v.typ, abstractInst).kind
|
||||
of tyTuple:
|
||||
if sonsLen(v) != 2: GlobalError(v.info, errWrongNumberOfVariables)
|
||||
strVal = v.sons[1] # second tuple part is the string value
|
||||
if skipTypes(strVal.typ, abstractInst).kind notin {tyString, tyCstring}:
|
||||
GlobalError(strVal.info, errStringLiteralExpected)
|
||||
x = getOrdValue(v.sons[0]) # first tuple part is the ordinal
|
||||
if sonsLen(v) == 2:
|
||||
strVal = v.sons[1] # second tuple part is the string value
|
||||
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)
|
||||
else:
|
||||
LocalError(v.info, errWrongNumberOfVariables)
|
||||
of tyString, tyCstring:
|
||||
strVal = v
|
||||
x = counter
|
||||
@@ -59,7 +62,8 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
if i != 1:
|
||||
if x != counter: incl(result.flags, tfEnumHasHoles)
|
||||
if x < counter:
|
||||
GlobalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
||||
LocalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
||||
x = counter
|
||||
e.ast = strVal # might be nil
|
||||
counter = x
|
||||
of nkSym:
|
||||
@@ -84,10 +88,13 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
|
||||
addSonSkipIntLit(result, base)
|
||||
if base.kind == tyGenericInst: base = lastSon(base)
|
||||
if base.kind != tyGenericParam:
|
||||
if not isOrdinalType(base): GlobalError(n.info, errOrdinalTypeExpected)
|
||||
if lengthOrd(base) > MaxSetElements: GlobalError(n.info, errSetTooBig)
|
||||
else:
|
||||
GlobalError(n.info, errXExpectsOneTypeParam, "set")
|
||||
if not isOrdinalType(base):
|
||||
LocalError(n.info, errOrdinalTypeExpected)
|
||||
elif lengthOrd(base) > MaxSetElements:
|
||||
LocalError(n.info, errSetTooBig)
|
||||
else:
|
||||
LocalError(n.info, errXExpectsOneTypeParam, "set")
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
|
||||
proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
|
||||
prev: PType): PType =
|
||||
@@ -96,7 +103,8 @@ proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
|
||||
var base = semTypeNode(c, n.sons[1], nil)
|
||||
addSonSkipIntLit(result, base)
|
||||
else:
|
||||
GlobalError(n.info, errXExpectsOneTypeParam, kindStr)
|
||||
LocalError(n.info, errXExpectsOneTypeParam, kindStr)
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
|
||||
proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, prev: PType): PType =
|
||||
if sonsLen(n) == 1:
|
||||
@@ -110,7 +118,9 @@ proc semVarType(c: PContext, n: PNode, prev: PType): PType =
|
||||
if sonsLen(n) == 1:
|
||||
result = newOrPrevType(tyVar, prev, c)
|
||||
var base = semTypeNode(c, n.sons[0], nil)
|
||||
if base.kind == tyVar: GlobalError(n.info, errVarVarTypeNotAllowed)
|
||||
if base.kind == tyVar:
|
||||
LocalError(n.info, errVarVarTypeNotAllowed)
|
||||
base = base.sons[0]
|
||||
addSonSkipIntLit(result, base)
|
||||
else:
|
||||
result = newConstraint(c, tyVar)
|
||||
@@ -128,28 +138,32 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = newOrPrevType(tyRange, prev, c)
|
||||
result.n = newNodeI(nkRange, n.info)
|
||||
if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
|
||||
GlobalError(n.Info, errRangeIsEmpty)
|
||||
LocalError(n.Info, errRangeIsEmpty)
|
||||
var a = semConstExpr(c, n[1])
|
||||
var b = semConstExpr(c, n[2])
|
||||
if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
|
||||
if a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,tyFloat..tyFloat128,
|
||||
tyUInt8..tyUInt32}:
|
||||
GlobalError(n.info, errOrdinalTypeExpected)
|
||||
if enumHasHoles(a.typ):
|
||||
GlobalError(n.info, errEnumXHasHoles, a.typ.sym.name.s)
|
||||
if not leValue(a, b): GlobalError(n.Info, errRangeIsEmpty)
|
||||
if not sameType(a.typ, b.typ):
|
||||
LocalError(n.info, errPureTypeMismatch)
|
||||
elif a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,
|
||||
tyFloat..tyFloat128,tyUInt8..tyUInt32}:
|
||||
LocalError(n.info, errOrdinalTypeExpected)
|
||||
elif enumHasHoles(a.typ):
|
||||
LocalError(n.info, errEnumXHasHoles, a.typ.sym.name.s)
|
||||
elif not leValue(a, b): LocalError(n.Info, errRangeIsEmpty)
|
||||
addSon(result.n, a)
|
||||
addSon(result.n, b)
|
||||
addSonSkipIntLit(result, b.typ)
|
||||
|
||||
proc semRange(c: PContext, n: PNode, prev: PType): PType =
|
||||
proc semRange(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = nil
|
||||
if sonsLen(n) == 2:
|
||||
if sonsLen(n) == 2:
|
||||
if isRange(n[1]): result = semRangeAux(c, n[1], prev)
|
||||
else: GlobalError(n.sons[0].info, errRangeExpected)
|
||||
else:
|
||||
GlobalError(n.info, errXExpectsOneTypeParam, "range")
|
||||
|
||||
else:
|
||||
LocalError(n.sons[0].info, errRangeExpected)
|
||||
result = errorType(c)
|
||||
else:
|
||||
LocalError(n.info, errXExpectsOneTypeParam, "range")
|
||||
result = errorType(c)
|
||||
|
||||
proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||
var indx, base: PType
|
||||
result = newOrPrevType(tyArray, prev, c)
|
||||
@@ -161,13 +175,14 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||
if indx.kind == tyGenericInst: indx = lastSon(indx)
|
||||
if indx.kind != tyGenericParam:
|
||||
if not isOrdinalType(indx):
|
||||
GlobalError(n.sons[1].info, errOrdinalTypeExpected)
|
||||
if enumHasHoles(indx):
|
||||
GlobalError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s)
|
||||
LocalError(n.sons[1].info, errOrdinalTypeExpected)
|
||||
elif enumHasHoles(indx):
|
||||
LocalError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s)
|
||||
base = semTypeNode(c, n.sons[2], nil)
|
||||
addSonSkipIntLit(result, base)
|
||||
else:
|
||||
GlobalError(n.info, errArrayExpectsTwoTypeParams)
|
||||
LocalError(n.info, errArrayExpectsTwoTypeParams)
|
||||
result = errorType(c)
|
||||
|
||||
proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = newOrPrevType(tyOrdinal, prev, c)
|
||||
@@ -175,10 +190,11 @@ 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):
|
||||
GlobalError(n.sons[1].info, errOrdinalTypeExpected)
|
||||
LocalError(n.sons[1].info, errOrdinalTypeExpected)
|
||||
addSonSkipIntLit(result, base)
|
||||
else:
|
||||
GlobalError(n.info, errXExpectsOneTypeParam, "ordinal")
|
||||
else:
|
||||
LocalError(n.info, errXExpectsOneTypeParam, "ordinal")
|
||||
result = errorType(c)
|
||||
|
||||
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||
if n.kind == nkSym:
|
||||
@@ -205,14 +221,17 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||
while amb != nil and amb.kind != skType:
|
||||
amb = nextOverloadIter(ov, c, n)
|
||||
if amb != nil: result = amb
|
||||
else: GlobalError(n.info, errTypeExpected)
|
||||
else:
|
||||
LocalError(n.info, errTypeExpected)
|
||||
return errorSym(n)
|
||||
if result.typ.kind != tyGenericParam:
|
||||
# XXX get rid of this hack!
|
||||
reset(n[])
|
||||
n.kind = nkSym
|
||||
n.sym = result
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected)
|
||||
LocalError(n.info, errIdentifierExpected)
|
||||
result = errorSym(n)
|
||||
|
||||
proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||
if n.sonsLen == 0: return newConstraint(c, tyTuple)
|
||||
@@ -228,18 +247,21 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||
var length = sonsLen(a)
|
||||
if a.sons[length - 2].kind != nkEmpty:
|
||||
typ = semTypeNode(c, a.sons[length - 2], nil)
|
||||
else: GlobalError(a.info, errTypeExpected)
|
||||
else:
|
||||
LocalError(a.info, errTypeExpected)
|
||||
typ = errorType(c)
|
||||
if a.sons[length - 1].kind != nkEmpty:
|
||||
GlobalError(a.sons[length - 1].info, errInitHereNotAllowed)
|
||||
LocalError(a.sons[length - 1].info, errInitHereNotAllowed)
|
||||
for j in countup(0, length - 3):
|
||||
var field = newSymS(skField, a.sons[j], c)
|
||||
field.typ = typ
|
||||
field.position = counter
|
||||
inc(counter)
|
||||
if ContainsOrIncl(check, field.name.id):
|
||||
GlobalError(a.sons[j].info, errAttemptToRedefine, field.name.s)
|
||||
addSon(result.n, newSymNode(field))
|
||||
addSonSkipIntLit(result, typ)
|
||||
LocalError(a.sons[j].info, errAttemptToRedefine, field.name.s)
|
||||
else:
|
||||
addSon(result.n, newSymNode(field))
|
||||
addSonSkipIntLit(result, typ)
|
||||
|
||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym =
|
||||
@@ -290,8 +312,8 @@ 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): GlobalError(b.info, errRangeIsEmpty)
|
||||
covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
|
||||
if emptyRange(ac, bc): LocalError(b.info, errRangeIsEmpty)
|
||||
else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
|
||||
|
||||
proc SemCaseBranchRange(c: PContext, t, b: PNode,
|
||||
covered: var biggestInt): PNode =
|
||||
@@ -349,11 +371,12 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int,
|
||||
incl(a.sons[0].sym.flags, sfDiscriminant)
|
||||
var covered: biggestInt = 0
|
||||
var typ = skipTypes(a.sons[0].Typ, abstractVar)
|
||||
if not isOrdinalType(typ): GlobalError(n.info, errSelectorMustBeOrdinal)
|
||||
if firstOrd(typ) < 0:
|
||||
GlobalError(n.info, errOrdXMustNotBeNegative, a.sons[0].sym.name.s)
|
||||
if lengthOrd(typ) > 0x00007FFF:
|
||||
GlobalError(n.info, errLenXinvalid, a.sons[0].sym.name.s)
|
||||
if not isOrdinalType(typ):
|
||||
LocalError(n.info, errSelectorMustBeOrdinal)
|
||||
elif firstOrd(typ) < 0:
|
||||
LocalError(n.info, errOrdXMustNotBeNegative, a.sons[0].sym.name.s)
|
||||
elif lengthOrd(typ) > 0x00007FFF:
|
||||
LocalError(n.info, errLenXinvalid, a.sons[0].sym.name.s)
|
||||
var chckCovered = true
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
var b = copyTree(n.sons[i])
|
||||
@@ -426,10 +449,13 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int,
|
||||
else: a = ast.emptyNode
|
||||
if n.sons[length-1].kind != nkEmpty:
|
||||
localError(n.sons[length-1].info, errInitHereNotAllowed)
|
||||
var typ: PType
|
||||
if n.sons[length-2].kind == nkEmpty:
|
||||
GlobalError(n.info, errTypeExpected)
|
||||
var typ = semTypeNode(c, n.sons[length-2], nil)
|
||||
for i in countup(0, sonsLen(n)-3):
|
||||
LocalError(n.info, errTypeExpected)
|
||||
typ = errorType(c)
|
||||
else:
|
||||
typ = semTypeNode(c, n.sons[length-2], nil)
|
||||
for i in countup(0, sonsLen(n)-3):
|
||||
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
|
||||
f.typ = typ
|
||||
f.position = pos
|
||||
@@ -568,7 +594,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||
let s = SymtabGet(c.tab, paramTypId)
|
||||
# tests/run/tinterf triggers this:
|
||||
if s != nil: result = s.typ
|
||||
else: GlobalError(info, errCannotInstantiateX, paramName)
|
||||
else:
|
||||
LocalError(info, errCannotInstantiateX, paramName)
|
||||
result = errorType(c)
|
||||
else:
|
||||
block addImplicitGeneric:
|
||||
# is this a bindOnce type class already present in the param list?
|
||||
@@ -700,13 +728,15 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
result = newOrPrevType(tyGenericInvokation, prev, c)
|
||||
var isConcrete = true
|
||||
if s.typ == nil:
|
||||
GlobalError(n.info, errCannotInstantiateX, s.name.s)
|
||||
LocalError(n.info, errCannotInstantiateX, s.name.s)
|
||||
return errorType(c)
|
||||
elif s.typ.kind != tyGenericBody:
|
||||
isConcrete = false
|
||||
elif s.typ.containerID == 0:
|
||||
InternalError(n.info, "semtypes.semGeneric")
|
||||
elif sonsLen(n) != sonsLen(s.typ):
|
||||
GlobalError(n.info, errWrongNumberOfArguments)
|
||||
LocalError(n.info, errWrongNumberOfArguments)
|
||||
return errorType(c)
|
||||
addSonSkipIntLit(result, s.typ)
|
||||
# iterate over arguments:
|
||||
for i in countup(1, sonsLen(n)-1):
|
||||
@@ -716,12 +746,15 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
if elem.isNil: rawAddSon(result, elem)
|
||||
else: addSonSkipIntLit(result, elem)
|
||||
if isConcrete:
|
||||
if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s)
|
||||
result = instGenericContainer(c, n, result)
|
||||
if s.ast == nil:
|
||||
LocalError(n.info, errCannotInstantiateX, s.name.s)
|
||||
result = errorType(c)
|
||||
else:
|
||||
result = instGenericContainer(c, n, result)
|
||||
|
||||
proc semTypeFromMacro(c: PContext, n: PNode): PType =
|
||||
# Expands a macro or template until a type is returned
|
||||
# results in GlobalError if the macro expands to something different
|
||||
# results in an error type if the macro expands to something different
|
||||
var sym = expectMacroOrTemplateCall(c, n)
|
||||
markUsed(n, sym)
|
||||
case sym.kind
|
||||
@@ -730,7 +763,8 @@ proc semTypeFromMacro(c: PContext, n: PNode): PType =
|
||||
of skTemplate:
|
||||
result = semTypeNode(c, semTemplateExpr(c, n, sym), nil)
|
||||
else:
|
||||
GlobalError(n.info, errXisNoMacroOrTemplate, n.renderTree)
|
||||
LocalError(n.info, errXisNoMacroOrTemplate, n.renderTree)
|
||||
result = errorType(c)
|
||||
|
||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = nil
|
||||
@@ -743,16 +777,21 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = semExprWithType(c, n.sons[0], {efInTypeof}).typ
|
||||
of nkPar:
|
||||
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
||||
else: GlobalError(n.info, errTypeExpected)
|
||||
else:
|
||||
LocalError(n.info, errTypeExpected)
|
||||
result = errorType(c)
|
||||
of nkCallKinds:
|
||||
let op = n.sons[0].ident
|
||||
if op.id in {ord(wAnd), ord(wOr)} or op.s == "|":
|
||||
var
|
||||
t1 = semTypeNode(c, n.sons[1], nil)
|
||||
t2 = semTypeNode(c, n.sons[2], nil)
|
||||
|
||||
if t1 == nil: GlobalError(n.sons[1].info, errTypeExpected)
|
||||
elif t2 == nil: GlobalError(n.sons[2].info, errTypeExpected)
|
||||
if t1 == nil:
|
||||
LocalError(n.sons[1].info, errTypeExpected)
|
||||
result = errorType(c)
|
||||
elif t2 == nil:
|
||||
LocalError(n.sons[2].info, errTypeExpected)
|
||||
result = errorType(c)
|
||||
else:
|
||||
result = newTypeS(tyTypeClass, c)
|
||||
result.addSonSkipIntLit(t1)
|
||||
@@ -783,14 +822,16 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
else: result = semGeneric(c, n, s, prev)
|
||||
of nkIdent, nkDotExpr, nkAccQuoted:
|
||||
var s = semTypeIdent(c, n)
|
||||
if s.typ == nil: GlobalError(n.info, errTypeExpected)
|
||||
if prev == nil:
|
||||
if s.typ == nil:
|
||||
LocalError(n.info, errTypeExpected)
|
||||
result = errorType(c)
|
||||
elif prev == nil:
|
||||
result = s.typ
|
||||
else:
|
||||
assignType(prev, s.typ)
|
||||
prev.id = s.typ.id
|
||||
result = prev
|
||||
of nkSym:
|
||||
of nkSym:
|
||||
if n.sym.kind == skType and n.sym.typ != nil:
|
||||
var t = n.sym.typ
|
||||
if prev == nil:
|
||||
@@ -799,8 +840,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
assignType(prev, t)
|
||||
result = prev
|
||||
markUsed(n, n.sym)
|
||||
else:
|
||||
GlobalError(n.info, errTypeExpected)
|
||||
else:
|
||||
LocalError(n.info, errTypeExpected)
|
||||
result = errorType(c)
|
||||
of nkObjectTy: result = semObjectNode(c, n, prev)
|
||||
of nkTupleTy: result = semTuple(c, n, prev)
|
||||
of nkRefTy: result = semAnyRef(c, n, tyRef, prev)
|
||||
@@ -826,7 +868,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
of nkType: result = n.typ
|
||||
of nkStmtListType: result = semStmtListType(c, n, prev)
|
||||
of nkBlockType: result = semBlockType(c, n, prev)
|
||||
else: GlobalError(n.info, errTypeExpected)
|
||||
else:
|
||||
LocalError(n.info, errTypeExpected)
|
||||
result = errorType(c)
|
||||
|
||||
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
||||
m.typ.kind = kind
|
||||
@@ -874,7 +918,7 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||
of mSeq: setMagicType(m, tySequence, 0)
|
||||
of mOrdinal: setMagicType(m, tyOrdinal, 0)
|
||||
of mPNimrodNode: nil
|
||||
else: GlobalError(m.info, errTypeExpected)
|
||||
else: LocalError(m.info, errTypeExpected)
|
||||
|
||||
proc semGenericConstraints(c: PContext, n: PNode, result: PType) =
|
||||
var x = semTypeNode(c, n, nil)
|
||||
|
||||
@@ -119,7 +119,8 @@ proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
|
||||
proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType =
|
||||
result = PType(idTableGet(cl.typeMap, t))
|
||||
if result == nil:
|
||||
GlobalError(t.sym.info, errCannotInstantiateX, typeToString(t))
|
||||
LocalError(t.sym.info, errCannotInstantiateX, typeToString(t))
|
||||
result = errorType(cl.c)
|
||||
elif result.kind == tyGenericParam:
|
||||
InternalError(cl.info, "substitution with generic parameter")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user