diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 7dc1d183eb55e..27fdb9da1d273 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -121,3 +121,4 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimHasLentIterators") defineSymbol("nimHasDeclaredMagic") defineSymbol("nimHasStacktracesModule") + defineSymbol("nimHasCastPragmaBlocks") diff --git a/compiler/parser.nim b/compiler/parser.nim index 1ec70805733bb..e3cf54b38dce7 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -485,17 +485,24 @@ proc setOrTableConstr(p: var Parser): PNode = eat(p, tkCurlyRi) # skip '}' proc parseCast(p: var Parser): PNode = - #| castExpr = 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')' + #| castExpr = 'cast' ('[' optInd typeDesc optPar ']' '(' optInd expr optPar ')') / + # ('(' optInd exprColonEqExpr optPar ')') result = newNodeP(nkCast, p) getTok(p) - eat(p, tkBracketLe) - optInd(p, result) - result.add(parseTypeDesc(p)) - optPar(p) - eat(p, tkBracketRi) - eat(p, tkParLe) - optInd(p, result) - result.add(parseExpr(p)) + if p.tok.tokType == tkBracketLe: + getTok(p) + optInd(p, result) + result.add(parseTypeDesc(p)) + optPar(p) + eat(p, tkBracketRi) + eat(p, tkParLe) + optInd(p, result) + result.add(parseExpr(p)) + else: + result.add p.emptyNode + eat(p, tkParLe) + optInd(p, result) + result.add(exprColonEqExpr(p)) optPar(p) eat(p, tkParRi) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 67e574d52257e..fe8cd3cfe64d4 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -771,6 +771,15 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, if key.kind == nkBracketExpr: processNote(c, it) return + elif key.kind == nkCast: + if comesFromPush: + localError(c.config, n.info, "a 'cast' pragma cannot be pushed") + elif not isStatement: + localError(c.config, n.info, "'cast' pragma only allowed in a statement context") + case whichPragma(key[1]) + of wRaises, wTags: pragmaRaisesOrTags(c, key[1]) + else: discard + return elif key.kind notin nkIdentKinds: n[i] = semCustomPragma(c, it) return diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 88b9adf27a07f..08012bb55d611 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1057,9 +1057,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkSymbol, "(wrong conv)") of nkCast: put(g, tkCast, "cast") - put(g, tkBracketLe, "[") - gsub(g, n, 0) - put(g, tkBracketRi, "]") + if n.len > 0 and n[0].kind != nkEmpty: + put(g, tkBracketLe, "[") + gsub(g, n, 0) + put(g, tkBracketRi, "]") put(g, tkParLe, "(") gsub(g, n, 1) put(g, tkParRi, ")") diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index cda156224a286..47ff68368bbac 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -325,7 +325,7 @@ proc createTag(g: ModuleGraph; n: PNode): PNode = result.typ = g.sysTypeFromName(n.info, "RootEffect") if not n.isNil: result.info = n.info -proc addEffect(a: PEffects, e, comesFrom: PNode) = +proc addRaiseEffect(a: PEffects, e, comesFrom: PNode) = assert e.kind != nkRaiseStmt var aa = a.exc for i in a.bottom.. 0: n[0] else: n - if key.kind == nkIdent: result = whichKeyword(key.ident) + case key.kind + of nkIdent: result = whichKeyword(key.ident) + of nkSym: result = whichKeyword(key.sym.name) + of nkCast: result = wCast + of nkClosedSymChoice, nkOpenSymChoice: + result = whichPragma(key[0]) + else: result = wInvalid + +proc isNoSideEffectPragma*(n: PNode): bool = + var k = whichPragma(n) + if k == wCast: + k = whichPragma(n[1]) + result = k == wNoSideEffect proc findPragma*(n: PNode, which: TSpecialWord): PNode = if n.kind == nkPragma: diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index e59c5cb751c9c..a172a906e2183 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -29,8 +29,7 @@ ## for a high-level description of how borrow checking works. import ast, types, lineinfos, options, msgs, renderer, typeallowed -from trees import getMagic, whichPragma, stupidStmtListExpr -from wordrecg import wNoSideEffect +from trees import getMagic, isNoSideEffectPragma, stupidStmtListExpr from isolation_check import canAlias type @@ -713,7 +712,7 @@ proc traverse(c: var Partitions; n: PNode) = let pragmaList = n[0] var enforceNoSideEffects = 0 for i in 0..