diff options
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r-- | compiler/semstmts.nim | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d394a2ae5..255507548 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -29,17 +29,18 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode = of nkIdent: s = lookUp(c, n.sons[0]) of nkSym: s = n.sons[0].sym else: illFormedAst(n) - if s.kind == skLabel and s.owner.id == c.p.owner.id: + if s.kind == skLabel and s.owner.id == c.p.owner.id: var x = newSymNode(s) x.info = n.info incl(s.flags, sfUsed) n.sons[0] = x suggestSym(x.info, s) + styleCheckUse(x.info, s) else: localError(n.info, errInvalidControlFlowX, s.name.s) else: localError(n.info, errGenerated, "'continue' cannot have a label") - elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): + elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): localError(n.info, errInvalidControlFlowX, renderTree(n, {renderNoComments})) @@ -198,11 +199,12 @@ proc semCase(c: PContext, n: PNode): PNode = var covered: BiggestInt = 0 var typ = commonTypeBegin var hasElse = false + var notOrdinal = false case skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc}).kind of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool: chckCovered = true of tyFloat..tyFloat128, tyString, tyError: - discard + notOrdinal = true else: localError(n.info, errSelectorMustBeOfCertainTypes) return @@ -232,6 +234,9 @@ proc semCase(c: PContext, n: PNode): PNode = hasElse = true else: illFormedAst(x) + if notOrdinal and not hasElse: + message(n.info, warnDeprecated, + "use 'else: discard'; non-ordinal case without 'else'") if chckCovered: if covered == toCover(n.sons[0].typ): hasElse = true @@ -263,7 +268,7 @@ proc semTry(c: PContext, n: PNode): PNode = checkMinSonsLen(a, 1) var length = sonsLen(a) if a.kind == nkExceptBranch: - # XXX what does this do? so that ``except [a, b, c]`` is supported? + # so that ``except [a, b, c]`` is supported: if length == 2 and a.sons[0].kind == nkBracket: a.sons[0..0] = a.sons[0].sons length = a.sonsLen @@ -323,6 +328,7 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym = else: result = semIdentWithPragma(c, kind, n, {}) suggestSym(n.info, result) + styleCheckDef(result) proc checkNilable(v: PSym) = if sfGlobal in v.flags and {tfNotNil, tfNeedsInit} * v.typ.flags != {}: @@ -350,9 +356,14 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var def: PNode if a.sons[length-1].kind != nkEmpty: def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) - # BUGFIX: ``fitNode`` is needed here! - # check type compability between def.typ and typ: - if typ != nil: def = fitNode(c, typ, def) + if typ != nil: + if typ.isMetaType: + def = inferWithMetatype(c, typ, def) + typ = def.typ + else: + # BUGFIX: ``fitNode`` is needed here! + # check type compability between def.typ and typ + def = fitNode(c, typ, def) else: typ = skipIntLit(def.typ) if typ.kind in {tySequence, tyArray, tySet} and @@ -441,7 +452,7 @@ proc semConst(c: PContext, n: PNode): PNode = if typ == nil: localError(a.sons[2].info, errConstExprExpected) continue - if not typeAllowed(typ, skConst): + if not typeAllowed(typ, skConst) and def.kind != nkNilLit: localError(a.info, errXisNoType, typeToString(typ)) continue v.typ = typ @@ -614,6 +625,7 @@ proc addForVarDecl(c: PContext, v: PSym) = proc symForVar(c: PContext, n: PNode): PSym = let m = if n.kind == nkPragmaExpr: n.sons[0] else: n result = newSymG(skForVar, m, c) + styleCheckDef(result) proc semForVars(c: PContext, n: PNode): PNode = result = n @@ -1021,7 +1033,11 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = sameType(s.typ.sons[1], s.typ.sons[0]): # Note: we store the deepCopy in the base of the pointer to mitigate # the problem that pointers are structural types: - let t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) + var t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) + while true: + if t.kind == tyGenericBody: t = t.lastSon + elif t.kind == tyGenericInvokation: t = t.sons[0] + else: break if t.kind in {tyObject, tyDistinct, tyEnum}: if t.deepCopy.isNil: t.deepCopy = s else: @@ -1036,6 +1052,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = of "=": discard else: localError(n.info, errGenerated, "'destroy' or 'deepCopy' expected for 'override'") + incl(s.flags, sfUsed) type TProcCompilationSteps = enum @@ -1292,9 +1309,14 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode = let pragmaList = n.sons[0] pragma(c, nil, pragmaList, exprPragmas) result = semExpr(c, n.sons[1]) + n.sons[1] = result for i in 0 .. <pragmaList.len: - if whichPragma(pragmaList.sons[i]) == wLine: - setLine(result, pragmaList.sons[i].info) + case whichPragma(pragmaList.sons[i]) + of wLine: setLine(result, pragmaList.sons[i].info) + of wLocks: + result = n + result.typ = n.sons[1].typ + else: discard proc semStaticStmt(c: PContext, n: PNode): PNode = let a = semStmt(c, n.sons[0]) @@ -1393,6 +1415,11 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = else: discard if result.len == 1: result = result.sons[0] + when defined(nimfix): + if result.kind == nkCommentStmt and not result.comment.isNil and + not (result.comment[0] == '#' and result.comment[1] == '#'): + # it is an old-style comment statement: we replace it with 'discard ""': + prettybase.replaceComment(result.info) when false: # a statement list (s; e) has the type 'e': if result.kind == nkStmtList and result.len > 0: |