From cdfc1cb59e772ab76afa5953ded9aab360652597 Mon Sep 17 00:00:00 2001 From: metagn <10591326+metagn@users.noreply.github.com> Date: Sun, 11 Jun 2023 21:43:40 +0300 Subject: [PATCH 1/2] binary `not` only parses simple expressions fixes #16324 --- compiler/parser.nim | 8 ++++---- doc/grammar.txt | 6 +++--- tests/notnil/tparse.nim | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 tests/notnil/tparse.nim diff --git a/compiler/parser.nim b/compiler/parser.nim index 734474dbf18c..1bf99f043ca3 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 = simpleExpr(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' simpleExpr)? + #| typeDescExpr = (routineType / simpleExpr) ('not' simpleExpr)? #| 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' simpleExpr)? 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 e498dd2b2469..48360548f4d0 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' simpleExpr)? +typeDescExpr = (routineType / simpleExpr) ('not' simpleExpr)? typeDesc = rawTypeDesc / typeDescExpr typeDefValue = ((tupleDecl | enumDecl | objectDecl | conceptDecl | ('ref' | 'ptr' | 'distinct') (tupleDecl | objectDecl)) / (simpleExpr (exprEqExpr ^+ comma postExprBlocks?)?)) - ('not' expr)? + ('not' simpleExpr)? 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 000000000000..5c938ff04f62 --- /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.} From 9cb32e1b788784a40045aa71d7266f300a83052e Mon Sep 17 00:00:00 2001 From: metagn <10591326+metagn@users.noreply.github.com> Date: Sun, 11 Jun 2023 21:47:17 +0300 Subject: [PATCH 2/2] switch to primary --- compiler/parser.nim | 8 ++++---- doc/grammar.txt | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/parser.nim b/compiler/parser.nim index 1bf99f043ca3..1b8fd70a60ac 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 = simpleExpr(p, pmTypeDesc) + 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' simpleExpr)? - #| typeDescExpr = (routineType / simpleExpr) ('not' simpleExpr)? + #| ('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' simpleExpr)? + #| ('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 48360548f4d0..458eeb54a67a 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' simpleExpr)? -typeDescExpr = (routineType / simpleExpr) ('not' simpleExpr)? + ('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' simpleExpr)? + ('not' primary)? extraPostExprBlock = ( IND{=} doBlock | IND{=} 'of' exprList ':' stmt | IND{=} 'elif' expr ':' stmt