Skip to content

Commit

Permalink
fixes #23531; fixes invalid meta type accepted in the object fields (#…
Browse files Browse the repository at this point in the history
…23532)

fixes #23531
fixes #19546
fixes #6982
  • Loading branch information
ringabout committed Apr 26, 2024
1 parent 0b0f185 commit f682dab
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 9 deletions.
26 changes: 17 additions & 9 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1589,31 +1589,37 @@ 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
of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyLent, tyPtr, tyRef,
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

Expand Down Expand Up @@ -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):
Expand Down
61 changes: 61 additions & 0 deletions tests/errmsgs/tmetaobjectfields.nim
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit f682dab

Please sign in to comment.