mirror of
https://github.com/nim-lang/Nim.git
synced 2026-03-04 07:37:14 +00:00
pass-through of static int generic params to arrays when late instantiation is disabled
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user