fixes #23531; fixes invalid meta type accepted in the object fields (#23532)

fixes #23531
fixes #19546
fixes #6982
This commit is contained in:
ringabout
2024-04-26 22:05:03 +08:00
committed by GitHub
parent 0b0f185bd1
commit f682dabf71
2 changed files with 78 additions and 9 deletions

View File

@@ -1589,21 +1589,27 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
for sk in c.skipTypes:
discard semTypeNode(c, sk, nil)
c.skipTypes = @[]
proc checkForMetaFields(c: PContext; n: PNode) =
proc checkMeta(c: PContext; n: PNode; t: PType) =
if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
proc checkForMetaFields(c: PContext; n: PNode; hasError: var bool) =
proc checkMeta(c: PContext; n: PNode; t: PType; hasError: var bool; parent: PType) =
if t != nil and (t.isMetaType or t.kind == tyNone) and tfGenericTypeParam notin t.flags:
if t.kind == tyBuiltInTypeClass and t.len == 1 and t.elementType.kind == tyProc:
localError(c.config, n.info, ("'$1' is not a concrete type; " &
"for a callback without parameters use 'proc()'") % t.typeToString)
elif t.kind == tyNone and parent != nil:
# TODO: openarray has the `tfGenericTypeParam` flag & generics
# TODO: handle special cases (sink etc.) and views
localError(c.config, n.info, errTIsNotAConcreteType % parent.typeToString)
else:
localError(c.config, n.info, errTIsNotAConcreteType % t.typeToString)
hasError = true
if n.isNil: return
case n.kind
of nkRecList, nkRecCase:
for s in n: checkForMetaFields(c, s)
for s in n: checkForMetaFields(c, s, hasError)
of nkOfBranch, nkElse:
checkForMetaFields(c, n.lastSon)
checkForMetaFields(c, n.lastSon, hasError)
of nkSym:
let t = n.sym.typ
case t.kind
@@ -1611,9 +1617,9 @@ proc checkForMetaFields(c: PContext; n: PNode) =
tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink, tyOwned:
let start = ord(t.kind in {tyGenericInvocation, tyGenericInst})
for i in start..<t.len:
checkMeta(c, n, t[i])
checkMeta(c, n, t[i], hasError, t)
else:
checkMeta(c, n, t)
checkMeta(c, n, t, hasError, nil)
else:
internalAssert c.config, false
@@ -1648,9 +1654,11 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
assert s.typ != nil
assignType(s.typ, t)
s.typ.itemId = t.itemId # same id
checkConstructedType(c.config, s.info, s.typ)
var hasError = false
if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
checkForMetaFields(c, s.typ.n)
checkForMetaFields(c, s.typ.n, hasError)
if not hasError:
checkConstructedType(c.config, s.info, s.typ)
# fix bug #5170, bug #17162, bug #15526: ensure locally scoped types get a unique name:
if s.typ.kind in {tyEnum, tyRef, tyObject} and not isTopLevel(c):

View File

@@ -0,0 +1,61 @@
discard """
cmd: "nim check --hints:off $file"
action: "reject"
nimout: '''
tmetaobjectfields.nim(24, 5) Error: 'array' is not a concrete type
tmetaobjectfields.nim(28, 5) Error: 'seq' is not a concrete type
tmetaobjectfields.nim(32, 5) Error: 'set' is not a concrete type
tmetaobjectfields.nim(35, 3) Error: 'sink' is not a concrete type
tmetaobjectfields.nim(37, 3) Error: 'lent' is not a concrete type
tmetaobjectfields.nim(54, 16) Error: 'seq' is not a concrete type
tmetaobjectfields.nim(58, 5) Error: 'ptr' is not a concrete type
tmetaobjectfields.nim(59, 5) Error: 'ref' is not a concrete type
tmetaobjectfields.nim(60, 5) Error: 'auto' is not a concrete type
tmetaobjectfields.nim(61, 5) Error: 'UncheckedArray' is not a concrete type
'''
"""
# bug #6982
# bug #19546
# bug #23531
type
ExampleObj1 = object
arr: array
type
ExampleObj2 = object
arr: seq
type
ExampleObj3 = object
arr: set
type A = object
b: sink
# a: openarray
c: lent
type PropertyKind = enum
tInt,
tFloat,
tBool,
tString,
tArray
type
Property = ref PropertyObj
PropertyObj = object
case kind: PropertyKind
of tInt: intValue: int
of tFloat: floatValue: float
of tBool: boolValue: bool
of tString: stringValue: string
of tArray: arrayValue: seq
type
RegressionTest = object
a: ptr
b: ref
c: auto
d: UncheckedArray