Files
Nim/tests/init/treturns.nim
ringabout d13aab50cf fixes branches interacting with break, raise etc. in strictdefs (#22627)
```nim
{.experimental: "strictdefs".}

type Test = object
  id: int

proc test(): Test =
  if true:
    return Test()
  else:
    return
echo test()
```

I will tackle https://github.com/nim-lang/Nim/issues/16735 and #21615 in
the following PR.


The old code just premises that in branches ended with returns, raise
statements etc. , all variables including the result variable are
initialized for that branch. It's true for noreturn statements. But it
is false for the result variable in a branch tailing with a return
statement, in which the result variable is not initialized. The solution
is not perfect for usages below branch statements with the result
variable uninitialized, but it should suffice for now, which gives a
proper warning.

It also fixes

```nim

{.experimental: "strictdefs".}

type Test = object
  id: int

proc foo {.noreturn.} = discard

proc test9(x: bool): Test =
  if x:
    foo()
  else:
    foo()
```
which gives a warning, but shouldn't
2023-09-04 14:36:45 +02:00

94 lines
2.3 KiB
Nim

{.experimental: "strictdefs".}
type Test = object
id: int
proc foo {.noreturn.} = discard
proc test1(): Test =
if true: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return Test()
else:
return
proc test0(): Test =
if true: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return
else:
foo()
proc test2(): Test =
if true: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return
else:
return
proc test3(): Test =
if true: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return
else:
return Test()
proc test4(): Test =
if true: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return
else:
result = Test()
return
proc test5(x: bool): Test =
case x: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
of true:
return
else:
return Test()
proc test6(x: bool): Test =
case x: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
of true:
return
else:
return
proc test7(x: bool): Test =
case x: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
of true:
return
else:
discard
proc test8(x: bool): Test =
case x: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
of true:
discard
else:
raise
proc hasImportStmt(): bool =
if false: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return true
else:
discard
discard hasImportStmt()
block:
proc hasImportStmt(): bool =
if false: #[tt.Warning
^ Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]]#
return true
else:
return
discard hasImportStmt()