mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-05 04:27:44 +00:00
proper error for const defines with unsupported types (#24540)
fixes #24539
(cherry picked from commit b9c593404c)
This commit is contained in:
@@ -589,7 +589,7 @@ proc foldDefine(m, s: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||
raise newException(ValueError, "invalid enum value: " & str)
|
||||
else:
|
||||
localError(g.config, s.info, "unsupported type $1 for define '$2'" %
|
||||
[name, typeToString(rawTyp)])
|
||||
[typeToString(rawTyp), name])
|
||||
except ValueError as e:
|
||||
localError(g.config, s.info,
|
||||
"could not process define '$1' of type $2; $3" %
|
||||
|
||||
@@ -612,11 +612,38 @@ proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
||||
else:
|
||||
localError(c.config, n.info, "nkDotNode requires 2 children")
|
||||
|
||||
proc checkDefineType(c: PContext; v: PSym; t: PType) =
|
||||
# see semfold.foldDefine for acceptable types
|
||||
let typeKinds =
|
||||
case v.magic
|
||||
of mStrDefine: {tyString, tyCstring}
|
||||
# this used to be not typechecked, so anything that accepts int nodes for compatbility:
|
||||
of mIntDefine: {tyInt..tyInt64, tyUInt..tyUInt64, tyBool, tyChar, tyEnum}
|
||||
of mBoolDefine: {tyBool}
|
||||
of mGenericDefine: {tyString, tyCstring, tyInt..tyInt64, tyUInt..tyUInt64, tyBool, tyEnum}
|
||||
else: raiseAssert("unreachable")
|
||||
var skipped = abstractVarRange
|
||||
if v.magic == mGenericDefine:
|
||||
# no distinct types for generic define
|
||||
skipped.excl tyDistinct
|
||||
if t.skipTypes(skipped).kind notin typeKinds:
|
||||
let name =
|
||||
case v.magic
|
||||
of mStrDefine: "strdefine"
|
||||
of mIntDefine: "intdefine"
|
||||
of mBoolDefine: "booldefine"
|
||||
of mGenericDefine: "define"
|
||||
else: raiseAssert("unreachable")
|
||||
localError(c.config, v.info, "unsupported type for constant '" & v.name.s &
|
||||
"' with ." & name & " pragma: " & typeToString(t))
|
||||
|
||||
proc setVarType(c: PContext; v: PSym, typ: PType) =
|
||||
if v.typ != nil and not sameTypeOrNil(v.typ, typ):
|
||||
localError(c.config, v.info, "inconsistent typing for reintroduced symbol '" &
|
||||
v.name.s & "': previous type was: " & typeToString(v.typ, preferDesc) &
|
||||
"; new type is: " & typeToString(typ, preferDesc))
|
||||
if v.kind == skConst and v.magic in {mGenericDefine, mIntDefine, mStrDefine, mBoolDefine}:
|
||||
checkDefineType(c, v, typ)
|
||||
v.typ = typ
|
||||
|
||||
proc isPossibleMacroPragma(c: PContext, it: PNode, key: PNode): bool =
|
||||
|
||||
6
tests/errmsgs/twrongdefinetype.nim
Normal file
6
tests/errmsgs/twrongdefinetype.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
# issue #24539
|
||||
|
||||
type Foo = object
|
||||
const foo {.define.} = Foo() #[tt.Error
|
||||
^ unsupported type for constant 'foo' with .define pragma: Foo]#
|
||||
echo repr(foo)
|
||||
Reference in New Issue
Block a user