semstmts compiles again
This commit is contained in:
parent
ce859d8c16
commit
dd35111ff2
6 changed files with 192 additions and 198 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue