From 8f3d5a25a692f1630bb24fbaf4951e68c9c99e28 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Tue, 31 Dec 2013 03:58:31 +0200 Subject: Templates will pick the candidate in the nearest scope when symbols are mixed-in --- compiler/ast.nim | 4 ++++ compiler/semexprs.nim | 2 +- compiler/semtempl.nim | 1 + compiler/semtypinst.nim | 15 ++++++++------- compiler/sigmatch.nim | 23 ++++++++++++++++------- compiler/types.nim | 3 ++- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 8699d1715..e25f10a66 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1430,6 +1430,10 @@ proc skipGenericOwner*(s: PSym): PSym = result = if sfFromGeneric in s.flags: s.owner.owner else: s.owner +proc originatingModule*(s: PSym): PSym = + result = s.owner + while result.kind != skModule: result = result.owner + proc isRoutine*(s: PSym): bool {.inline.} = result = s.kind in {skProc, skTemplate, skMacro, skIterator, skMethod, skConverter} diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 14f611c5c..00c0e0f78 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1164,7 +1164,7 @@ proc semAsgn(c: PContext, n: PNode): PNode = if lhsIsResult: {efAllowDestructor} else: {}) if lhsIsResult: n.typ = enforceVoidContext - if lhs.sym.typ.isMetaType: + if lhs.sym.typ.isMetaType and lhs.sym.typ.kind != tyTypeDesc: if cmpTypes(c, lhs.typ, rhs.typ) == isGeneric: internalAssert c.p.resultSym != nil lhs.typ = rhs.typ diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index da38f8625..569d92d33 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -421,6 +421,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = else: s = semIdentVis(c, skTemplate, n.sons[0], {}) # check parameter list: + s.scope = c.currentScope pushOwner(s) openScope(c) n.sons[namePos] = newSymNode(s, n.sons[namePos].info) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index fb7be3a38..ec56f75e4 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -162,8 +162,9 @@ proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = elif result.kind == tyGenericParam and not cl.allowMetaTypes: internalError(cl.info, "substitution with generic parameter") -proc instCopyType(t: PType): PType = - result = copyType(t, t.owner, false) +proc instCopyType(cl: var TReplTypeVars, t: PType): PType = + # XXX: relying on allowMetaTypes is a kludge + result = copyType(t, t.owner, cl.allowMetaTypes) result.flags.incl tfFromGeneric result.flags.excl tfInstClearedFlags @@ -184,7 +185,7 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = if x.kind == tyGenericParam: x = lookupTypeVar(cl, x) if x != nil: - if header == nil: header = instCopyType(t) + if header == nil: header = instCopyType(cl, t) header.sons[i] = x propagateToOwner(header, x) @@ -193,7 +194,7 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = result = searchInstTypes(header) if result != nil: return else: - header = instCopyType(t) + header = instCopyType(cl, t) result = newType(tyGenericInst, t.sons[0].owner) # be careful not to propagate unnecessary flags here (don't use rawAddSon) @@ -279,7 +280,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = if t.kind in {tyStatic, tyGenericParam} + tyTypeClasses: let lookup = PType(idTableGet(cl.typeMap, t)) if lookup != nil: return lookup - + case t.kind of tyGenericInvokation: result = handleGenericInvokation(cl, t) @@ -295,7 +296,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = result = lookup if tfUnresolved in t.flags: result = result.base of tyGenericInst: - result = instCopyType(t) + result = instCopyType(cl, t) for i in 1 .. 0: diff --git a/compiler/types.nim b/compiler/types.nim index 1bf18fbe2..68e816c13 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -874,7 +874,8 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, tyOrdinal, tyTypeClasses: - cycleCheck() + cycleCheck() + if a.kind == tyTypeClass and a.n != nil: return a.n == b.n result = sameChildrenAux(a, b, c) and sameFlags(a, b) if result and a.kind == tyProc: result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and -- cgit 1.4.1-2-gfad0