-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 #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
- Loading branch information
Showing
4 changed files
with
226 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
discard """ | ||
matrix: "--warningAsError:ProveInit --warningAsError:Uninit" | ||
""" | ||
|
||
{.experimental: "strictdefs".} | ||
|
||
type Test = object | ||
id: int | ||
|
||
proc foo {.noreturn.} = discard | ||
|
||
block: | ||
proc test(x: bool): Test = | ||
if x: | ||
foo() | ||
else: | ||
foo() | ||
|
||
block: | ||
proc test(x: bool): Test = | ||
if x: | ||
result = Test() | ||
else: | ||
foo() | ||
|
||
discard test(true) | ||
|
||
block: | ||
proc test(x: bool): Test = | ||
if x: | ||
result = Test() | ||
else: | ||
return Test() | ||
|
||
discard test(true) | ||
|
||
block: | ||
proc test(x: bool): Test = | ||
if x: | ||
return Test() | ||
else: | ||
return Test() | ||
|
||
discard test(true) | ||
|
||
block: | ||
proc test(x: bool): Test = | ||
if x: | ||
result = Test() | ||
else: | ||
result = Test() | ||
return | ||
|
||
discard test(true) | ||
|
||
block: | ||
proc test(x: bool): Test = | ||
if x: | ||
result = Test() | ||
return | ||
else: | ||
raise newException(ValueError, "unreachable") | ||
|
||
discard test(true) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{.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() |