pass-through of static int generic params to arrays when late instantiation is disabled

This commit is contained in:
Zahary Karadjov
2013-08-23 00:42:43 +03:00
parent fee2a7ecfa
commit 8682ed9bd0
8 changed files with 31 additions and 18 deletions

View File

@@ -905,8 +905,7 @@ proc evalParseStmt(c: PEvalContext, n: PNode): PNode =
#result.typ = newType(tyStmt, c.module)
proc evalTypeTrait*(trait, operand: PNode, context: PSym): PNode =
InternalAssert operand.kind == nkSym and
operand.sym.typ.kind == tyTypeDesc
InternalAssert operand.kind == nkSym
let typ = operand.sym.typ.skipTypes({tyTypeDesc})
case trait.sym.name.s.normalize

View File

@@ -156,7 +156,7 @@ var
const oKeepVariableNames* = true
const oUseLateInstantiation* = true
const oUseLateInstantiation* = false
proc mainCommandArg*: string =
## This is intended for commands like check or parse

View File

@@ -225,14 +225,14 @@ proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
dest.owner = getCurrOwner()
dest.size = - 1
proc makeRangeType*(c: PContext, first, last: biggestInt,
info: TLineInfo): PType =
proc makeRangeType*(c: PContext; first, last: biggestInt;
info: TLineInfo; intType = getSysType(tyInt)): PType =
var n = newNodeI(nkRange, info)
addSon(n, newIntNode(nkIntLit, first))
addSon(n, newIntNode(nkIntLit, last))
addSon(n, newIntTypeNode(nkIntLit, first, intType))
addSon(n, newIntTypeNode(nkIntLit, last, intType))
result = newTypeS(tyRange, c)
result.n = n
rawAddSon(result, getSysType(tyInt)) # basetype of range
addSonSkipIntLit(result, intType) # basetype of range
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
if s.kind in {skProc, skConverter, skMethod, skIterator}:

View File

@@ -113,7 +113,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
of skGenericParam:
if s.typ.kind == tyExpr:
result = newSymNode(s, n.info)
result.typ = s.typ.lastSon
result.typ = s.typ
elif s.ast != nil:
result = semExpr(c, s.ast)
else:

View File

@@ -195,16 +195,18 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
else:
let e = semExprWithType(c, n.sons[1], {efDetermineType})
if e.kind in {nkIntLit..nkUInt64Lit}:
indx = newTypeS(tyRange, c)
indx.n = newNodeI(nkRange, n.info)
addSon(indx.n, newIntTypeNode(e.kind, 0, e.typ))
addSon(indx.n, newIntTypeNode(e.kind, e.intVal-1, e.typ))
addSonSkipIntLit(indx, e.typ)
indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
elif e.kind == nkSym and e.typ.kind == tyExpr:
if e.sym.ast != nil: return semArray(c, e.sym.ast, nil)
InternalAssert c.InGenericContext > 0
if not isOrdinalType(e.typ.lastSon):
localError(n[1].info, errOrdinalTypeExpected)
indx = e.typ
else:
indx = e.typ.skipTypes({tyTypeDesc})
addSonSkipIntLit(result, indx)
if indx.kind == tyGenericInst: indx = lastSon(indx)
if indx.kind != tyGenericParam:
if indx.kind notin {tyGenericParam, tyExpr}:
if not isOrdinalType(indx):
LocalError(n.sons[1].info, errOrdinalTypeExpected)
elif enumHasHoles(indx):

View File

@@ -208,6 +208,12 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
of tyInt:
result = skipIntLit(t)
else:
if t.kind == tyArray:
let idxt = t.sons[0]
if idxt.kind == tyExpr and
idxt.sym != nil and idxt.sym.kind == skGenericParam:
let value = lookupTypeVar(cl, idxt).n
t.sons[0] = makeRangeType(cl.c, 0, value.intVal - 1, value.info)
if containsGenericType(t):
result = copyType(t, t.owner, false)
incl(result.flags, tfFromGeneric)

View File

@@ -622,7 +622,8 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
of tyGenericParam, tyTypeClass:
var x = PType(idTableGet(c.bindings, f))
if x == nil:
if c.calleeSym.kind == skType and f.kind == tyGenericParam and not c.typedescMatched:
if c.calleeSym != nil and c.calleeSym.kind == skType and
f.kind == tyGenericParam and not c.typedescMatched:
# XXX: The fact that generic types currently use tyGenericParam for
# their parameters is really a misnomer. tyGenericParam means "match
# any value" and what we need is "match any type", which can be encoded

View File

@@ -1,17 +1,22 @@
discard """
file: "tstaticparams.nim"
output: "abracadabra\ntest"
output: "abracadabra\ntest\n3"
"""
type
TFoo[T; Val: expr[string]] = object
data: array[4, T]
TBar[T; I: expr[int]] = object
data: array[I, T]
proc takeFoo(x: TFoo) =
echo "abracadabra"
echo TFoo.Val
var x: TFoo[int, "test"]
takeFoo(x)
var y: TBar[float, 4]
echo high(y.data)