mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-01 19:33:42 +00:00
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.
(cherry picked from commit 33ee586913)
This commit is contained in:
committed by
narimiran
parent
c14d78eb56
commit
92177580e4
@@ -143,7 +143,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.typeInst != nil:
|
||||
# prevent against infinite recursions here, see bug #8883:
|
||||
|
||||
5
tests/ccgbugs/mseq_importc_alias.nim
Normal file
5
tests/ccgbugs/mseq_importc_alias.nim
Normal 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
|
||||
15
tests/ccgbugs/tseq_importc_alias_crossmod.nim
Normal file
15
tests/ccgbugs/tseq_importc_alias_crossmod.nim
Normal 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
|
||||
20
tests/ccgbugs/tseq_importc_alias_mangle.nim
Normal file
20
tests/ccgbugs/tseq_importc_alias_mangle.nim
Normal 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)
|
||||
7
tests/ic/timportcalias.nim
Normal file
7
tests/ic/timportcalias.nim
Normal file
@@ -0,0 +1,7 @@
|
||||
import ../ccgbugs/mseq_importc_alias
|
||||
|
||||
type CIntAlias = cint
|
||||
|
||||
var values: seq[CIntAlias]
|
||||
resizeCints(values, 2)
|
||||
doAssert cintLen(values) == 2
|
||||
Reference in New Issue
Block a user