diff options
author | Zahary Karadjov <zahary@gmail.com> | 2020-03-29 02:06:39 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-04-01 19:38:44 +0200 |
commit | 1b570f2b187fea9571476a1e2e768d2d4c2f7aa5 (patch) | |
tree | 3c4dcb1a6d4483dc6af28330b4ae41c49cf0387b /tests/constructors | |
parent | e0bb78553ad34282ff198c4f1121b14b18030dc2 (diff) | |
download | Nim-1b570f2b187fea9571476a1e2e768d2d4c2f7aa5.tar.gz |
Turn the warning for uninitialized (result) variables into errors
Diffstat (limited to 'tests/constructors')
-rw-r--r-- | tests/constructors/tinvalid_construction.nim | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/tests/constructors/tinvalid_construction.nim b/tests/constructors/tinvalid_construction.nim index f84a18e68..46156db6c 100644 --- a/tests/constructors/tinvalid_construction.nim +++ b/tests/constructors/tinvalid_construction.nim @@ -32,10 +32,14 @@ type a {.requiresInit.}: int b: string + PartialRequiresInitRef = ref PartialRequiresInit + FullRequiresInit {.requiresInit.} = object a: int b: int + FullRequiresInitRef = ref FullRequiresInit + FullRequiresInitWithParent {.requiresInit.} = object of THasNotNils e: int d: int @@ -72,8 +76,13 @@ var nilRef: TRefObj var notNilRef = TRefObj(x: 20) proc makeHasNotNils: ref THasNotNils = - result.a = TRefObj(x: 10) - result.b = TRefObj(x: 20) + (ref THasNotNils)(a: TRefObj(x: 10), + b: TRefObj(x: 20)) + +proc userDefinedDefault(T: typedesc): T = + # We'll use that to make sure the user cannot cheat + # with constructing requiresInit types + discard accept TObj() accept TObj(choice: A) @@ -125,7 +134,17 @@ accept PartialRequiresInit(a: 10, b: "x") accept PartialRequiresInit(a: 20) reject PartialRequiresInit(b: "x") reject PartialRequiresInit() +accept PartialRequiresInitRef(a: 10, b: "x") +accept PartialRequiresInitRef(a: 20) +reject PartialRequiresInitRef(b: "x") +reject PartialRequiresInitRef() +accept((ref PartialRequiresInit)(a: 10, b: "x")) +accept((ref PartialRequiresInit)(a: 20)) +reject((ref PartialRequiresInit)(b: "x")) +reject((ref PartialRequiresInit)()) + reject default(PartialRequiresInit) +reject userDefinedDefault(PartialRequiresInit) reject: var obj: PartialRequiresInit @@ -133,7 +152,17 @@ accept FullRequiresInit(a: 10, b: 20) reject FullRequiresInit(a: 10) reject FullRequiresInit(b: 20) reject FullRequiresInit() +accept FullRequiresInitRef(a: 10, b: 20) +reject FullRequiresInitRef(a: 10) +reject FullRequiresInitRef(b: 20) +reject FullRequiresInitRef() +accept((ref FullRequiresInit)(a: 10, b: 20)) +reject((ref FullRequiresInit)(a: 10)) +reject((ref FullRequiresInit)(b: 20)) +reject((ref FullRequiresInit)()) + reject default(FullRequiresInit) +reject userDefinedDefault(FullRequiresInit) reject: var obj: FullRequiresInit @@ -144,6 +173,7 @@ reject FullRequiresInitWithParent(a: notNilRef, b: notNilRef, e: 10, d: 20) # reject FullRequiresInitWithParent(a: notNilRef, b: notNilRef, c: nil, e: 10) # d should not be missing reject FullRequiresInitWithParent() reject default(FullRequiresInitWithParent) +reject userDefinedDefault(FullRequiresInitWithParent) reject: var obj: FullRequiresInitWithParent @@ -153,6 +183,55 @@ accept default(TNestedChoices) accept: var obj: TNestedChoices +reject: + # This proc is illegal, because it tries to produce + # a default object of a type that requires initialization: + proc defaultHasNotNils: THasNotNils = + discard + +reject: + # You cannot cheat by using the result variable to specify + # only some of the fields + proc invalidPartialTHasNotNils: THasNotNils = + result.c = nilRef + +reject: + # The same applies for requiresInit types + proc invalidPartialRequiersInit: PartialRequiresInit = + result.b = "x" + +# All code paths must return a value when the result requires initialization: +reject: + proc ifWithoutAnElse: THasNotNils = + if stdin.readLine == "": + return THasNotNils(a: notNilRef, b: notNilRef, c: nilRef) + +accept: + # All code paths must return a value when the result requires initialization: + proc wellFormedIf: THasNotNils = + if stdin.readLine == "": + return THasNotNils(a: notNilRef, b: notNilRef, c: nilRef) + else: + return THasNotNIls(a: notNilRef, b: notNilRef) + +reject: + proc caseWithoutAllCasesCovered: FullRequiresInit = + # Please note that these is no else branch here: + case stdin.readLine + of "x": + return FullRequiresInit(a: 10, b: 20) + of "y": + return FullRequiresInit(a: 30, b: 40) + +accept: + proc wellFormedCase: FullRequiresInit = + case stdin.readLine + of "x": + result = FullRequiresInit(a: 10, b: 20) + else: + # Mixing result and return is fine: + return FullRequiresInit(a: 30, b: 40) + # but if we supply a run-time value for the inner branch, the compiler won't be able to prove # that the notnil field was initialized reject TNestedChoices(outerChoice: false, innerChoice: x) # XXX: The error message is not very good here |