mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
* 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:
@@ -591,6 +591,7 @@ type
|
||||
tfEffectSystemWorkaround
|
||||
tfIsOutParam
|
||||
tfSendable
|
||||
tfImplicitStatic
|
||||
|
||||
TTypeFlags* = set[TTypeFlag]
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
9
tests/generics/t12938.nim
Normal file
9
tests/generics/t12938.nim
Normal 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
|
||||
6
tests/generics/t14193.nim
Normal file
6
tests/generics/t14193.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
type
|
||||
Task*[N: int] = object
|
||||
env*: array[N, byte]
|
||||
|
||||
var task14193: Task[20]
|
||||
doAssert task14193.env.len == 20
|
||||
Reference in New Issue
Block a user