mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-22 08:51:21 +00:00
semstmts compiles again
This commit is contained in:
@@ -185,7 +185,6 @@ errIntLiteralExpected: "integer literal expected",
|
||||
errIdentifierExpected: "identifier expected, but found '$1'",
|
||||
errNewlineExpected: "newline expected, but found '$1'",
|
||||
errInvalidModuleName: "invalid module name: '$1'",
|
||||
errRecursiveDependencyX: "recursive dependency: '$1'",
|
||||
errOnOrOffExpected: "'on' or 'off' expected",
|
||||
errNoneSpeedOrSizeExpected: "'none', 'speed' or 'size' expected",
|
||||
errInvalidPragma: "invalid pragma",
|
||||
@@ -193,11 +192,7 @@ errUnknownPragma: "unknown pragma: '$1'",
|
||||
errAtPopWithoutPush: "'pop' without a 'push' pragma",
|
||||
errEmptyAsm: "empty asm statement",
|
||||
errInvalidIndentation: "invalid indentation",
|
||||
errExceptionAlreadyHandled: "exception already handled",
|
||||
errYieldNotAllowedHere: "'yield' only allowed in an iterator",
|
||||
errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlined iterator",
|
||||
errInvalidNumberOfYieldExpr: "invalid number of 'yield' expressions",
|
||||
errCannotReturnExpr: "current routine cannot return an expression",
|
||||
|
||||
errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type",
|
||||
errAttemptToRedefine: ,
|
||||
errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma",
|
||||
@@ -261,13 +256,10 @@ errExprMustBeBool: "expression must be of type 'bool'",
|
||||
errConstExprExpected: "constant expression expected",
|
||||
errDuplicateCaseLabel: "duplicate case label",
|
||||
errRangeIsEmpty: "range is empty",
|
||||
errSelectorMustBeOfCertainTypes: "selector must be of an ordinal type, float or string",
|
||||
,
|
||||
errSelectorMustBeOrdinal: "selector must be of an ordinal type",
|
||||
errOrdXMustNotBeNegative: "ord($1) must not be negative",
|
||||
errLenXinvalid: "len($1) must be less than 32768",
|
||||
errWrongNumberOfVariables: "wrong number of variables",
|
||||
errExprCannotBeRaised: "only a 'ref object' can be raised",
|
||||
errBreakOnlyInLoop: "'break' only allowed in loop construct",
|
||||
errTypeXhasUnknownSize: "type '$1' has unknown size",
|
||||
errConstNeedsConstExpr: "a constant can only be initialized with a constant expression",
|
||||
errConstNeedsValue: "a constant needs a value",
|
||||
@@ -288,11 +280,9 @@ errWrongNumberOfArguments: "wrong number of arguments",
|
||||
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",
|
||||
,
|
||||
errImplOfXexpected: ,
|
||||
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
|
||||
errDiscardValueX: "value of type '$1' has to be discarded",
|
||||
errInvalidDiscard: "statement returns no value that can be discarded",
|
||||
|
||||
errIllegalConvFromXtoY: ,
|
||||
errCannotBindXTwice: "cannot bind parameter '$1' twice",
|
||||
errInvalidOrderInArrayConstructor: "invalid order in array constructor",
|
||||
@@ -315,7 +305,6 @@ errNoReturnTypeForX: "no return type allowed for $1",
|
||||
errConvNeedsOneArg: "a type conversion needs exactly one argument",
|
||||
errInvalidPragmaX: ,
|
||||
errXNotAllowedHere: "$1 not allowed here",
|
||||
errInvalidControlFlowX: "invalid control flow: $1",
|
||||
errXisNoType: "invalid type: '$1'",
|
||||
errCircumNeedsPointer: "'[]' needs a pointer or reference type",
|
||||
errInvalidExpression: "invalid expression",
|
||||
@@ -325,7 +314,7 @@ errNamedExprExpected: "named expression expected",
|
||||
errNamedExprNotAllowed: "named expression not allowed here",
|
||||
errNoCommand: "no command given",
|
||||
errInvalidCommandX: "invalid command: '$1'",
|
||||
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
|
||||
errXNeedsParamObjectType: ,
|
||||
errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N",
|
||||
errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N",
|
||||
errInstantiationFrom: "template/generic instantiation from here",
|
||||
@@ -344,7 +333,7 @@ errXisNoValidIndexFile: "'$1' is no valid index file",
|
||||
errCannotRenderX: "cannot render reStructuredText element '$1'",
|
||||
errVarVarTypeNotAllowed: ,
|
||||
errInstantiateXExplicitly: "instantiate '$1' explicitly",
|
||||
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator",
|
||||
errOnlyACallOpCanBeDelegator: ,
|
||||
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",
|
||||
@@ -368,18 +357,9 @@ errUnhandledExceptionX: "unhandled exception: $1",
|
||||
errCyclicTree: "macro returned a cyclic abstract syntax tree",
|
||||
errXisNoMacroOrTemplate: "'$1' is no macro or template",
|
||||
errXhasSideEffects: "'$1' can have side effects",
|
||||
errIteratorExpected: "iterator within for loop context expected",
|
||||
errLetNeedsInit: "'let' symbol requires an initialization",
|
||||
errThreadvarCannotInit: "a thread var cannot be initialized explicitly; this would only run for the main thread",
|
||||
errWrongSymbolX:,
|
||||
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",
|
||||
errCannotInferStaticParam: "cannot infer the value of the static param `$1`",
|
||||
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.",
|
||||
,
|
||||
]#
|
||||
|
||||
@@ -33,7 +33,7 @@ proc at(a, i: PNode, elemType: PType): PNode =
|
||||
|
||||
proc liftBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
for i in 0 ..< t.len:
|
||||
let lit = lowerings.newIntLit(i)
|
||||
let lit = lowerings.newIntLit(c.c.graph, x.info, i)
|
||||
liftBodyAux(c, t.sons[i], body, x.at(lit, t.sons[i]), y.at(lit, t.sons[i]))
|
||||
|
||||
proc dotField(x: PNode, f: PSym): PNode =
|
||||
@@ -66,15 +66,15 @@ proc liftBodyObj(c: var TLiftCtx; n, body, x, y: PNode) =
|
||||
liftBodyObj(c, n[i].lastSon, branch.sons[L-1], x, y)
|
||||
caseStmt.add(branch)
|
||||
body.add(caseStmt)
|
||||
localError(c.info, "cannot lift assignment operator to 'case' object")
|
||||
localError(c.c.config, c.info, "cannot lift assignment operator to 'case' object")
|
||||
of nkRecList:
|
||||
for t in items(n): liftBodyObj(c, t, body, x, y)
|
||||
else:
|
||||
illFormedAstLocal(n)
|
||||
illFormedAstLocal(n, c.c.config)
|
||||
|
||||
proc genAddr(c: PContext; x: PNode): PNode =
|
||||
if x.kind == nkHiddenDeref:
|
||||
checkSonsLen(x, 1)
|
||||
checkSonsLen(x, 1, c.config)
|
||||
result = x.sons[0]
|
||||
else:
|
||||
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(c, x.typ))
|
||||
@@ -82,7 +82,7 @@ proc genAddr(c: PContext; x: PNode): PNode =
|
||||
|
||||
proc newAsgnCall(c: PContext; op: PSym; x, y: PNode): PNode =
|
||||
if sfError in op.flags:
|
||||
localError(x.info, errWrongSymbolX, op.name.s)
|
||||
localError(c.config, x.info, "usage of '$1' is a user-defined error" % op.name.s)
|
||||
result = newNodeI(nkCall, x.info)
|
||||
result.add newSymNode(op)
|
||||
result.add genAddr(c, x)
|
||||
@@ -124,7 +124,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
|
||||
op = field
|
||||
if op == nil:
|
||||
op = liftBody(c.c, t, c.kind, c.info)
|
||||
markUsed(c.info, op, c.c.graph.usageSym)
|
||||
markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
|
||||
styleCheckUse(c.info, op)
|
||||
body.add newAsgnCall(c.c, op, x, y)
|
||||
result = true
|
||||
@@ -134,7 +134,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
||||
of attachedDestructor:
|
||||
let op = t.destructor
|
||||
if op != nil:
|
||||
markUsed(c.info, op, c.c.graph.usageSym)
|
||||
markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
|
||||
styleCheckUse(c.info, op)
|
||||
body.add destructorCall(c.c, op, x)
|
||||
result = true
|
||||
@@ -145,7 +145,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
||||
of attachedDeepCopy:
|
||||
let op = t.deepCopy
|
||||
if op != nil:
|
||||
markUsed(c.info, op, c.c.graph.usageSym)
|
||||
markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
|
||||
styleCheckUse(c.info, op)
|
||||
body.add newDeepCopyCall(op, x, y)
|
||||
result = true
|
||||
@@ -163,37 +163,37 @@ proc addVar(father, v, value: PNode) =
|
||||
|
||||
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
|
||||
var temp = newSym(skTemp, getIdent(lowerings.genPrefix), c.fn, c.info)
|
||||
temp.typ = getSysType(tyInt)
|
||||
temp.typ = getSysType(c.c.graph, body.info, tyInt)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
|
||||
var v = newNodeI(nkVarSection, c.info)
|
||||
result = newSymNode(temp)
|
||||
v.addVar(result, lowerings.newIntLit(first))
|
||||
v.addVar(result, lowerings.newIntLit(c.c.graph, body.info, first))
|
||||
body.add v
|
||||
|
||||
proc genBuiltin(magic: TMagic; name: string; i: PNode): PNode =
|
||||
proc genBuiltin(g: ModuleGraph; magic: TMagic; name: string; i: PNode): PNode =
|
||||
result = newNodeI(nkCall, i.info)
|
||||
result.add createMagic(name, magic).newSymNode
|
||||
result.add createMagic(g, name, magic).newSymNode
|
||||
result.add i
|
||||
|
||||
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
||||
result = newNodeI(nkWhileStmt, c.info, 2)
|
||||
let cmp = genBuiltin(mLeI, "<=", i)
|
||||
cmp.add genHigh(dest)
|
||||
cmp.typ = getSysType(tyBool)
|
||||
let cmp = genBuiltin(c.c.graph, mLeI, "<=", i)
|
||||
cmp.add genHigh(c.c.graph, dest)
|
||||
cmp.typ = getSysType(c.c.graph, c.info, tyBool)
|
||||
result.sons[0] = cmp
|
||||
result.sons[1] = newNodeI(nkStmtList, c.info)
|
||||
|
||||
proc addIncStmt(body, i: PNode) =
|
||||
let incCall = genBuiltin(mInc, "inc", i)
|
||||
incCall.add lowerings.newIntLit(1)
|
||||
proc addIncStmt(c: var TLiftCtx; body, i: PNode) =
|
||||
let incCall = genBuiltin(c.c.graph, mInc, "inc", i)
|
||||
incCall.add lowerings.newIntLit(c.c.graph, c.info, 1)
|
||||
body.add incCall
|
||||
|
||||
proc newSeqCall(c: PContext; x, y: PNode): PNode =
|
||||
# don't call genAddr(c, x) here:
|
||||
result = genBuiltin(mNewSeq, "newSeq", x)
|
||||
let lenCall = genBuiltin(mLengthSeq, "len", y)
|
||||
lenCall.typ = getSysType(tyInt)
|
||||
result = genBuiltin(c.graph, mNewSeq, "newSeq", x)
|
||||
let lenCall = genBuiltin(c.graph, mLengthSeq, "len", y)
|
||||
lenCall.typ = getSysType(c.graph, x.info, tyInt)
|
||||
result.add lenCall
|
||||
|
||||
proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
@@ -212,7 +212,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
let elemType = t.lastSon
|
||||
liftBodyAux(c, elemType, whileLoop.sons[1], x.at(i, elemType),
|
||||
y.at(i, elemType))
|
||||
addIncStmt(whileLoop.sons[1], i)
|
||||
addIncStmt(c, whileLoop.sons[1], i)
|
||||
body.add whileLoop
|
||||
else:
|
||||
defaultOp(c, t, body, x, y)
|
||||
@@ -231,20 +231,20 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
# have to go through some indirection; we delegate this to the codegen:
|
||||
let call = newNodeI(nkCall, c.info, 2)
|
||||
call.typ = t
|
||||
call.sons[0] = newSymNode(createMagic("deepCopy", mDeepCopy))
|
||||
call.sons[0] = newSymNode(createMagic(c.c.graph, "deepCopy", mDeepCopy))
|
||||
call.sons[1] = y
|
||||
body.add newAsgnStmt(x, call)
|
||||
of tyVarargs, tyOpenArray:
|
||||
localError(c.info, errGenerated, "cannot copy openArray")
|
||||
localError(c.c.config, c.info, "cannot copy openArray")
|
||||
of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
|
||||
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything,
|
||||
tyGenericParam, tyGenericBody, tyNil, tyExpr, tyStmt,
|
||||
tyTypeDesc, tyGenericInvocation, tyForward:
|
||||
internalError(c.info, "assignment requested for type: " & typeToString(t))
|
||||
internalError(c.c.config, c.info, "assignment requested for type: " & typeToString(t))
|
||||
of tyOrdinal, tyRange, tyInferred,
|
||||
tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink:
|
||||
liftBodyAux(c, lastSon(t), body, x, y)
|
||||
of tyUnused, tyOptAsRef: internalError("liftBodyAux")
|
||||
of tyUnused, tyOptAsRef: internalError(c.c.config, "liftBodyAux")
|
||||
|
||||
proc newProcType(info: TLineInfo; owner: PSym): PType =
|
||||
result = newType(tyProc, owner)
|
||||
|
||||
@@ -215,7 +215,7 @@ proc semConv(c: PContext, n: PNode): PNode =
|
||||
elif op.kind in {nkPar, nkTupleConstr} and targetType.kind == tyTuple:
|
||||
op = fitNode(c, targetType, op, result.info)
|
||||
of convNotNeedeed:
|
||||
message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
|
||||
message(c.config, n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
|
||||
of convNotLegal:
|
||||
result = fitNode(c, result.typ, result.sons[1], result.info)
|
||||
if result == nil:
|
||||
@@ -1494,7 +1494,7 @@ proc semProcBody(c: PContext, n: PNode): PNode =
|
||||
# nil
|
||||
# # comment
|
||||
# are not expressions:
|
||||
fixNilType(result)
|
||||
fixNilType(c, result)
|
||||
else:
|
||||
var a = newNodeI(nkAsgn, n.info, 2)
|
||||
a.sons[0] = newSymNode(c.p.resultSym)
|
||||
@@ -2264,7 +2264,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
result.kind = nkCall
|
||||
result = semExpr(c, result, flags)
|
||||
of nkBind:
|
||||
message(n.info, warnDeprecated, "bind")
|
||||
message(c.config, n.info, warnDeprecated, "bind")
|
||||
result = semExpr(c, n.sons[0], flags)
|
||||
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
|
||||
if c.matchedConcept != nil and n.len == 1:
|
||||
|
||||
@@ -16,16 +16,17 @@ type
|
||||
tupleIndex: int
|
||||
field: PSym
|
||||
replaceByFieldName: bool
|
||||
c: PContext
|
||||
|
||||
proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
|
||||
case n.kind
|
||||
of nkEmpty..pred(nkIdent), succ(nkSym)..nkNilLit: result = n
|
||||
of nkIdent, nkSym:
|
||||
result = n
|
||||
let ident = considerQuotedIdent(n)
|
||||
let ident = considerQuotedIdent(c.c.config, n)
|
||||
var L = sonsLen(forLoop)
|
||||
if c.replaceByFieldName:
|
||||
if ident.id == considerQuotedIdent(forLoop[0]).id:
|
||||
if ident.id == considerQuotedIdent(c.c.config, forLoop[0]).id:
|
||||
let fieldName = if c.tupleType.isNil: c.field.name.s
|
||||
elif c.tupleType.n.isNil: "Field" & $c.tupleIndex
|
||||
else: c.tupleType.n.sons[c.tupleIndex].sym.name.s
|
||||
@@ -33,7 +34,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
|
||||
return
|
||||
# other fields:
|
||||
for i in ord(c.replaceByFieldName)..L-3:
|
||||
if ident.id == considerQuotedIdent(forLoop[i]).id:
|
||||
if ident.id == considerQuotedIdent(c.c.config, forLoop[i]).id:
|
||||
var call = forLoop.sons[L-2]
|
||||
var tupl = call.sons[i+1-ord(c.replaceByFieldName)]
|
||||
if c.field.isNil:
|
||||
@@ -47,7 +48,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
|
||||
break
|
||||
else:
|
||||
if n.kind == nkContinueStmt:
|
||||
localError(c.config, n.info, errGenerated,
|
||||
localError(c.c.config, n.info,
|
||||
"'continue' not supported in a 'fields' loop")
|
||||
result = copyNode(n)
|
||||
newSons(result, sonsLen(n))
|
||||
@@ -63,6 +64,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
|
||||
case typ.kind
|
||||
of nkSym:
|
||||
var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid
|
||||
fc.c = c.c
|
||||
fc.field = typ.sym
|
||||
fc.replaceByFieldName = c.m == mFieldPairs
|
||||
openScope(c.c)
|
||||
@@ -76,7 +78,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
|
||||
let L = forLoop.len
|
||||
let call = forLoop.sons[L-2]
|
||||
if call.len > 2:
|
||||
localError(c.config, forLoop.info, errGenerated,
|
||||
localError(c.c.config, forLoop.info,
|
||||
"parallel 'fields' iterator does not work for 'case' objects")
|
||||
return
|
||||
# iterate over the selector:
|
||||
@@ -99,17 +101,17 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
|
||||
of nkRecList:
|
||||
for t in items(typ): semForObjectFields(c, t, forLoop, father)
|
||||
else:
|
||||
illFormedAstLocal(typ)
|
||||
illFormedAstLocal(typ, c.c.config)
|
||||
|
||||
proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
# so that 'break' etc. work as expected, we produce
|
||||
# a 'while true: stmt; break' loop ...
|
||||
result = newNodeI(nkWhileStmt, n.info, 2)
|
||||
var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true")
|
||||
var trueSymbol = strTableGet(c.graph.systemModule.tab, getIdent"true")
|
||||
if trueSymbol == nil:
|
||||
localError(c.config, n.info, errSystemNeeds, "true")
|
||||
localError(c.config, n.info, "system needs: 'true'")
|
||||
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(c), n.info)
|
||||
trueSymbol.typ = getSysType(tyBool)
|
||||
trueSymbol.typ = getSysType(c.graph, n.info, tyBool)
|
||||
|
||||
result.sons[0] = newSymNode(trueSymbol, n.info)
|
||||
var stmts = newNodeI(nkStmtList, n.info)
|
||||
@@ -129,7 +131,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
for i in 1..call.len-1:
|
||||
var tupleTypeB = skipTypes(call.sons[i].typ, skippedTypesForFields)
|
||||
if not sameType(tupleTypeA, tupleTypeB):
|
||||
typeMismatch(call.sons[i].info, tupleTypeA, tupleTypeB)
|
||||
typeMismatch(c.config, call.sons[i].info, tupleTypeA, tupleTypeB)
|
||||
|
||||
inc(c.p.nestedLoopCounter)
|
||||
if tupleTypeA.kind == tyTuple:
|
||||
@@ -139,6 +141,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
var fc: TFieldInstCtx
|
||||
fc.tupleType = tupleTypeA
|
||||
fc.tupleIndex = i
|
||||
fc.c = c
|
||||
fc.replaceByFieldName = m == mFieldPairs
|
||||
var body = instFieldLoopBody(fc, loopBody, n)
|
||||
inc c.inUnrolledContext
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
|
||||
# included from sem.nim
|
||||
|
||||
proc getIdentNode(n: PNode): PNode =
|
||||
proc getIdentNode(c: PContext; n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkPostfix: result = getIdentNode(n.sons[1])
|
||||
of nkPragmaExpr: result = getIdentNode(n.sons[0])
|
||||
of nkPostfix: result = getIdentNode(c, n.sons[1])
|
||||
of nkPragmaExpr: result = getIdentNode(c, n.sons[0])
|
||||
of nkIdent, nkAccQuoted, nkSym: result = n
|
||||
else:
|
||||
illFormedAst(n)
|
||||
illFormedAst(n, c.config)
|
||||
result = n
|
||||
|
||||
type
|
||||
@@ -103,8 +103,8 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||
proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
ctx: var GenericCtx): PNode =
|
||||
result = n
|
||||
let ident = considerQuotedIdent(n)
|
||||
var s = searchInScopes(c, ident).skipAlias(n)
|
||||
let ident = considerQuotedIdent(c.config, n)
|
||||
var s = searchInScopes(c, ident).skipAlias(n, c.config)
|
||||
if s == nil:
|
||||
s = strTableGet(c.pureEnumFields, ident)
|
||||
if s != nil and contains(c.ambiguousSymbols, s.id):
|
||||
@@ -140,8 +140,8 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
|
||||
result = n
|
||||
let n = n[1]
|
||||
let ident = considerQuotedIdent(n)
|
||||
var s = searchInScopes(c, ident).skipAlias(n)
|
||||
let ident = considerQuotedIdent(c.config, n)
|
||||
var s = searchInScopes(c, ident).skipAlias(n, c.config)
|
||||
if s != nil and s.kind in routineKinds:
|
||||
isMacro = s.kind in {skTemplate, skMacro}
|
||||
if withinBind in flags:
|
||||
@@ -158,7 +158,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
result = newDot(result, syms)
|
||||
|
||||
proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) =
|
||||
let s = newSymS(skUnknown, getIdentNode(n), c)
|
||||
let s = newSymS(skUnknown, getIdentNode(c, n), c)
|
||||
addPrelimDecl(c, s)
|
||||
styleCheckDef(n.info, s, kind)
|
||||
|
||||
@@ -201,13 +201,13 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
result = semMixinStmt(c, n, ctx.toMixin)
|
||||
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
|
||||
# check if it is an expression macro:
|
||||
checkMinSonsLen(n, 1)
|
||||
checkMinSonsLen(n, 1, c.config)
|
||||
let fn = n.sons[0]
|
||||
var s = qualifiedLookUp(c, fn, {})
|
||||
if s == nil and
|
||||
{withinMixin, withinConcept}*flags == {} and
|
||||
fn.kind in {nkIdent, nkAccQuoted} and
|
||||
considerQuotedIdent(fn).id notin ctx.toMixin:
|
||||
considerQuotedIdent(c.config, fn).id notin ctx.toMixin:
|
||||
errorUndeclaredIdentifier(c, n.info, fn.renderTree)
|
||||
|
||||
var first = int ord(withinConcept in flags)
|
||||
@@ -285,7 +285,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
withBracketExpr ctx, n.sons[0]:
|
||||
result = semGenericStmt(c, result, flags, ctx)
|
||||
of nkAsgn, nkFastAsgn:
|
||||
checkSonsLen(n, 2)
|
||||
checkSonsLen(n, 2, c.config)
|
||||
let a = n.sons[0]
|
||||
let b = n.sons[1]
|
||||
|
||||
@@ -323,7 +323,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
|
||||
for i in countup(1, sonsLen(n)-1):
|
||||
var a = n.sons[i]
|
||||
checkMinSonsLen(a, 1)
|
||||
checkMinSonsLen(a, 1, c.config)
|
||||
var L = sonsLen(a)
|
||||
for j in countup(0, L-2):
|
||||
a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx)
|
||||
@@ -340,23 +340,23 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
closeScope(c)
|
||||
closeScope(c)
|
||||
of nkBlockStmt, nkBlockExpr, nkBlockType:
|
||||
checkSonsLen(n, 2)
|
||||
checkSonsLen(n, 2, c.config)
|
||||
openScope(c)
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
addTempDecl(c, n.sons[0], skLabel)
|
||||
n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
|
||||
closeScope(c)
|
||||
of nkTryStmt:
|
||||
checkMinSonsLen(n, 2)
|
||||
checkMinSonsLen(n, 2, c.config)
|
||||
n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx)
|
||||
for i in countup(1, sonsLen(n)-1):
|
||||
var a = n.sons[i]
|
||||
checkMinSonsLen(a, 1)
|
||||
checkMinSonsLen(a, 1, c.config)
|
||||
var L = sonsLen(a)
|
||||
openScope(c)
|
||||
for j in countup(0, L-2):
|
||||
if a.sons[j].isInfixAs():
|
||||
addTempDecl(c, getIdentNode(a.sons[j][2]), skLet)
|
||||
addTempDecl(c, getIdentNode(c, a.sons[j][2]), skLet)
|
||||
a.sons[j].sons[1] = semGenericStmt(c, a.sons[j][1], flags+{withinTypeDesc}, ctx)
|
||||
else:
|
||||
a.sons[j] = semGenericStmt(c, a.sons[j], flags+{withinTypeDesc}, ctx)
|
||||
@@ -367,44 +367,44 @@ proc semGenericStmt(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 != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a)
|
||||
checkMinSonsLen(a, 3)
|
||||
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.config)
|
||||
checkMinSonsLen(a, 3, c.config)
|
||||
var L = sonsLen(a)
|
||||
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
|
||||
a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx)
|
||||
for j in countup(0, L-3):
|
||||
addTempDecl(c, getIdentNode(a.sons[j]), skVar)
|
||||
addTempDecl(c, getIdentNode(c, a.sons[j]), skVar)
|
||||
of nkGenericParams:
|
||||
for i in countup(0, 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 L = sonsLen(a)
|
||||
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
|
||||
# do not perform symbol lookup for default expressions
|
||||
for j in countup(0, L-3):
|
||||
addTempDecl(c, getIdentNode(a.sons[j]), skType)
|
||||
addTempDecl(c, getIdentNode(c, a.sons[j]), skType)
|
||||
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)
|
||||
addTempDecl(c, getIdentNode(a.sons[0]), skConst)
|
||||
if (a.kind != nkConstDef): illFormedAst(a, c.config)
|
||||
checkSonsLen(a, 3, c.config)
|
||||
addTempDecl(c, getIdentNode(c, a.sons[0]), skConst)
|
||||
a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx)
|
||||
a.sons[2] = semGenericStmt(c, a.sons[2], flags, ctx)
|
||||
of nkTypeSection:
|
||||
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)
|
||||
addTempDecl(c, getIdentNode(a.sons[0]), skType)
|
||||
if (a.kind != nkTypeDef): illFormedAst(a, c.config)
|
||||
checkSonsLen(a, 3, c.config)
|
||||
addTempDecl(c, getIdentNode(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.config)
|
||||
checkSonsLen(a, 3, c.config)
|
||||
if a.sons[1].kind != nkEmpty:
|
||||
openScope(c)
|
||||
a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx)
|
||||
@@ -421,28 +421,28 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
case n.sons[i].kind
|
||||
of nkEnumFieldDef: a = n.sons[i].sons[0]
|
||||
of nkIdent: a = n.sons[i]
|
||||
else: illFormedAst(n)
|
||||
addDecl(c, newSymS(skUnknown, getIdentNode(a), c))
|
||||
else: illFormedAst(n, c.config)
|
||||
addDecl(c, newSymS(skUnknown, getIdentNode(c, a), c))
|
||||
of nkObjectTy, nkTupleTy, nkTupleClassTy:
|
||||
discard
|
||||
of nkFormalParams:
|
||||
checkMinSonsLen(n, 1)
|
||||
checkMinSonsLen(n, 1, c.config)
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx)
|
||||
for i in countup(1, 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 L = sonsLen(a)
|
||||
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
|
||||
a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx)
|
||||
for j in countup(0, L-3):
|
||||
addTempDecl(c, getIdentNode(a.sons[j]), skParam)
|
||||
addTempDecl(c, getIdentNode(c, a.sons[j]), skParam)
|
||||
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
|
||||
nkFuncDef, nkIteratorDef, nkLambdaKinds:
|
||||
checkSonsLen(n, bodyPos + 1)
|
||||
checkSonsLen(n, bodyPos + 1, c.config)
|
||||
if n.sons[namePos].kind != nkEmpty:
|
||||
addTempDecl(c, getIdentNode(n.sons[0]), skProc)
|
||||
addTempDecl(c, getIdentNode(c, n.sons[0]), skProc)
|
||||
openScope(c)
|
||||
n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos],
|
||||
flags, ctx)
|
||||
@@ -463,7 +463,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
closeScope(c)
|
||||
of nkPragma, nkPragmaExpr: discard
|
||||
of nkExprColonExpr, nkExprEqExpr:
|
||||
checkMinSonsLen(n, 2)
|
||||
checkMinSonsLen(n, 2, c.config)
|
||||
result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
|
||||
else:
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
|
||||
@@ -10,7 +10,33 @@
|
||||
## this module does the semantic checking of statements
|
||||
# included from sem.nim
|
||||
|
||||
var enforceVoidContext = PType(kind: tyStmt)
|
||||
const
|
||||
errNoSymbolToBorrowFromFound = "no symbol to borrow from found"
|
||||
errDiscardValueX = "value of type '$1' has to be discarded"
|
||||
errInvalidDiscard = "statement returns no value that can be discarded"
|
||||
errInvalidControlFlowX = "invalid control flow: $1"
|
||||
errSelectorMustBeOfCertainTypes = "selector must be of an ordinal type, float or string"
|
||||
errExprCannotBeRaised = "only a 'ref object' can be raised"
|
||||
errBreakOnlyInLoop = "'break' only allowed in loop construct"
|
||||
errExceptionAlreadyHandled = "exception already handled"
|
||||
errYieldNotAllowedHere = "'yield' only allowed in an iterator"
|
||||
errYieldNotAllowedInTryStmt = "'yield' cannot be used within 'try' in a non-inlined iterator"
|
||||
errInvalidNumberOfYieldExpr = "invalid number of 'yield' expressions"
|
||||
errCannotReturnExpr = "current routine cannot return an expression"
|
||||
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."
|
||||
errCannotInferTypeOfTheLiteral = "cannot infer the type of the $1"
|
||||
errCannotInferReturnType = "cannot infer the return type of the proc"
|
||||
errCannotInferStaticParam = "cannot infer the value of the static param '$1'"
|
||||
errProcHasNoConcreteType = "'$1' doesn't have a concrete type, due to unspecified generic parameters."
|
||||
errLetNeedsInit = "'let' symbol requires an initialization"
|
||||
errThreadvarCannotInit = "a thread var cannot be initialized explicitly; this would only run for the main thread"
|
||||
errImplOfXexpected = "implementation of '$1' expected"
|
||||
errRecursiveDependencyX = "recursive dependency: '$1'"
|
||||
errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1"
|
||||
|
||||
var enforceVoidContext = PType(kind: tyStmt) # XXX global variable here
|
||||
|
||||
proc semDiscard(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
@@ -39,18 +65,18 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode =
|
||||
suggestSym(x.info, s, c.graph.usageSym)
|
||||
styleCheckUse(x.info, s)
|
||||
else:
|
||||
localError(c.config, n.info, errInvalidControlFlowX, s.name.s)
|
||||
localError(c.config, n.info, errInvalidControlFlowX % s.name.s)
|
||||
else:
|
||||
localError(c.config, n.info, errGenerated, "'continue' cannot have a label")
|
||||
elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0):
|
||||
localError(c.config, n.info, errInvalidControlFlowX,
|
||||
localError(c.config, n.info, errInvalidControlFlowX %
|
||||
renderTree(n, {renderNoComments}))
|
||||
|
||||
proc semAsm(con: PContext, n: PNode): PNode =
|
||||
proc semAsm(c: PContext, n: PNode): PNode =
|
||||
checkSonsLen(n, 2, c.config)
|
||||
var marker = pragmaAsm(con, n.sons[0])
|
||||
var marker = pragmaAsm(c, n.sons[0])
|
||||
if marker == '\0': marker = '`' # default marker
|
||||
result = semAsmOrEmit(con, n, marker)
|
||||
result = semAsmOrEmit(c, n, marker)
|
||||
|
||||
proc semWhile(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
@@ -95,13 +121,13 @@ proc implicitlyDiscardable(n: PNode): bool =
|
||||
result = isCallExpr(n) and n.sons[0].kind == nkSym and
|
||||
sfDiscardable in n.sons[0].sym.flags
|
||||
|
||||
proc fixNilType(n: PNode) =
|
||||
proc fixNilType(c: PContext; n: PNode) =
|
||||
if isAtom(n):
|
||||
if n.kind != nkNilLit and n.typ != nil:
|
||||
localError(c.config, 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)
|
||||
for it in n: fixNilType(c, it)
|
||||
n.typ = nil
|
||||
|
||||
proc discardCheck(c: PContext, result: PNode) =
|
||||
@@ -207,7 +233,7 @@ proc semCase(c: PContext, n: PNode): PNode =
|
||||
if covered == toCover(n.sons[0].typ):
|
||||
hasElse = true
|
||||
else:
|
||||
localError(c.config, n.info, errNotAllCasesCovered)
|
||||
localError(c.config, n.info, "not all cases covered")
|
||||
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)
|
||||
@@ -339,16 +365,16 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
||||
result = semIdentWithPragma(c, kind, n, {})
|
||||
if result.owner.kind == skModule:
|
||||
incl(result.flags, sfGlobal)
|
||||
suggestSym(c.config, n.info, result, c.graph.usageSym)
|
||||
suggestSym(n.info, result, c.graph.usageSym)
|
||||
styleCheckDef(result)
|
||||
|
||||
proc checkNilable(v: PSym) =
|
||||
proc checkNilable(c: PContext; v: PSym) =
|
||||
if {sfGlobal, sfImportC} * v.flags == {sfGlobal} and
|
||||
{tfNotNil, tfNeedsInit} * v.typ.flags != {}:
|
||||
if v.ast.isNil:
|
||||
message(v.info, warnProveInit, v.name.s)
|
||||
message(c.config, v.info, warnProveInit, v.name.s)
|
||||
elif tfNotNil in v.typ.flags and tfNotNil notin v.ast.typ.flags:
|
||||
message(v.info, warnProveInit, v.name.s)
|
||||
message(c.config, v.info, warnProveInit, v.name.s)
|
||||
|
||||
include semasgn
|
||||
|
||||
@@ -369,7 +395,7 @@ proc isDiscardUnderscore(v: PSym): bool =
|
||||
|
||||
proc semUsing(c: PContext; n: PNode): PNode =
|
||||
result = ast.emptyNode
|
||||
if not isTopLevel(c): localError(c.config, 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)
|
||||
@@ -432,7 +458,7 @@ proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
||||
else:
|
||||
localError(c.config, n.info, "nkDotNode requires 2 children")
|
||||
|
||||
proc setVarType(v: PSym, typ: PType) =
|
||||
proc setVarType(c: PContext; v: PSym, typ: PType) =
|
||||
if v.typ != nil and not sameTypeOrNil(v.typ, typ):
|
||||
localError(c.config, v.info, "inconsistent typing for reintroduced symbol '" &
|
||||
v.name.s & "': previous type was: " & typeToString(v.typ) &
|
||||
@@ -476,16 +502,16 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
|
||||
typ = typ.lastSon
|
||||
if hasEmpty(typ):
|
||||
localError(c.config, def.info, errCannotInferTypeOfTheLiteral,
|
||||
localError(c.config, def.info, errCannotInferTypeOfTheLiteral %
|
||||
($typ.kind).substr(2).toLowerAscii)
|
||||
elif typ.kind == tyProc and tfUnresolved in typ.flags:
|
||||
localError(c.config, def.info, errProcHasNoConcreteType, def.renderTree)
|
||||
localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree)
|
||||
else:
|
||||
if symkind == skLet: localError(c.config, a.info, errLetNeedsInit)
|
||||
|
||||
# this can only happen for errornous var statements:
|
||||
if typ == nil: continue
|
||||
typeAllowedCheck(a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {})
|
||||
typeAllowedCheck(c.config, a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {})
|
||||
liftTypeBoundOps(c, typ, a.info)
|
||||
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||
if a.kind == nkVarTuple:
|
||||
@@ -500,7 +526,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
addToVarSection(c, result, n, b)
|
||||
elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and
|
||||
a.kind == nkIdentDefs and a.len > 3:
|
||||
message(a.info, warnEachIdentIsTuple)
|
||||
message(c.config, a.info, warnEachIdentIsTuple)
|
||||
|
||||
for j in countup(0, length-3):
|
||||
if a[j].kind == nkDotExpr:
|
||||
@@ -518,17 +544,17 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
if shadowed != nil:
|
||||
shadowed.flags.incl(sfShadowed)
|
||||
if shadowed.kind == skResult and sfGenSym notin v.flags:
|
||||
message(a.info, warnResultShadowed)
|
||||
message(c.config, a.info, warnResultShadowed)
|
||||
# a shadowed variable is an error unless it appears on the right
|
||||
# side of the '=':
|
||||
if warnShadowIdent in gNotes and not identWithin(def, v.name):
|
||||
message(a.info, warnShadowIdent, v.name.s)
|
||||
if warnShadowIdent in c.config.notes and not identWithin(def, v.name):
|
||||
message(c.config, a.info, warnShadowIdent, v.name.s)
|
||||
if a.kind != nkVarTuple:
|
||||
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(c.config, def.info, errThreadvarCannotInit)
|
||||
setVarType(v, typ)
|
||||
setVarType(c, v, typ)
|
||||
b = newNodeI(nkIdentDefs, a.info)
|
||||
if importantComments(c.config):
|
||||
# keep documentation information:
|
||||
@@ -540,13 +566,13 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
else:
|
||||
if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j]
|
||||
# bug #7663, for 'nim check' this can be a non-tuple:
|
||||
if tup.kind == tyTuple: setVarType(v, tup.sons[j])
|
||||
if tup.kind == tyTuple: setVarType(c, v, tup.sons[j])
|
||||
else: v.typ = tup
|
||||
b.sons[j] = newSymNode(v)
|
||||
checkNilable(v)
|
||||
checkNilable(c, v)
|
||||
if sfCompileTime in v.flags: hasCompileTime = true
|
||||
if hasCompileTime:
|
||||
vm.setupCompileTimeVar(c.module, c.cache, c.graph.config, result)
|
||||
vm.setupCompileTimeVar(c.module, c.cache, c.graph, result)
|
||||
|
||||
proc semConst(c: PContext, n: PNode): PNode =
|
||||
result = copyNode(n)
|
||||
@@ -575,11 +601,11 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||
if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit:
|
||||
localError(c.config, a.info, "invalid type for const: " & typeToString(typ))
|
||||
continue
|
||||
setVarType(v, typ)
|
||||
setVarType(c, v, typ)
|
||||
v.ast = def # no need to copy
|
||||
if sfGenSym notin v.flags: addInterfaceDecl(c, v)
|
||||
var b = newNodeI(nkConstDef, a.info)
|
||||
if importantComments(): b.comment = a.comment
|
||||
if importantComments(c.config): b.comment = a.comment
|
||||
addSon(b, newSymNode(v))
|
||||
addSon(b, a.sons[1])
|
||||
addSon(b, copyTree(def))
|
||||
@@ -588,12 +614,12 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||
include semfields
|
||||
|
||||
proc addForVarDecl(c: PContext, v: PSym) =
|
||||
if warnShadowIdent in gNotes:
|
||||
if warnShadowIdent in c.config.notes:
|
||||
let shadowed = findShadowedVar(c, v)
|
||||
if shadowed != nil:
|
||||
# XXX should we do this here?
|
||||
#shadowed.flags.incl(sfShadowed)
|
||||
message(v.info, warnShadowIdent, v.name.s)
|
||||
message(c.config, v.info, warnShadowIdent, v.name.s)
|
||||
addDecl(c, v)
|
||||
|
||||
proc symForVar(c: PContext, n: PNode): PSym =
|
||||
@@ -658,7 +684,7 @@ proc handleForLoopMacro(c: PContext; n: PNode): PNode =
|
||||
# n := for a, b, c in m(x, y, z): Y
|
||||
# to
|
||||
# m(n)
|
||||
let forLoopStmt = magicsys.getCompilerProc("ForLoopStmt")
|
||||
let forLoopStmt = magicsys.getCompilerProc(c.graph, "ForLoopStmt")
|
||||
if forLoopStmt == nil: return
|
||||
|
||||
let headSymbol = iterExpr[0]
|
||||
@@ -715,7 +741,7 @@ proc semFor(c: PContext, n: PNode): PNode =
|
||||
elif length == 4:
|
||||
n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2])
|
||||
else:
|
||||
localError(c.config, n.sons[length-2].info, errIteratorExpected)
|
||||
localError(c.config, n.sons[length-2].info, "iterator within for loop context expected")
|
||||
result = semForVars(c, n)
|
||||
else:
|
||||
result = semForVars(c, n)
|
||||
@@ -744,7 +770,7 @@ proc addGenericParamListToScope(c: PContext, n: PNode) =
|
||||
if a.kind == nkSym: addDecl(c, a.sym)
|
||||
else: illFormedAst(a, c.config)
|
||||
|
||||
proc typeSectionTypeName(n: PNode): PNode =
|
||||
proc typeSectionTypeName(c: PContext; n: PNode): PNode =
|
||||
if n.kind == nkPragmaExpr:
|
||||
if n.len == 0: illFormedAst(n, c.config)
|
||||
result = n.sons[0]
|
||||
@@ -818,14 +844,12 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||
else:
|
||||
a.sons[0] = newSymNode(s)
|
||||
|
||||
proc checkCovariantParamsUsages(genericType: PType) =
|
||||
proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
|
||||
var body = genericType[^1]
|
||||
|
||||
proc traverseSubTypes(t: PType): bool =
|
||||
proc traverseSubTypes(c: PContext; t: PType): bool =
|
||||
template error(msg) = localError(c.config, genericType.sym.info, msg)
|
||||
|
||||
result = false
|
||||
|
||||
template subresult(r) =
|
||||
let sub = r
|
||||
result = result or sub
|
||||
@@ -834,24 +858,19 @@ proc checkCovariantParamsUsages(genericType: PType) =
|
||||
of tyGenericParam:
|
||||
t.flags.incl tfWeakCovariant
|
||||
return true
|
||||
|
||||
of tyObject:
|
||||
for field in t.n:
|
||||
subresult traverseSubTypes(field.typ)
|
||||
|
||||
subresult traverseSubTypes(c, field.typ)
|
||||
of tyArray:
|
||||
return traverseSubTypes(t[1])
|
||||
|
||||
return traverseSubTypes(c, t[1])
|
||||
of tyProc:
|
||||
for subType in t.sons:
|
||||
if subType != nil:
|
||||
subresult traverseSubTypes(subType)
|
||||
subresult traverseSubTypes(c, subType)
|
||||
if result:
|
||||
error("non-invariant type param used in a proc type: " & $t)
|
||||
|
||||
of tySequence:
|
||||
return traverseSubTypes(t[0])
|
||||
|
||||
return traverseSubTypes(c, t[0])
|
||||
of tyGenericInvocation:
|
||||
let targetBody = t[0]
|
||||
for i in 1 ..< t.len:
|
||||
@@ -872,32 +891,24 @@ proc checkCovariantParamsUsages(genericType: PType) =
|
||||
"' used in a non-contravariant position")
|
||||
result = true
|
||||
else:
|
||||
subresult traverseSubTypes(param)
|
||||
|
||||
subresult traverseSubTypes(c, param)
|
||||
of tyAnd, tyOr, tyNot, tyStatic, tyBuiltInTypeClass, tyCompositeTypeClass:
|
||||
error("non-invariant type parameters cannot be used with types such '" & $t & "'")
|
||||
|
||||
of tyUserTypeClass, tyUserTypeClassInst:
|
||||
error("non-invariant type parameters are not supported in concepts")
|
||||
|
||||
of tyTuple:
|
||||
for fieldType in t.sons:
|
||||
subresult traverseSubTypes(fieldType)
|
||||
|
||||
subresult traverseSubTypes(c, fieldType)
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
if t.base.kind == tyGenericParam: return true
|
||||
return traverseSubTypes(t.base)
|
||||
|
||||
return traverseSubTypes(c, t.base)
|
||||
of tyDistinct, tyAlias, tySink:
|
||||
return traverseSubTypes(t.lastSon)
|
||||
|
||||
return traverseSubTypes(c, t.lastSon)
|
||||
of tyGenericInst:
|
||||
internalAssert false
|
||||
|
||||
internalAssert c.config, false
|
||||
else:
|
||||
discard
|
||||
|
||||
discard traverseSubTypes(body)
|
||||
discard traverseSubTypes(c, body)
|
||||
|
||||
proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
@@ -905,10 +916,10 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
if a.kind == nkCommentStmt: continue
|
||||
if a.kind != nkTypeDef: illFormedAst(a, c.config)
|
||||
checkSonsLen(a, 3, c.config)
|
||||
let name = typeSectionTypeName(a.sons[0])
|
||||
let name = typeSectionTypeName(c, a.sons[0])
|
||||
var s = name.sym
|
||||
if s.magic == mNone and a.sons[2].kind == nkEmpty:
|
||||
localError(c.config, 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,
|
||||
@@ -939,7 +950,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
body.size = -1 # could not be computed properly
|
||||
s.typ.sons[sonsLen(s.typ) - 1] = body
|
||||
if tfCovariant in s.typ.flags:
|
||||
checkCovariantParamsUsages(s.typ)
|
||||
checkCovariantParamsUsages(c, s.typ)
|
||||
# XXX: This is a temporary limitation:
|
||||
# The codegen currently produces various failures with
|
||||
# generic imported types that have fields, but we need
|
||||
@@ -974,8 +985,8 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
# give anonymous object a dummy symbol:
|
||||
var st = s.typ
|
||||
if st.kind == tyGenericBody: st = st.lastSon
|
||||
internalAssert st.kind in {tyPtr, tyRef}
|
||||
internalAssert st.lastSon.sym == nil
|
||||
internalAssert c.config, st.kind in {tyPtr, tyRef}
|
||||
internalAssert c.config, st.lastSon.sym == nil
|
||||
incl st.flags, tfRefsAnonObj
|
||||
let obj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
||||
getCurrOwner(c), s.info)
|
||||
@@ -983,17 +994,17 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
st.lastSon.sym = obj
|
||||
|
||||
|
||||
proc checkForMetaFields(n: PNode) =
|
||||
proc checkForMetaFields(c: PContext; n: PNode) =
|
||||
template checkMeta(t) =
|
||||
if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
|
||||
localError(c.config, n.info, errTIsNotAConcreteType, t.typeToString)
|
||||
localError(c.config, n.info, errTIsNotAConcreteType % t.typeToString)
|
||||
|
||||
if n.isNil: return
|
||||
case n.kind
|
||||
of nkRecList, nkRecCase:
|
||||
for s in n: checkForMetaFields(s)
|
||||
for s in n: checkForMetaFields(c, s)
|
||||
of nkOfBranch, nkElse:
|
||||
checkForMetaFields(n.lastSon)
|
||||
checkForMetaFields(c, n.lastSon)
|
||||
of nkSym:
|
||||
let t = n.sym.typ
|
||||
case t.kind
|
||||
@@ -1005,13 +1016,13 @@ proc checkForMetaFields(n: PNode) =
|
||||
else:
|
||||
checkMeta(t)
|
||||
else:
|
||||
internalAssert false
|
||||
internalAssert c.config, false
|
||||
|
||||
proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var a = n.sons[i]
|
||||
if a.kind == nkCommentStmt: continue
|
||||
let name = typeSectionTypeName(a.sons[0])
|
||||
let name = typeSectionTypeName(c, a.sons[0])
|
||||
var s = name.sym
|
||||
# compute the type's size and check for illegal recursions:
|
||||
if a.sons[1].kind == nkEmpty:
|
||||
@@ -1031,9 +1042,9 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
assert s.typ != nil
|
||||
assignType(s.typ, t)
|
||||
s.typ.id = t.id # same id
|
||||
checkConstructedType(s.info, s.typ)
|
||||
checkConstructedType(c.config, s.info, s.typ)
|
||||
if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
|
||||
checkForMetaFields(s.typ.n)
|
||||
checkForMetaFields(c, s.typ.n)
|
||||
instAllTypeBoundOp(c, n.info)
|
||||
|
||||
|
||||
@@ -1042,10 +1053,10 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkIncludeStmt:
|
||||
for i in 0..<n.len:
|
||||
var f = checkModuleName(n.sons[i])
|
||||
var f = checkModuleName(c.config, n.sons[i])
|
||||
if f != InvalidFileIDX:
|
||||
if containsOrIncl(c.includedFiles, f.int):
|
||||
localError(c.config, 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
|
||||
@@ -1154,7 +1165,7 @@ proc semProcAnnotation(c: PContext, prc: PNode;
|
||||
prc.sons[namePos] = newIdentNode(c.cache.idDelegator, prc.info)
|
||||
prc.sons[pragmasPos] = copyExcept(n, i)
|
||||
else:
|
||||
localError(c.config, prc.info, errOnlyACallOpCanBeDelegator)
|
||||
localError(c.config, prc.info, "only a call operator can be a delegator")
|
||||
continue
|
||||
elif sfCustomPragma in m.flags:
|
||||
continue # semantic check for custom pragma happens later in semProcAux
|
||||
@@ -1236,13 +1247,13 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
addResult(c, s.typ.sons[0], n.info, skProc)
|
||||
addResultNode(c, n)
|
||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
||||
n.sons[bodyPos] = transformBody(c.graph, c.module, semBody, s)
|
||||
popProcCon(c)
|
||||
elif efOperand notin flags:
|
||||
localError(c.config, n.info, errGenericLambdaNotAllowed)
|
||||
sideEffectsCheck(c, s)
|
||||
else:
|
||||
localError(c.config, 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
|
||||
@@ -1277,7 +1288,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||
addResult(c, n.typ.sons[0], n.info, skProc)
|
||||
addResultNode(c, n)
|
||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
||||
n.sons[bodyPos] = transformBody(c.graph, c.module, semBody, s)
|
||||
popProcCon(c)
|
||||
popOwner(c)
|
||||
closeScope(c)
|
||||
@@ -1426,7 +1437,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
|
||||
foundObj = true
|
||||
x.methods.safeAdd((col,s))
|
||||
if not foundObj:
|
||||
message(n.info, warnDeprecated, "generic method not attachable to object type")
|
||||
message(c.config, n.info, warnDeprecated, "generic method not attachable to object type")
|
||||
else:
|
||||
# why check for the body? bug #2400 has none. Checking for sfForward makes
|
||||
# no sense either.
|
||||
@@ -1434,7 +1445,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
|
||||
if hasObjParam(s):
|
||||
methodDef(c.graph, s, fromCache=false)
|
||||
else:
|
||||
localError(c.config, n.info, errXNeedsParamObjectType, "method")
|
||||
localError(c.config, n.info, "'method' needs a parameter that has an object type")
|
||||
|
||||
proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
validPragmas: TSpecialWords,
|
||||
@@ -1547,7 +1558,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos]
|
||||
n.sons[paramsPos] = proto.ast.sons[paramsPos]
|
||||
n.sons[pragmasPos] = proto.ast.sons[pragmasPos]
|
||||
if n.sons[namePos].kind != nkSym: internalError(n.info, "semProcAux")
|
||||
if n.sons[namePos].kind != nkSym: internalError(c.config, n.info, "semProcAux")
|
||||
n.sons[namePos].sym = proto
|
||||
if importantComments(c.config) and not isNil(proto.ast.comment):
|
||||
n.comment = proto.ast.comment
|
||||
@@ -1606,7 +1617,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
popProcCon(c)
|
||||
else:
|
||||
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||
if proto != nil: localError(c.config, n.info, errImplOfXexpected, proto.name.s)
|
||||
if proto != nil: localError(c.config, n.info, errImplOfXexpected % proto.name.s)
|
||||
if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone:
|
||||
incl(s.flags, sfForward)
|
||||
elif sfBorrow in s.flags: semBorrow(c, n, s)
|
||||
@@ -1655,7 +1666,7 @@ proc semIterator(c: PContext, n: PNode): PNode =
|
||||
else:
|
||||
s.typ.callConv = ccInline
|
||||
if n.sons[bodyPos].kind == nkEmpty and s.magic == mNone:
|
||||
localError(c.config, n.info, errImplOfXexpected, s.name.s)
|
||||
localError(c.config, n.info, errImplOfXexpected % s.name.s)
|
||||
|
||||
proc semProc(c: PContext, n: PNode): PNode =
|
||||
result = semProcAux(c, n, skProc, procPragmas)
|
||||
@@ -1664,7 +1675,7 @@ proc semFunc(c: PContext, n: PNode): PNode =
|
||||
result = semProcAux(c, n, skFunc, procPragmas)
|
||||
|
||||
proc semMethod(c: PContext, n: PNode): PNode =
|
||||
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "method")
|
||||
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "method")
|
||||
result = semProcAux(c, n, skMethod, methodPragmas)
|
||||
# macros can transform converters to nothing:
|
||||
if namePos >= result.safeLen: return result
|
||||
@@ -1685,7 +1696,7 @@ 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(c.config, n.info, errXOnlyAtModuleScope, "converter")
|
||||
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:
|
||||
@@ -1696,8 +1707,8 @@ 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(c.config, n.info, errXNeedsReturnType, "converter")
|
||||
if sonsLen(t) != 2: localError(c.config, 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, "a converter takes exactly one argument")
|
||||
addConverter(c, s)
|
||||
|
||||
proc semMacroDef(c: PContext, n: PNode): PNode =
|
||||
@@ -1718,7 +1729,7 @@ proc semMacroDef(c: PContext, n: PNode): PNode =
|
||||
if allUntyped: incl(s.flags, sfAllUntyped)
|
||||
if t.sons[0] == nil: localError(c.config, n.info, "macro needs a return type")
|
||||
if n.sons[bodyPos].kind == nkEmpty:
|
||||
localError(c.config, 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)
|
||||
@@ -1756,7 +1767,7 @@ proc semStaticStmt(c: PContext, n: PNode): PNode =
|
||||
#writeStackTrace()
|
||||
let a = semStmt(c, n.sons[0])
|
||||
n.sons[0] = a
|
||||
evalStaticStmt(c.module, c.cache, c.graph.config, a, c.p.owner)
|
||||
evalStaticStmt(c.module, c.cache, c.graph, a, c.p.owner)
|
||||
result = newNodeI(nkDiscardStmt, n.info, 1)
|
||||
result.sons[0] = emptyNode
|
||||
|
||||
@@ -1839,7 +1850,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(c.config, n.sons[j].info, errStmtInvalidAfterReturn)
|
||||
else: localError(c.config, n.sons[j].info, "unreachable statement after 'return'")
|
||||
else: discard
|
||||
|
||||
if result.len == 1 and
|
||||
|
||||
Reference in New Issue
Block a user