mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-27 00:51:39 +00:00
refs https://github.com/nim-lang/Nim/pull/23873#discussion_r1687995060, fixes #23386, fixes #23385, supersedes #23572 Turns the `nfOpenSym` node flag implemented in #23091 and extended in #23102 and #23873, into a node kind `nkOpenSym` that forms a unary node containing either `nkSym` or `nkOpenSymChoice`. Since this affects macros working on generic proc AST, the node kind is now only generated when the experimental switch `genericsOpenSym` is enabled, and a new node flag `nfDisabledOpenSym` is set to the `nkSym` or `nkOpenSymChoice` when the switch is not enabled so that we can give a warning. Now that the experimental switch has more reasonable semantics, we define `nimHasGenericsOpenSym2`.
60 lines
1.6 KiB
Nim
60 lines
1.6 KiB
Nim
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")
|
|
|
|
proc g(T: type): string =
|
|
let x = f().valueOr:
|
|
{.push warningAsError[GenericsIgnoredInjection]: 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]]#
|
|
|
|
"ok"
|
|
|
|
discard g(int)
|