mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-07 04:14:19 +00:00
whitelist prev types to reuse in newOrPrevType (#24899)
fixes #24898
A type is only overwritten if it is definitely a forward type, partial
object (symbol marked `sfForward`) or a magic type. Maybe worse for
performance but should be more correct. Another option might be to
provide a different value for `prev` for the `preserveSym` case but then
we cannot easily ignore only nominal type nodes.
(cherry picked from commit d966ee3fc3)
This commit is contained in:
@@ -38,21 +38,27 @@ const
|
||||
errNoGenericParamsAllowedForX = "no generic parameters allowed for $1"
|
||||
errInOutFlagNotExtern = "the '$1' modifier can be used only with imported types"
|
||||
|
||||
proc reusePrev(prev: PType): bool {.inline.} =
|
||||
# only overwrite `prev` if it is a forward type, partial object or magic type
|
||||
result = prev != nil and (prev.kind == tyForward or (prev.sym != nil and
|
||||
# partial object marks sym as `sfForward`
|
||||
(sfForward in prev.sym.flags or prev.sym.magic != mNone)))
|
||||
|
||||
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext, son: sink PType): PType =
|
||||
if prev == nil or prev.kind == tyGenericBody:
|
||||
result = newTypeS(kind, c, son)
|
||||
else:
|
||||
if reusePrev(prev):
|
||||
result = prev
|
||||
result.setSon(son)
|
||||
if result.kind == tyForward: result.kind = kind
|
||||
else:
|
||||
result = newTypeS(kind, c, son)
|
||||
#if kind == tyError: result.flags.incl tfCheckedForDestructor
|
||||
|
||||
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
|
||||
if prev == nil or prev.kind == tyGenericBody:
|
||||
result = newTypeS(kind, c)
|
||||
else:
|
||||
if reusePrev(prev):
|
||||
result = prev
|
||||
if result.kind == tyForward: result.kind = kind
|
||||
else:
|
||||
result = newTypeS(kind, c)
|
||||
|
||||
proc newConstraint(c: PContext, k: TTypeKind): PType =
|
||||
result = newTypeS(tyBuiltInTypeClass, c)
|
||||
|
||||
18
tests/types/tresemtypesection.nim
Normal file
18
tests/types/tresemtypesection.nim
Normal file
@@ -0,0 +1,18 @@
|
||||
macro foo(x: typed) =
|
||||
result = x
|
||||
|
||||
foo:
|
||||
type
|
||||
Generic1[T] = object
|
||||
Generic2[T] = ref int
|
||||
Generic3[T] = ref Generic1[T]
|
||||
Generic4[T] = Generic2[T]
|
||||
GenericInst1 = Generic1[int]
|
||||
GenericInst2 = Generic2[int]
|
||||
GenericInst3 = Generic3[int]
|
||||
GenericInst4 = Generic4[int]
|
||||
|
||||
block: # issue #24898
|
||||
type V[W] = object
|
||||
template g(d: int) = discard d
|
||||
g((; type J = V[int]; 0))
|
||||
Reference in New Issue
Block a user