diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2024-04-26 22:05:03 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-26 16:05:03 +0200 |
commit | f682dabf71f35833e934a79007906f94d8d32c92 (patch) | |
tree | fcf6ecd98957bbc83d0d51665468537ed5d2c44a | |
parent | 0b0f185bd1db2500079aefd888078b6bd1094270 (diff) | |
download | Nim-f682dabf71f35833e934a79007906f94d8d32c92.tar.gz |
fixes #23531; fixes invalid meta type accepted in the object fields (#23532)
fixes #23531 fixes #19546 fixes #6982
-rw-r--r-- | compiler/semstmts.nim | 26 | ||||
-rw-r--r-- | tests/errmsgs/tmetaobjectfields.nim | 61 |
2 files changed, 78 insertions, 9 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 7ccc29d7e..a29b07d92 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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): diff --git a/tests/errmsgs/tmetaobjectfields.nim b/tests/errmsgs/tmetaobjectfields.nim new file mode 100644 index 000000000..837041512 --- /dev/null +++ b/tests/errmsgs/tmetaobjectfields.nim @@ -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 |