diff options
-rw-r--r-- | compiler/evals.nim | 3 | ||||
-rw-r--r-- | compiler/options.nim | 2 | ||||
-rw-r--r-- | compiler/semdata.nim | 10 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 14 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 6 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 3 | ||||
-rw-r--r-- | tests/run/tstaticparams.nim | 9 |
8 files changed, 31 insertions, 18 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim index 35954ccec..053068ea4 100644 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -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 diff --git a/compiler/options.nim b/compiler/options.nim index cfda15f6a..2b25b2650 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -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 diff --git a/compiler/semdata.nim b/compiler/semdata.nim index b9c32a680..8b04f4af5 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -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}: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d88cc28b6..ebda31501 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 1f7574bb5..e5d9058b4 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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): diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 5482d5df8..0c15c7248 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index fa87f27a7..4483b1f8b 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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 diff --git a/tests/run/tstaticparams.nim b/tests/run/tstaticparams.nim index 3e501ed8b..232748356 100644 --- a/tests/run/tstaticparams.nim +++ b/tests/run/tstaticparams.nim @@ -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) + |