From f760bc243b957ec8ebb529b9eadea53fc93adca5 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 19 Aug 2013 01:29:37 +0300 Subject: Revert "Revert "static and default params for generics"" This reverts commit 0662ec4a434f4656b5afc486bc4ebaab82c52da6. --- compiler/ast.nim | 2 + compiler/semstmts.nim | 3 +- compiler/semtypes.nim | 129 +++++++++++++++++++++++++++++--------------------- compiler/sigmatch.nim | 19 ++++++-- 4 files changed, 92 insertions(+), 61 deletions(-) (limited to 'compiler') diff --git a/compiler/ast.nim b/compiler/ast.nim index 4be931c8d..13df058e7 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -686,6 +686,8 @@ type # for record types a nkRecord node # for enum types a list of symbols # for tyInt it can be the int literal + # for procs and tyGenericBody, it's the + # formal param list # else: unused destructor*: PSym # destructor. warning: nil here may not necessary # mean that there is no destructor. diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 4de1f9151..33c0adac1 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -721,7 +721,8 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = # TGObj[T] = object # TAlias[T] = TGObj[T] # - a.sons[1] = semGenericParamList(c, a.sons[1], s.typ) + s.typ.n = semGenericParamList(c, a.sons[1], s.typ) + a.sons[1] = s.typ.n s.typ.size = -1 # could not be computed properly # we fill it out later. For magic generics like 'seq', it won't be filled # so we use tyEmpty instead of nil to not crash for strange conversions diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4bc0ad784..bb6c646f2 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -806,29 +806,44 @@ proc semGenericParamInInvokation(c: PContext, n: PNode): PType = proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = result = newOrPrevType(tyGenericInvokation, prev, c) - var isConcrete = true + addSonSkipIntLit(result, s.typ) + + template addToResult(typ) = + if typ.isNil: + InternalAssert false + rawAddSon(result, typ) + else: addSonSkipIntLit(result, typ) + if s.typ == nil: LocalError(n.info, errCannotInstantiateX, s.name.s) return newOrPrevType(tyError, prev, c) - elif s.typ.kind != tyGenericBody: - isConcrete = false - elif sonsLen(n) != sonsLen(s.typ): - LocalError(n.info, errWrongNumberOfArguments) - return newOrPrevType(tyError, prev, c) - addSonSkipIntLit(result, s.typ) - # iterate over arguments: - for i in countup(1, sonsLen(n)-1): - var elem = semGenericParamInInvokation(c, n.sons[i]) - if containsGenericType(elem): isConcrete = false - #if elem.kind in {tyGenericParam, tyGenericInvokation}: isConcrete = false - if elem.isNil: rawAddSon(result, elem) - else: addSonSkipIntLit(result, elem) - if isConcrete: - if s.ast == nil: - LocalError(n.info, errCannotInstantiateX, s.name.s) - result = newOrPrevType(tyError, prev, c) - else: - result = instGenericContainer(c, n, result) + elif s.typ.kind == tyForward: + for i in countup(1, sonsLen(n)-1): + var elem = semGenericParamInInvokation(c, n.sons[i]) + addToResult(elem) + else: + internalAssert s.typ.kind == tyGenericBody + + var m = newCandidate(s, n) + matches(c, n, copyTree(n), m) + + if m.state != csMatch: + LocalError(n.info, errWrongNumberOfArguments) + return newOrPrevType(tyError, prev, c) + + var isConcrete = true + + for i in 1 ..