fix #12938 index type of array in type section without static (#20529)

* fix #12938 nim compiler assertion fail when literal integer is passed as template argument for array size

* use new flag tfImplicitStatic

* fix

* fix #14193

* correct tfUnresolved add condition

* clean test
This commit is contained in:
Bung
2023-08-09 18:45:43 +08:00
committed by GitHub
parent 5334dc921f
commit d53a89e453
4 changed files with 52 additions and 21 deletions

View File

@@ -591,6 +591,7 @@ type
tfEffectSystemWorkaround
tfIsOutParam
tfSendable
tfImplicitStatic
TTypeFlags* = set[TTypeFlag]

View File

@@ -335,6 +335,14 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType =
localError(c.config, n.info, errXExpectsOneTypeParam % "range")
result = newOrPrevType(tyError, prev, c)
proc semArrayIndexConst(c: PContext, e: PNode, info: TLineInfo): PType =
let x = semConstExpr(c, e)
if x.kind in {nkIntLit..nkUInt64Lit}:
result = makeRangeType(c, 0, x.intVal-1, info,
x.typ.skipTypes({tyTypeDesc}))
else:
result = x.typ.skipTypes({tyTypeDesc})
proc semArrayIndex(c: PContext, n: PNode): PType =
if isRange(n):
result = semRangeAux(c, n, nil)
@@ -351,14 +359,18 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
localError(c.config, n.info,
"Array length can't be negative, but was " & $e.intVal)
result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
elif e.kind == nkSym and e.typ.kind == tyStatic:
if e.sym.ast != nil:
return semArrayIndex(c, e.sym.ast)
if e.typ.lastSon.kind != tyGenericParam and not isOrdinalType(e.typ.lastSon):
let info = if n.safeLen > 1: n[1].info else: n.info
localError(c.config, info, errOrdinalTypeExpected % typeToString(e.typ, preferDesc))
result = makeRangeWithStaticExpr(c, e)
if c.inGenericContext > 0: result.flags.incl tfUnresolved
elif e.kind == nkSym and (e.typ.kind == tyStatic or e.typ.kind == tyTypeDesc) :
if e.typ.kind == tyStatic:
if e.sym.ast != nil:
return semArrayIndex(c, e.sym.ast)
if e.typ.lastSon.kind != tyGenericParam and not isOrdinalType(e.typ.lastSon):
let info = if n.safeLen > 1: n[1].info else: n.info
localError(c.config, info, errOrdinalTypeExpected % typeToString(e.typ, preferDesc))
result = makeRangeWithStaticExpr(c, e)
if c.inGenericContext > 0: result.flags.incl tfUnresolved
else:
result = e.typ.skipTypes({tyTypeDesc})
result.flags.incl tfImplicitStatic
elif e.kind in (nkCallKinds + {nkBracketExpr}) and hasUnresolvedArgs(c, e):
if not isOrdinalType(e.typ.skipTypes({tyStatic, tyAlias, tyGenericInst, tySink})):
localError(c.config, n[1].info, errOrdinalTypeExpected % typeToString(e.typ, preferDesc))
@@ -371,12 +383,7 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
elif e.kind == nkIdent:
result = e.typ.skipTypes({tyTypeDesc})
else:
let x = semConstExpr(c, e)
if x.kind in {nkIntLit..nkUInt64Lit}:
result = makeRangeType(c, 0, x.intVal-1, n.info,
x.typ.skipTypes({tyTypeDesc}))
else:
result = x.typ.skipTypes({tyTypeDesc})
result = semArrayIndexConst(c, e, n.info)
#localError(c.config, n[1].info, errConstExprExpected)
proc semArray(c: PContext, n: PNode, prev: PType): PType =
@@ -1504,20 +1511,24 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
var t = s.typ.skipTypes({tyAlias})
if t.kind == tyCompositeTypeClass and t.base.kind == tyGenericBody:
t = t.base
result = newOrPrevType(tyGenericInvocation, prev, c)
addSonSkipIntLit(result, t, c.idgen)
template addToResult(typ) =
template addToResult(typ, skip) =
if typ.isNil:
internalAssert c.config, false
rawAddSon(result, typ)
else: addSonSkipIntLit(result, typ, c.idgen)
else:
if skip:
addSonSkipIntLit(result, typ, c.idgen)
else:
rawAddSon(result, makeRangeWithStaticExpr(c, typ.n))
if t.kind == tyForward:
for i in 1..<n.len:
var elem = semGenericParamInInvocation(c, n[i])
addToResult(elem)
addToResult(elem, true)
return
elif t.kind != tyGenericBody:
# we likely got code of the form TypeA[TypeB] where TypeA is
@@ -1537,7 +1548,8 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
return newOrPrevType(tyError, prev, c)
var isConcrete = true
let rType = m.call[0].typ
let mIndex = if rType != nil: rType.len - 1 else: -1
for i in 1..<m.call.len:
var typ = m.call[i].typ
# is this a 'typedesc' *parameter*? If so, use the typedesc type,
@@ -1545,11 +1557,14 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
if m.call[i].kind == nkSym and m.call[i].sym.kind == skParam and
typ.kind == tyTypeDesc and containsGenericType(typ):
isConcrete = false
addToResult(typ)
addToResult(typ, true)
else:
typ = typ.skipTypes({tyTypeDesc})
if containsGenericType(typ): isConcrete = false
addToResult(typ)
var skip = true
if mIndex >= i - 1 and tfImplicitStatic in rType[i - 1].flags and isIntLit(typ):
skip = false
addToResult(typ, skip)
if isConcrete:
if s.ast == nil and s.typ.kind != tyCompositeTypeClass:

View File

@@ -0,0 +1,9 @@
type
ExampleArray[Size, T] = array[Size, T]
var integerArray: ExampleArray[32, int] # Compiler crash!
doAssert integerArray.len == 32
const Size = 2
var integerArray2: ExampleArray[Size, int]
doAssert integerArray2.len == 2

View File

@@ -0,0 +1,6 @@
type
Task*[N: int] = object
env*: array[N, byte]
var task14193: Task[20]
doAssert task14193.env.len == 20