From 33ee586913930ce6755a603dc15eece559034e1e Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Fri, 28 Aug 2026 16:33:20 -0400 Subject: [PATCH] fixes #11797; fix C type hashes for imported aliases (#26150) Fixes #11797. Imported scalar and pointer aliases inherit their external C spelling, but receive a different Nim symbol. Signature hashing previously used that symbol identity, so aliases that emit exactly the same C type could produce different backend names for tuples, sequences, and other generic types. For example, `cint` and `type CIntAlias = cint` both emit `int`, but `seq[cint]` and `seq[CIntAlias]` could be emitted as incompatible C structs. The Nim type checker nevertheless permits assignments and calls between them, causing the generated C or C++ compilation to fail. This changes the backend hash to use the external type spelling when available. A symbol-based fallback remains for imported types without a resolved spelling. The change deliberately does not collapse imported types into their underlying Nim builtin. Types such as `pid_t`, imported pointers with qualifiers, and platform typedefs may require distinct backend representations. ## NIF and incremental compilation This does not change NIF serialization, NIF type keys, or the IC cache format. The bug is in backend type-name generation. An IC regression test is included to ensure that the corrected backend identity is preserved when compilation passes through the NIF pipeline. ## Tests The regressions cover: - tuple and sequence assignments between an imported type and its alias - cross-module sequence parameters and mutation - C and C++ backends - NIF-backed incremental compilation Existing C-type tests were also run under C/C++, refc, and ARC. ## Remaining scope This does not solve the broader question of compatibility between imported and builtin types that have different backend identities, such as `seq[cdouble]` and `seq[float]`. That remains tracked by #19374. --- compiler/sighashes.nim | 6 +++++- tests/ccgbugs/mseq_importc_alias.nim | 5 +++++ tests/ccgbugs/tseq_importc_alias_crossmod.nim | 15 ++++++++++++++ tests/ccgbugs/tseq_importc_alias_mangle.nim | 20 +++++++++++++++++++ tests/ic/timportcalias.nim | 7 +++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/ccgbugs/mseq_importc_alias.nim create mode 100644 tests/ccgbugs/tseq_importc_alias_crossmod.nim create mode 100644 tests/ccgbugs/tseq_importc_alias_mangle.nim create mode 100644 tests/ic/timportcalias.nim diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 447767d7eb..6c07541f3d 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -209,7 +209,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi # backend spelling instead of collapsing into the generic Nim builtin: c &= char(t.kind) if t.sym != nil and {sfImportc, sfExportc} * t.sym.flags != {}: - c.hashSym(t.sym) + # Aliases inherit the external name, but have a different symbol. + if t.sym.loc.snippet != "": + c &= t.sym.loc.snippet + else: + c.hashSym(t.sym) of tyObject, tyEnum: if t.typeInstImpl != nil: # prevent against infinite recursions here, see bug #8883: diff --git a/tests/ccgbugs/mseq_importc_alias.nim b/tests/ccgbugs/mseq_importc_alias.nim new file mode 100644 index 0000000000..5b3f97747d --- /dev/null +++ b/tests/ccgbugs/mseq_importc_alias.nim @@ -0,0 +1,5 @@ +proc resizeCints*(s: var seq[cint], n: int) = + s.setLen(n) + +proc cintLen*(s: seq[cint]): int = + result = s.len diff --git a/tests/ccgbugs/tseq_importc_alias_crossmod.nim b/tests/ccgbugs/tseq_importc_alias_crossmod.nim new file mode 100644 index 0000000000..a4c94d2b2e --- /dev/null +++ b/tests/ccgbugs/tseq_importc_alias_crossmod.nim @@ -0,0 +1,15 @@ +discard """ + action: run + targets: "c cpp" +""" + +import mseq_importc_alias + +type CIntAlias = cint + +var fds: seq[CIntAlias] +doAssert cintLen(@[1.cint, 2.cint]) == 2 +doAssert cintLen(fds) == 0 +resizeCints(fds, 3) +fds[1] = CIntAlias(7) +doAssert cintLen(fds) == 3 diff --git a/tests/ccgbugs/tseq_importc_alias_mangle.nim b/tests/ccgbugs/tseq_importc_alias_mangle.nim new file mode 100644 index 0000000000..a6a9074ec4 --- /dev/null +++ b/tests/ccgbugs/tseq_importc_alias_mangle.nim @@ -0,0 +1,20 @@ +discard """ + action: run + targets: "c cpp" +""" + +type CIntAlias = cint + +var x: (cint,) = (1.cint,) +var y: (CIntAlias,) = x +x = y +doAssert x[0] == 1.cint + +var a: seq[cint] +var b: seq[CIntAlias] +a.add 1.cint +a.add 2.cint +b = a +a = b +doAssert a[0] == 1.cint +doAssert b[1] == CIntAlias(2) diff --git a/tests/ic/timportcalias.nim b/tests/ic/timportcalias.nim new file mode 100644 index 0000000000..2f6c20f4b5 --- /dev/null +++ b/tests/ic/timportcalias.nim @@ -0,0 +1,7 @@ +import ../ccgbugs/mseq_importc_alias + +type CIntAlias = cint + +var values: seq[CIntAlias] +resizeCints(values, 2) +doAssert cintLen(values) == 2