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.
This commit is contained in:
Ryan McConnell
2026-08-28 16:33:20 -04:00
committed by GitHub
parent 0be9b4f3f6
commit 33ee586913
5 changed files with 52 additions and 1 deletions

View File

@@ -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:

View File

@@ -0,0 +1,5 @@
proc resizeCints*(s: var seq[cint], n: int) =
s.setLen(n)
proc cintLen*(s: seq[cint]): int =
result = s.len

View File

@@ -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

View File

@@ -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)

View File

@@ -0,0 +1,7 @@
import ../ccgbugs/mseq_importc_alias
type CIntAlias = cint
var values: seq[CIntAlias]
resizeCints(values, 2)
doAssert cintLen(values) == 2