Skip to content

Commit

Permalink
proper error for const defines with unsupported types [backport:2.0]
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Dec 16, 2024
1 parent 556f217 commit b5ee289
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/semfold.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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" %
Expand Down
23 changes: 23 additions & 0 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -612,11 +612,34 @@ 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")
if t.skipTypes(abstractVarRange-{tyDistinct}).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 =
Expand Down
4 changes: 4 additions & 0 deletions tests/errmsgs/twrongdefinetype.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type Foo = object
const foo {.define.} = Foo() #[tt.Error
^ unsupported type for constant 'foo' with .define pragma: Foo]#
echo repr(foo)

0 comments on commit b5ee289

Please sign in to comment.