From 8be82c36c97d51a183633249d284afd0a621b0fd Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Thu, 17 Oct 2024 02:49:31 +0800 Subject: [PATCH] fixes #18896; fixes #20886; importc types alias doesn't work with distinct (#24313) fixes #18896 fixes #20886 ```nim type PFile {.importc: "FILE*", header: "".} = distinct pointer # import C's FILE* type; Nim will treat it as a new pointer type ``` This is an excerpt from the Nim manual. In the old Nim versions, it produces a void pointer type instead of the `FILE*` type that should have been generated. Because these C types tend to be opaque and adapt to changes on different platforms. It might affect the portability of Nim on various OS, i.e. `csource_v2` cannot build on the apline platform because of `Time` relies on Nim types instead of the `time_t` type. ref https://github.com/nim-lang/Nim/pull/18851 --- compiler/ccgtypes.nim | 10 ++++++++-- tests/ccgbugs/timportc_distinct.nim | 13 +++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/ccgbugs/timportc_distinct.nim diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 154ab7475da2..2337c70e63af 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -340,7 +340,12 @@ proc getSimpleTypeDesc(m: BModule; typ: PType): Rope = of tyNil: result = typeNameOrLiteral(m, typ, "void*") of tyInt..tyUInt64: result = typeNameOrLiteral(m, typ, NumericalTypeToStr[typ.kind]) - of tyDistinct, tyRange, tyOrdinal: result = getSimpleTypeDesc(m, typ.skipModifier) + of tyRange, tyOrdinal: result = getSimpleTypeDesc(m, typ.skipModifier) + of tyDistinct: + result = getSimpleTypeDesc(m, typ.skipModifier) + if isImportedType(typ) and result != "": + useHeader(m, typ.sym) + result = typ.sym.loc.snippet of tyStatic: if typ.n != nil: result = getSimpleTypeDesc(m, skipModifier typ) else: @@ -861,7 +866,8 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes if t != origTyp and origTyp.sym != nil: useHeader(m, origTyp.sym) let sig = hashType(origTyp, m.config) - result = getTypePre(m, t, sig) + # tyDistinct matters if it is an importc type + result = getTypePre(m, origTyp.skipTypes(irrelevantForBackend-{tyOwned, tyDistinct}), sig) defer: # defer is the simplest in this case if isImportedType(t) and not m.typeABICache.containsOrIncl(sig): addAbiCheck(m, t, result) diff --git a/tests/ccgbugs/timportc_distinct.nim b/tests/ccgbugs/timportc_distinct.nim new file mode 100644 index 000000000000..afeadf33f9ed --- /dev/null +++ b/tests/ccgbugs/timportc_distinct.nim @@ -0,0 +1,13 @@ +discard """ + ccodecheck: "time_t" + joinable: false +""" + +type + Time* {.importc: "time_t", header: "".} = distinct clong + +proc foo = + var s: Time = default(Time) + discard s + +foo()