support for accessing the inferred concept type params with the dot operator
This commit is contained in:
parent
66e0f0e19c
commit
eab1d0cc02
6 changed files with 24 additions and 7 deletions
|
|
@ -101,6 +101,8 @@ proc getUniqueType*(key: PType): PType =
|
||||||
gCanonicalTypes[k] = key
|
gCanonicalTypes[k] = key
|
||||||
result = key
|
result = key
|
||||||
of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr, tyFieldAccessor:
|
of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr, tyFieldAccessor:
|
||||||
|
if key.isResolvedUserTypeClass:
|
||||||
|
return getUniqueType(lastSon(key))
|
||||||
if key.sym != nil:
|
if key.sym != nil:
|
||||||
internalError(key.sym.info, "metatype not eliminated")
|
internalError(key.sym.info, "metatype not eliminated")
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -909,12 +909,12 @@ proc makeDeref(n: PNode): PNode =
|
||||||
t = skipTypes(baseTyp, {tyGenericInst, tyAlias})
|
t = skipTypes(baseTyp, {tyGenericInst, tyAlias})
|
||||||
|
|
||||||
const
|
const
|
||||||
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
|
tyTypeParamsHolders = {tyGenericInst, tyUserTypeClassInst, tyCompositeTypeClass}
|
||||||
tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias}
|
tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias}
|
||||||
|
|
||||||
proc readTypeParameter(c: PContext, typ: PType,
|
proc readTypeParameter(c: PContext, typ: PType,
|
||||||
paramName: PIdent, info: TLineInfo): PNode =
|
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);
|
else: (internalAssert(typ.kind == tyCompositeTypeClass);
|
||||||
typ.sons[1].skipGenericAlias)
|
typ.sons[1].skipGenericAlias)
|
||||||
let tbody = ty.sons[0]
|
let tbody = ty.sons[0]
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||||
of tyUserTypeClass:
|
of tyUserTypeClass:
|
||||||
result = t
|
result = t
|
||||||
|
|
||||||
of tyGenericInst:
|
of tyGenericInst, tyUserTypeClassInst:
|
||||||
bailout()
|
bailout()
|
||||||
result = instCopyType(cl, t)
|
result = instCopyType(cl, t)
|
||||||
idTablePut(cl.localCache, t, result)
|
idTablePut(cl.localCache, t, result)
|
||||||
|
|
|
||||||
|
|
@ -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
|
# 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
|
# to be resolvable while matching the rest of the parameters
|
||||||
for p in typeParams:
|
for p in typeParams:
|
||||||
put(m.bindings, p[0].typ, p[1])
|
put(m.bindings, p[1], p[0].typ)
|
||||||
|
|
||||||
return isGeneric
|
return isGeneric
|
||||||
|
|
||||||
|
|
@ -716,6 +716,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
tyGenericInst, tyGenericParam} + tyTypeClasses:
|
tyGenericInst, tyGenericParam} + tyTypeClasses:
|
||||||
return typeRel(c, f, lastSon(a))
|
return typeRel(c, f, lastSon(a))
|
||||||
|
|
||||||
|
if a.isResolvedUserTypeClass:
|
||||||
|
return typeRel(c, f, a.lastSon)
|
||||||
|
|
||||||
template bindingRet(res) =
|
template bindingRet(res) =
|
||||||
if doBind:
|
if doBind:
|
||||||
let bound = aOrig.skipTypes({tyRange}).skipIntLit
|
let bound = aOrig.skipTypes({tyRange}).skipIntLit
|
||||||
|
|
@ -1125,12 +1128,20 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
else:
|
else:
|
||||||
return isNone
|
return isNone
|
||||||
|
|
||||||
of tyUserTypeClass, tyUserTypeClassInst:
|
of tyUserTypeClass:
|
||||||
considerPreviousT:
|
considerPreviousT:
|
||||||
result = matchUserTypeClass(c.c, c, f, aOrig)
|
result = matchUserTypeClass(c.c, c, f, aOrig)
|
||||||
if result == isGeneric:
|
if result == isGeneric:
|
||||||
put(c, f, a)
|
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:
|
of tyCompositeTypeClass:
|
||||||
considerPreviousT:
|
considerPreviousT:
|
||||||
let roota = a.skipGenericAlias
|
let roota = a.skipGenericAlias
|
||||||
|
|
|
||||||
|
|
@ -1485,6 +1485,9 @@ proc isEmptyContainer*(t: PType): bool =
|
||||||
of tyGenericInst, tyAlias: result = isEmptyContainer(t.lastSon)
|
of tyGenericInst, tyAlias: result = isEmptyContainer(t.lastSon)
|
||||||
else: result = false
|
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 =
|
proc takeType*(formal, arg: PType): PType =
|
||||||
# param: openArray[string] = []
|
# param: openArray[string] = []
|
||||||
# [] is an array constructor of length 0 of type string!
|
# [] is an array constructor of length 0 of type string!
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ discard """
|
||||||
output: "20\n10"
|
output: "20\n10"
|
||||||
msg: '''
|
msg: '''
|
||||||
INFERRED int
|
INFERRED int
|
||||||
|
IMPLICIT INFERRED int int
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -32,7 +33,7 @@ proc genericAlgorithm[T](s: var Stack[T], y: T) =
|
||||||
echo s.pop
|
echo s.pop
|
||||||
|
|
||||||
proc implicitGeneric(s: var Stack): auto =
|
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()
|
return s.pop()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue