diff options
author | metagn <metagngn@gmail.com> | 2023-06-12 07:22:50 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-12 06:22:50 +0200 |
commit | e0ad71a912361d994b1d7b052d0153f7f5528a63 (patch) | |
tree | a9db339caee4998910e53fa72a1cd1b8e96b1fe6 | |
parent | 7b1c448744f9b29a41d205f102fb2b4e7f735d88 (diff) | |
download | Nim-e0ad71a912361d994b1d7b052d0153f7f5528a63.tar.gz |
make binary `not` not parse complex expressions on right side (#22078)
* binary `not` only parses simple expressions fixes #16324 * switch to primary
-rw-r--r-- | compiler/parser.nim | 8 | ||||
-rw-r--r-- | doc/grammar.txt | 6 | ||||
-rw-r--r-- | tests/notnil/tparse.nim | 18 |
3 files changed, 25 insertions, 7 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim index 734474dbf..1b8fd70a6 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1396,7 +1396,7 @@ proc binaryNot(p: var Parser; a: PNode): PNode = let notOpr = newIdentNodeP(p.tok.ident, p) getTok(p) optInd(p, notOpr) - let b = parseExpr(p) + let b = primary(p, pmTypeDesc) result = newNodeP(nkInfix, p) result.add notOpr result.add a @@ -1407,8 +1407,8 @@ proc binaryNot(p: var Parser; a: PNode): PNode = proc parseTypeDesc(p: var Parser, fullExpr = false): PNode = #| rawTypeDesc = (tupleType | routineType | 'enum' | 'object' | #| ('var' | 'out' | 'ref' | 'ptr' | 'distinct') typeDesc?) - #| ('not' expr)? - #| typeDescExpr = (routineType / simpleExpr) ('not' expr)? + #| ('not' primary)? + #| typeDescExpr = (routineType / simpleExpr) ('not' primary)? #| typeDesc = rawTypeDesc / typeDescExpr newlineWasSplitting(p) if fullExpr: @@ -1445,7 +1445,7 @@ proc parseTypeDefValue(p: var Parser): PNode = #| typeDefValue = ((tupleDecl | enumDecl | objectDecl | conceptDecl | #| ('ref' | 'ptr' | 'distinct') (tupleDecl | objectDecl)) #| / (simpleExpr (exprEqExpr ^+ comma postExprBlocks?)?)) - #| ('not' expr)? + #| ('not' primary)? case p.tok.tokType of tkTuple: result = parseTuple(p, true) of tkRef: result = parseTypeDescKAux(p, nkRefTy, pmTypeDef) diff --git a/doc/grammar.txt b/doc/grammar.txt index e498dd2b2..458eeb54a 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -104,13 +104,13 @@ primary = simplePrimary (commandStart expr (doBlock extraPostExprBlock*)?)? / prefixOperator primary rawTypeDesc = (tupleType | routineType | 'enum' | 'object' | ('var' | 'out' | 'ref' | 'ptr' | 'distinct') typeDesc?) - ('not' expr)? -typeDescExpr = (routineType / simpleExpr) ('not' expr)? + ('not' primary)? +typeDescExpr = (routineType / simpleExpr) ('not' primary)? typeDesc = rawTypeDesc / typeDescExpr typeDefValue = ((tupleDecl | enumDecl | objectDecl | conceptDecl | ('ref' | 'ptr' | 'distinct') (tupleDecl | objectDecl)) / (simpleExpr (exprEqExpr ^+ comma postExprBlocks?)?)) - ('not' expr)? + ('not' primary)? extraPostExprBlock = ( IND{=} doBlock | IND{=} 'of' exprList ':' stmt | IND{=} 'elif' expr ':' stmt diff --git a/tests/notnil/tparse.nim b/tests/notnil/tparse.nim new file mode 100644 index 000000000..5c938ff04 --- /dev/null +++ b/tests/notnil/tparse.nim @@ -0,0 +1,18 @@ +# issue #16324 + +{.push experimental: "notnil".} + +block: + type Foo = ref object + value: int + + proc newFoo1(): Foo not nil = # This compiles + return Foo(value: 1) + + proc newFoo2(): Foo not nil {.inline.} = # This does not + return Foo(value: 1) + + doAssert newFoo1().value == 1 + doAssert newFoo2().value == 1 + +{.pop.} |