mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-04 22:48:38 +00:00
preparations for better type-keys
This commit is contained in:
@@ -47,6 +47,11 @@ type
|
||||
CoConsiderOwned
|
||||
CoDistinct
|
||||
CoHashTypeInsideNode
|
||||
CoPrecise # produce a FRONTEND-faithful, unique key (for the
|
||||
# stable NIF *name*, not hook dedup): keep distinctions
|
||||
# sem makes that the backend identity collapses — e.g.
|
||||
# an `int literal(x)` type carries its value so it does
|
||||
# not merge with `int`. See `getTypeKey`/`typeKeyHook`.
|
||||
|
||||
TypeLoader* = proc (t: PType) {.nimcall.}
|
||||
SymLoader* = proc (s: PSym) {.nimcall.}
|
||||
@@ -139,6 +144,20 @@ proc maybeImported(c: var Context; s: PSym; conf: ConfigRef) {.inline.} =
|
||||
if s != nil and {sfImportc, sfExportc} * s.flagsImpl != {}:
|
||||
c.symKey(s, conf)
|
||||
|
||||
proc emitPreciseFlags(c: var Context; t: PType; flags: set[ConsiderFlag]) {.inline.} =
|
||||
## Under CoPrecise the NIF *name* must be as fine as `types.sameType`, which
|
||||
## compares `eqTypeFlags * flags` (see `sameFlags`). Without this a
|
||||
## `proc() {.gcsafe.}` keyed identically to `proc()`, and a `ref X not nil`
|
||||
## identically to `ref X` — the loader would then merge two frontend-distinct
|
||||
## types onto one NIF name. Emitted only for the naming path (CoPrecise); the
|
||||
## `setAttachedOp` hook key (no CoPrecise) is unaffected, so its byte layout is
|
||||
## unchanged.
|
||||
if CoPrecise in flags:
|
||||
let ef = eqTypeFlags * t.flagsImpl
|
||||
if ef != {}:
|
||||
withTree c.m, "´tflags":
|
||||
for f in ef: c.m.addIntLit ord(f)
|
||||
|
||||
proc backendTypeName(t: PType; conf: ConfigRef): string =
|
||||
## Stable cross-module identity of a backend-minted (lower-stage) type: its
|
||||
## serialized `@bk` NIF name (mirrors ast2nif.nifTypeName). A closure-env
|
||||
@@ -229,6 +248,10 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
of tyInt:
|
||||
withTree c.m, "i":
|
||||
c.m.addIntLit -1
|
||||
# An `int literal(x)` type (nImpl holds the value) must stay distinct from
|
||||
# plain `int` for the NIF name, else overload resolution breaks on reload.
|
||||
if CoPrecise in flags and t.nImpl != nil:
|
||||
c.m.addIntLit t.nImpl.intVal
|
||||
maybeImported(c, t.symImpl, conf)
|
||||
of tyInt8:
|
||||
withTree c.m, "i":
|
||||
@@ -266,6 +289,14 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
withTree c.m, "u":
|
||||
c.m.addIntLit 64
|
||||
maybeImported(c, t.symImpl, conf)
|
||||
of tyFloat:
|
||||
withTree c.m, "f":
|
||||
c.m.addIntLit -1
|
||||
# A `float literal(x)` type (nImpl = nkFloatLit) must stay distinct from
|
||||
# plain `float`, just like the `int literal(x)` case above.
|
||||
if CoPrecise in flags and t.nImpl != nil and t.nImpl.kind in {nkFloatLit..nkFloat64Lit}:
|
||||
c.m.addFloatLit t.nImpl.floatVal
|
||||
maybeImported(c, t.symImpl, conf)
|
||||
of tyObject, tyEnum:
|
||||
if t.typeInstImpl != nil:
|
||||
# prevent against infinite recursions here, see bug #8883:
|
||||
@@ -381,6 +412,9 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
|
||||
c.m.addIdent toNifTag(t.callConvImpl)
|
||||
if tfVarargs in t.flagsImpl: c.m.addIdent "´varargs"
|
||||
# `.gcsafe`/`.noSideEffect` (in eqTypeFlags) distinguish proc types under
|
||||
# sameType, so they must distinguish the NIF name too.
|
||||
emitPreciseFlags(c, t, flags)
|
||||
of tyArray:
|
||||
withTree c.m, toNifTag(t.kind):
|
||||
if t.sonsImpl.len == 0:
|
||||
@@ -395,6 +429,9 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
c.typeKey t.sonsImpl[i], flags, conf
|
||||
if tfNotNil in t.flagsImpl and CoType notin flags:
|
||||
c.m.addIdent "´notnil"
|
||||
# tfNotNil/tfVarIsPtr/tfIsOutParam (eqTypeFlags) part of sameType identity
|
||||
# for ref/ptr/var/lent/sink; the hook path (no CoPrecise) keeps its layout.
|
||||
emitPreciseFlags(c, t, flags)
|
||||
|
||||
proc typeKey*(t: PType; conf: ConfigRef; tl: TypeLoader; sl: SymLoader): string =
|
||||
var c: Context = Context(m: createMangler(30, -1), tl: tl, sl: sl,
|
||||
|
||||
Reference in New Issue
Block a user