deepCopy is instantiated when its corresponding type is instantiated
This commit is contained in:
parent
dfd7390277
commit
1088814e56
10 changed files with 87 additions and 15 deletions
|
|
@ -898,7 +898,7 @@ include ccgtrav
|
|||
|
||||
proc genDeepCopyProc(m: BModule; s: PSym; result: PRope) =
|
||||
genProc(m, s)
|
||||
appf(m.s[cfsTypeInit3], "$1.deepcopy = (N_NIMCALL_PTR(void*, void*)) $2;$n",
|
||||
appf(m.s[cfsTypeInit3], "$1.deepcopy =(N_NIMCALL_PTR(void*,)(void*))$2;$n",
|
||||
[result, s.loc.r])
|
||||
|
||||
proc genTypeInfo(m: BModule, t: PType): PRope =
|
||||
|
|
|
|||
|
|
@ -371,6 +371,8 @@ proc myOpen(module: PSym): PPassContext =
|
|||
c.semInferredLambda = semInferredLambda
|
||||
c.semGenerateInstance = generateInstance
|
||||
c.semTypeNode = semTypeNode
|
||||
c.instDeepCopy = sigmatch.instDeepCopy
|
||||
|
||||
pushProcCon(c, module)
|
||||
pushOwner(c.module)
|
||||
c.importTable = openScope(c)
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ type
|
|||
lastGenericIdx*: int # used for the generics stack
|
||||
hloLoopDetector*: int # used to prevent endless loops in the HLO
|
||||
inParallelStmt*: int
|
||||
instDeepCopy*: proc (c: PContext; dc: PSym; t: PType;
|
||||
info: TLineInfo): PSym {.nimcall.}
|
||||
|
||||
|
||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||
result.genericSym = s
|
||||
|
|
|
|||
|
|
@ -1029,7 +1029,11 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
|
|||
sameType(s.typ.sons[1], s.typ.sons[0]):
|
||||
# Note: we store the deepCopy in the base of the pointer to mitigate
|
||||
# the problem that pointers are structural types:
|
||||
let t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst)
|
||||
var t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst)
|
||||
while true:
|
||||
if t.kind == tyGenericBody: t = t.lastSon
|
||||
elif t.kind == tyGenericInvokation: t = t.sons[0]
|
||||
else: break
|
||||
if t.kind in {tyObject, tyDistinct, tyEnum}:
|
||||
if t.deepCopy.isNil: t.deepCopy = s
|
||||
else:
|
||||
|
|
@ -1044,6 +1048,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
|
|||
of "=": discard
|
||||
else: localError(n.info, errGenerated,
|
||||
"'destroy' or 'deepCopy' expected for 'override'")
|
||||
incl(s.flags, sfUsed)
|
||||
|
||||
type
|
||||
TProcCompilationSteps = enum
|
||||
|
|
|
|||
|
|
@ -299,6 +299,18 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
|||
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
|
||||
rawAddSon(result, newbody)
|
||||
checkPartialConstructedType(cl.info, newbody)
|
||||
let dc = newbody.deepCopy
|
||||
if dc != nil and sfFromGeneric notin newbody.deepCopy.flags:
|
||||
# 'deepCopy' needs to be instantiated for
|
||||
# generics *when the type is constructed*:
|
||||
newbody.deepCopy = cl.c.instDeepCopy(cl.c, dc, result, cl.info)
|
||||
when false:
|
||||
var bindings: TIdTable
|
||||
initIdTable(bindings)
|
||||
debug newbody
|
||||
bindings.idTablePut(dc.ast[genericParamsPos].sons[0].typ, newbody)
|
||||
newbody.deepCopy = cl.c.semGenerateInstance(cl.c, dc, bindings, cl.info)
|
||||
assert sfFromGeneric in newbody.deepCopy.flags
|
||||
|
||||
proc eraseVoidParams*(t: PType) =
|
||||
if t.sons[0] != nil and t.sons[0].kind == tyEmpty:
|
||||
|
|
|
|||
|
|
@ -1482,6 +1482,18 @@ proc argtypeMatches*(c: PContext, f, a: PType): bool =
|
|||
# instantiate generic converters for that
|
||||
result = res != nil
|
||||
|
||||
proc instDeepCopy*(c: PContext; dc: PSym; t: PType; info: TLineInfo): PSym {.
|
||||
procvar.} =
|
||||
var m: TCandidate
|
||||
initCandidate(c, m, dc.typ)
|
||||
var f = dc.typ.sons[1]
|
||||
if f.kind in {tyRef, tyPtr}: f = f.lastSon
|
||||
if typeRel(m, f, t) == isNone:
|
||||
localError(info, errGenerated, "cannot instantiate 'deepCopy'")
|
||||
else:
|
||||
result = c.semGenerateInstance(c, dc, m.bindings, info)
|
||||
assert sfFromGeneric in result.flags
|
||||
|
||||
include suggest
|
||||
|
||||
when not declared(tests):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue