diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/compileoption/texperimental.nim | 4 | ||||
-rw-r--r-- | tests/compileoption/texperimental.nims | 4 | ||||
-rw-r--r-- | tests/config.nims | 2 | ||||
-rw-r--r-- | tests/generics/tmacroinjectedsymwarning.nim | 4 | ||||
-rw-r--r-- | tests/template/topensym.nim | 209 | ||||
-rw-r--r-- | tests/template/topensymwarning.nim | 60 |
6 files changed, 276 insertions, 7 deletions
diff --git a/tests/compileoption/texperimental.nim b/tests/compileoption/texperimental.nim index e31b0481d..be637e58a 100644 --- a/tests/compileoption/texperimental.nim +++ b/tests/compileoption/texperimental.nim @@ -16,5 +16,5 @@ static: doAssert compileOption("experimental", "strictDefs") doAssert compileOption("experimental", "strictCaseObjects") doAssert compileOption("experimental", "inferGenericTypes") - doAssert compileOption("experimental", "genericsOpenSym") - doAssert compileOption("experimental", "vtables") \ No newline at end of file + doAssert compileOption("experimental", "openSym") + doAssert compileOption("experimental", "vtables") diff --git a/tests/compileoption/texperimental.nims b/tests/compileoption/texperimental.nims index a2094eb4a..c2c357caa 100644 --- a/tests/compileoption/texperimental.nims +++ b/tests/compileoption/texperimental.nims @@ -15,5 +15,5 @@ switch("experimental", "flexibleOptionalParams") switch("experimental", "strictDefs") switch("experimental", "strictCaseObjects") switch("experimental", "inferGenericTypes") -switch("experimental", "genericsOpenSym") -switch("experimental", "vtables") \ No newline at end of file +switch("experimental", "openSym") +switch("experimental", "vtables") diff --git a/tests/config.nims b/tests/config.nims index 91934cc74..31610e128 100644 --- a/tests/config.nims +++ b/tests/config.nims @@ -45,4 +45,4 @@ switch("define", "nimPreviewNonVarDestructor") switch("warningAserror", "UnnamedBreak") switch("legacy", "verboseTypeMismatch") switch("experimental", "vtables") -switch("experimental", "genericsOpenSym") +switch("experimental", "openSym") diff --git a/tests/generics/tmacroinjectedsymwarning.nim b/tests/generics/tmacroinjectedsymwarning.nim index 4b2ae4f7e..77119004b 100644 --- a/tests/generics/tmacroinjectedsymwarning.nim +++ b/tests/generics/tmacroinjectedsymwarning.nim @@ -46,13 +46,13 @@ proc f(): Result[int, cstring] = proc g(T: type): string = let x = f().valueOr: - {.push warningAsError[GenericsIgnoredInjection]: on.} + {.push warningAsError[IgnoredSymbolInjection]: on.} # test spurious error discard true let _ = f {.pop.} return $error #[tt.Warning - ^ a new symbol 'error' has been injected during instantiation of g, however 'error' [enumField declared in tmacroinjectedsymwarning.nim(6, 3)] captured at the proc declaration will be used instead; either enable --experimental:genericsOpenSym to use the injected symbol or `bind` this captured symbol explicitly [GenericsIgnoredInjection]]# + ^ a new symbol 'error' has been injected during template or generic instantiation, however 'error' [enumField declared in tmacroinjectedsymwarning.nim(6, 3)] captured at the proc declaration will be used instead; either enable --experimental:openSym to use the injected symbol, or `bind` this captured symbol explicitly [IgnoredSymbolInjection]]# "ok" diff --git a/tests/template/topensym.nim b/tests/template/topensym.nim new file mode 100644 index 000000000..9393e1971 --- /dev/null +++ b/tests/template/topensym.nim @@ -0,0 +1,209 @@ +{.experimental: "templateOpenSym".} + +block: # issue #24002 + type Result[T, E] = object + func value[T, E](self: Result[T, E]): T {.inline.} = + discard + func value[T: not void, E](self: var Result[T, E]): var T {.inline.} = + discard + template unrecognizedFieldWarning = + doAssert value == 123 + let x = value + doAssert value == x + proc readValue(value: var int) = + unrecognizedFieldWarning() + var foo: int = 123 + readValue(foo) + +block: # issue #22605 for templates, normal call syntax + const error = "bad" + + template valueOr(self: int, def: untyped): untyped = + case false + of true: "" + of false: + template error: untyped {.used, inject.} = "good" + def + + template g(T: type): string = + var res = "ok" + let x = valueOr 123: + res = $error + "dummy" + res + + doAssert g(int) == "good" + + template g2(T: type): string = + bind error # use the bad version on purpose + var res = "ok" + let x = valueOr 123: + res = $error + "dummy" + res + + doAssert g2(int) == "bad" + +block: # issue #22605 for templates, method call syntax + const error = "bad" + + template valueOr(self: int, def: untyped): untyped = + case false + of true: "" + of false: + template error: untyped {.used, inject.} = "good" + def + + template g(T: type): string = + var res = "ok" + let x = 123.valueOr: + res = $error + "dummy" + res + + doAssert g(int) == "good" + + template g2(T: type): string = + bind error # use the bad version on purpose + var res = "ok" + let x = 123.valueOr: + res = $error + "dummy" + res + + doAssert g2(int) == "bad" + +block: # issue #22605 for templates, original complex example + type Xxx = enum + error + value + + type + Result[T, E] = object + when T is void: + when E is void: + oResultPrivate*: bool + else: + case oResultPrivate*: bool + of false: + eResultPrivate*: E + of true: + discard + else: + when E is void: + case oResultPrivate*: bool + of false: + discard + of true: + vResultPrivate*: T + else: + case oResultPrivate*: bool + of false: + eResultPrivate*: E + of true: + vResultPrivate*: T + + template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped = + let s = (self) # TODO avoid copy + case s.oResultPrivate + of true: + s.vResultPrivate + of false: + when E isnot void: + template error: untyped {.used, inject.} = s.eResultPrivate + def + + proc f(): Result[int, cstring] = + Result[int, cstring](oResultPrivate: false, eResultPrivate: "f") + + template g(T: type): string = + var res = "ok" + let x = f().valueOr: + res = $error + 123 + res + + doAssert g(int) == "f" + + template g2(T: type): string = + bind error # use the bad version on purpose + var res = "ok" + let x = f().valueOr: + res = $error + 123 + res + + doAssert g2(int) == "error" + +block: # issue #23865 for templates + type Xxx = enum + error + value + + type + Result[T, E] = object + when T is void: + when E is void: + oResultPrivate: bool + else: + case oResultPrivate: bool + of false: + eResultPrivate: E + of true: + discard + else: + when E is void: + case oResultPrivate: bool + of false: + discard + of true: + vResultPrivate: T + else: + case oResultPrivate: bool + of false: + eResultPrivate: E + of true: + vResultPrivate: T + + func error[T, E](self: Result[T, E]): E = + ## Fetch error of result if set, or raise Defect + case self.oResultPrivate + of true: + when T isnot void: + raiseResultDefect("Trying to access error when value is set", self.vResultPrivate) + else: + raiseResultDefect("Trying to access error when value is set") + of false: + when E isnot void: + self.eResultPrivate + + template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped = + let s = (self) # TODO avoid copy + case s.oResultPrivate + of true: + s.vResultPrivate + of false: + when E isnot void: + template error: untyped {.used, inject.} = s.eResultPrivate + def + proc f(): Result[int, cstring] = + Result[int, cstring](oResultPrivate: false, eResultPrivate: "f") + template g(T: type): string = + var res = "ok" + let x = f().valueOr: + res = $error + 123 + res + doAssert g(int) == "f" + +import std/sequtils + +block: # issue #15314 + var it: string + var nums = @[1,2,3] + + template doubleNums() = + nums.applyIt(it * 2) + + doubleNums() + doAssert nums == @[2, 4, 6] diff --git a/tests/template/topensymwarning.nim b/tests/template/topensymwarning.nim new file mode 100644 index 000000000..0bbe0a9fb --- /dev/null +++ b/tests/template/topensymwarning.nim @@ -0,0 +1,60 @@ +discard """ + matrix: "--skipParentCfg --filenames:legacyRelProj" +""" + +type Xxx = enum + error + value + +type + Result[T, E] = object + when T is void: + when E is void: + oResultPrivate*: bool + else: + case oResultPrivate*: bool + of false: + eResultPrivate*: E + of true: + discard + else: + when E is void: + case oResultPrivate*: bool + of false: + discard + of true: + vResultPrivate*: T + else: + case oResultPrivate*: bool + of false: + eResultPrivate*: E + of true: + vResultPrivate*: T + +template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped = + let s = (self) # TODO avoid copy + case s.oResultPrivate + of true: + s.vResultPrivate + of false: + when E isnot void: + template error: untyped {.used, inject.} = s.eResultPrivate + def + +proc f(): Result[int, cstring] = + Result[int, cstring](oResultPrivate: false, eResultPrivate: "f") + +template g(T: type): string = + var res = "ok" + let x = f().valueOr: + {.push warningAsError[IgnoredSymbolInjection]: on.} + # test spurious error + discard true + let _ = f + {.pop.} + res = $error #[tt.Warning + ^ a new symbol 'error' has been injected during template or generic instantiation, however 'error' [enumField declared in topensymwarning.nim(6, 3)] captured at the proc declaration will be used instead; either enable --experimental:openSym to use the injected symbol, or `bind` this captured symbol explicitly [IgnoredSymbolInjection]]# + 123 + res + +discard g(int) |