diff options
Diffstat (limited to 'compiler/seminst.nim')
-rwxr-xr-x | compiler/seminst.nim | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 1da6a671f..9ec78488b 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -8,6 +8,7 @@ # # This module implements the instantiation of generic procs. +# included from sem.nim proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, entry: var TInstantiatedSymbol) = @@ -106,6 +107,35 @@ proc sideEffectsCheck(c: PContext, s: PSym) = s.ast.sons[genericParamsPos].kind == nkEmpty: c.threadEntries.add(s) +template nimdbg: expr = c.filename.endsWith"nimdbg.nim" + +proc applyConcreteTypesToSig(genericProc: PSym, concTypes: seq[PType]): PType = + # XXX: This is intended to replace the use of semParamList in generateInstance. + # The results of semParamList's analysis are already encoded in the original + # proc type and any concrete types may be aplied directly over it. + # Besides being more efficient, it will remove the awkward case of + # genericParams == nil in semParamList. + # Currenly, it fails in some cases such as: + # proc inc2*[T](x: var ordinal[T], y = 1) {.magic: "Inc", noSideEffect.} + let sig = genericProc.typ + result = copyType(sig, getCurrOwner(), false) + result.n = sig.n.shallowCopy + + for i in countup(0, sig.len - 1): + let tOrig = sig.sons[i] + if tOrig == nil: continue + let oGenParams = genericProc.ast.sons[genericParamsPos] + if skipTypes(tOrig, skipPtrs).kind in {tyGenericParam}: + var tConcrete = concTypes[tOrig.sym.position] + if i > 0: + let param = sig.n.sons[i].sym.copySym + param.typ = tConcrete + result.n.sons[i] = newSymNode(param) + result.sons[i] = tConcrete + else: + result.sons[i] = tOrig + if i > 0: result.n.sons[i] = sig.n.sons[i] + proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym = # generates an instantiated proc @@ -133,12 +163,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry) n.sons[genericParamsPos] = ast.emptyNode # semantic checking for the parameters: - if n.sons[paramsPos].kind != nkEmpty: - removeDefaultParamValues(n.sons[ParamsPos]) - semParamList(c, n.sons[ParamsPos], nil, result) - # XXX: obsoleted - happens in semParamList # - # addParams(c, result.typ.n) - else: + if n.sons[paramsPos].kind != nkEmpty: + if false and nimdbg: + result.typ = applyConcreteTypesToSig(fn, entry.concreteTypes) + addParams(c, result.typ.n, fn.kind) + else: + removeDefaultParamValues(n.sons[ParamsPos]) + semParamList(c, n.sons[ParamsPos], nil, result) + else: result.typ = newTypeS(tyProc, c) addSon(result.typ, nil) result.typ.callConv = fn.typ.callConv |