diff options
-rw-r--r-- | compiler/ccgutils.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 4 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 17 | ||||
-rw-r--r-- | compiler/types.nim | 3 | ||||
-rw-r--r-- | tests/concepts/tstackconcept.nim | 3 |
6 files changed, 24 insertions, 7 deletions
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index ff8f768bd..afcf24167 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -101,6 +101,8 @@ proc getUniqueType*(key: PType): PType = gCanonicalTypes[k] = key result = key of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr, tyFieldAccessor: + if key.isResolvedUserTypeClass: + return getUniqueType(lastSon(key)) if key.sym != nil: internalError(key.sym.info, "metatype not eliminated") else: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index cb16bf406..a14bc6c79 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -909,12 +909,12 @@ proc makeDeref(n: PNode): PNode = t = skipTypes(baseTyp, {tyGenericInst, tyAlias}) const - tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass} + tyTypeParamsHolders = {tyGenericInst, tyUserTypeClassInst, tyCompositeTypeClass} tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias} proc readTypeParameter(c: PContext, typ: PType, paramName: PIdent, info: TLineInfo): PNode = - let ty = if typ.kind == tyGenericInst: typ.skipGenericAlias + let ty = if typ.kind in {tyGenericInst, tyUserTypeClassInst}: typ.skipGenericAlias else: (internalAssert(typ.kind == tyCompositeTypeClass); typ.sons[1].skipGenericAlias) let tbody = ty.sons[0] diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 75dffb67f..9a1ace42e 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -447,7 +447,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = of tyUserTypeClass: result = t - of tyGenericInst: + of tyGenericInst, tyUserTypeClassInst: bailout() result = instCopyType(cl, t) idTablePut(cl.localCache, t, result) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index b279e7d2d..f8004fa21 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -642,7 +642,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, # We need to put them in the current sigmatch's binding table in order for them # to be resolvable while matching the rest of the parameters for p in typeParams: - put(m.bindings, p[0].typ, p[1]) + put(m.bindings, p[1], p[0].typ) return isGeneric @@ -716,6 +716,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = tyGenericInst, tyGenericParam} + tyTypeClasses: return typeRel(c, f, lastSon(a)) + if a.isResolvedUserTypeClass: + return typeRel(c, f, a.lastSon) + template bindingRet(res) = if doBind: let bound = aOrig.skipTypes({tyRange}).skipIntLit @@ -1125,12 +1128,20 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: return isNone - of tyUserTypeClass, tyUserTypeClassInst: + of tyUserTypeClass: considerPreviousT: result = matchUserTypeClass(c.c, c, f, aOrig) if result == isGeneric: put(c, f, a) + of tyUserTypeClassInst: + considerPreviousT: + result = matchUserTypeClass(c.c, c, f, aOrig) + if result == isGeneric: + var fWithResolvedParams = generateTypeInstance(c.c, c.bindings, c.call.info, f) + fWithResolvedParams.sons.add a + put(c.bindings, f, fWithResolvedParams) + of tyCompositeTypeClass: considerPreviousT: let roota = a.skipGenericAlias @@ -1397,7 +1408,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, arg = argSemantized argType = argType c = m.c - + if inferTypeClassParam(c, f, argType): return argSemantized diff --git a/compiler/types.nim b/compiler/types.nim index f4ef75094..285854aa0 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1485,6 +1485,9 @@ proc isEmptyContainer*(t: PType): bool = of tyGenericInst, tyAlias: result = isEmptyContainer(t.lastSon) else: result = false +proc isResolvedUserTypeClass*(t: PType): bool = + t.kind in {tyUserTypeClassInst} and t.base.sonsLen == t.sonsLen - 2 + proc takeType*(formal, arg: PType): PType = # param: openArray[string] = [] # [] is an array constructor of length 0 of type string! diff --git a/tests/concepts/tstackconcept.nim b/tests/concepts/tstackconcept.nim index 3993ca534..dc75df5ff 100644 --- a/tests/concepts/tstackconcept.nim +++ b/tests/concepts/tstackconcept.nim @@ -2,6 +2,7 @@ discard """ output: "20\n10" msg: ''' INFERRED int +IMPLICIT INFERRED int int ''' """ @@ -32,7 +33,7 @@ proc genericAlgorithm[T](s: var Stack[T], y: T) = echo s.pop proc implicitGeneric(s: var Stack): auto = - # static: echo "IMPLICIT INFERRED ", s.T.name, " ", Stack.T.name + static: echo "IMPLICIT INFERRED ", s.T.name, " ", Stack.T.name return s.pop() |