mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-22 07:15:22 +00:00
NIR: progress (#22817)
Done: - [x] Implement conversions to openArray/varargs. - [x] Implement index/range checking.
This commit is contained in:
@@ -45,6 +45,7 @@ type
|
||||
locGen: int
|
||||
m: ModuleCon
|
||||
prc: PSym
|
||||
options: TOptions
|
||||
|
||||
proc initModuleCon*(graph: ModuleGraph; config: ConfigRef; idgen: IdGenerator; module: PSym): ModuleCon =
|
||||
result = ModuleCon(graph: graph, types: initTypesCon(config), slotGenerator: new(int),
|
||||
@@ -61,7 +62,9 @@ proc initModuleCon*(graph: ModuleGraph; config: ConfigRef; idgen: IdGenerator; m
|
||||
result.nativeUIntId = UInt16Id
|
||||
|
||||
proc initProcCon*(m: ModuleCon; prc: PSym; config: ConfigRef): ProcCon =
|
||||
ProcCon(m: m, sm: initSlotManager({}, m.slotGenerator), prc: prc, config: config)
|
||||
ProcCon(m: m, sm: initSlotManager({}, m.slotGenerator), prc: prc, config: config,
|
||||
options: if prc != nil: prc.options
|
||||
else: config.options)
|
||||
|
||||
proc toLineInfo(c: var ProcCon; i: TLineInfo): PackedLineInfo =
|
||||
var val: LitId
|
||||
@@ -476,14 +479,21 @@ proc genField(c: var ProcCon; n: PNode; d: var Value) =
|
||||
d.addImmediateVal toLineInfo(c, n.info), pos
|
||||
|
||||
proc genIndex(c: var ProcCon; n: PNode; arr: PType; d: var Value) =
|
||||
let info = toLineInfo(c, n.info)
|
||||
if arr.skipTypes(abstractInst).kind == tyArray and
|
||||
(let x = firstOrd(c.config, arr); x != Zero):
|
||||
let info = toLineInfo(c, n.info)
|
||||
buildTyped d, info, Sub, c.m.nativeIntId:
|
||||
c.gen(n, d)
|
||||
d.addImmediateVal toLineInfo(c, n.info), toInt(x)
|
||||
else:
|
||||
c.gen(n, d)
|
||||
if optBoundsCheck in c.options:
|
||||
let idx = move d
|
||||
build d, info, CheckedIndex:
|
||||
copyTree d.Tree, idx
|
||||
let x = toInt64 lengthOrd(c.config, arr)
|
||||
d.Tree.addIntVal c.m.integers, info, c.m.nativeIntId, x
|
||||
d.Tree.addLabel info, CheckedGoto, c.exitLabel
|
||||
|
||||
proc genNew(c: var ProcCon; n: PNode; needsInit: bool) =
|
||||
# If in doubt, always follow the blueprint of the C code generator for `mm:orc`.
|
||||
@@ -586,6 +596,8 @@ proc genBinaryOp(c: var ProcCon; n: PNode; d: var Value; opc: Opcode) =
|
||||
let t = typeToIr(c.m.types, n.typ)
|
||||
template body(target) =
|
||||
buildTyped target, info, opc, t:
|
||||
if optOverflowCheck in c.options and opc in {CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedMod}:
|
||||
c.code.addLabel info, CheckedGoto, c.exitLabel
|
||||
copyTree target, tmp
|
||||
copyTree target, tmp2
|
||||
intoDest d, info, t, body
|
||||
@@ -688,10 +700,16 @@ proc genUnaryMinus(c: var ProcCon; n: PNode; d: var Value) =
|
||||
c.freeTemp(tmp)
|
||||
|
||||
proc genHigh(c: var ProcCon; n: PNode; d: var Value) =
|
||||
let subOpr = createMagic(c.m.graph, c.m.idgen, "-", mSubI)
|
||||
let lenOpr = createMagic(c.m.graph, c.m.idgen, "len", mLengthOpenArray)
|
||||
let asLenExpr = subOpr.buildCall(lenOpr.buildCall(n[1]), nkIntLit.newIntNode(1))
|
||||
c.gen asLenExpr, d
|
||||
let info = toLineInfo(c, n.info)
|
||||
let t = typeToIr(c.m.types, n.typ)
|
||||
var x = default(Value)
|
||||
genArrayLen(c, n, x)
|
||||
template body(target) =
|
||||
buildTyped target, info, Sub, t:
|
||||
copyTree target, x
|
||||
target.addIntVal(c.m.integers, info, t, 1)
|
||||
intoDest d, info, t, body
|
||||
c.freeTemp x
|
||||
|
||||
proc genBinaryCp(c: var ProcCon; n: PNode; d: var Value; compilerProc: string) =
|
||||
let info = toLineInfo(c, n.info)
|
||||
@@ -1365,6 +1383,81 @@ proc genDefault(c: var ProcCon; n: PNode; d: var Value) =
|
||||
let m = expandDefault(n.typ, n.info)
|
||||
gen c, m, d
|
||||
|
||||
proc genWasMoved(c: var ProcCon; n: PNode) =
|
||||
let n1 = n[1].skipAddr
|
||||
# XXX We need a way to replicate this logic or better yet a better
|
||||
# solution for injectdestructors.nim:
|
||||
#if c.withinBlockLeaveActions > 0 and notYetAlive(n1):
|
||||
var d = c.genx(n1)
|
||||
assert not isEmpty(d)
|
||||
let m = expandDefault(n1.typ, n1.info)
|
||||
gen c, m, d
|
||||
|
||||
proc genMove(c: var ProcCon; n: PNode; d: var Value) =
|
||||
let info = toLineInfo(c, n.info)
|
||||
let n1 = n[1].skipAddr
|
||||
var a = c.genx(n1)
|
||||
if n.len == 4:
|
||||
# generated by liftdestructors:
|
||||
let src = c.genx(n[2])
|
||||
# if ($1.p == $2.p) goto lab1
|
||||
let lab1 = newLabel(c.labelGen)
|
||||
|
||||
let payloadType = seqPayloadPtrType(c.m.types, n1.typ)
|
||||
buildTyped c.code, info, Select, Bool8Id:
|
||||
buildTyped c.code, info, Eq, payloadType:
|
||||
buildTyped c.code, info, FieldAt, payloadType:
|
||||
copyTree c.code, a
|
||||
c.code.addImmediateVal info, 1 # (len, p)-pair
|
||||
buildTyped c.code, info, FieldAt, payloadType:
|
||||
copyTree c.code, src
|
||||
c.code.addImmediateVal info, 1 # (len, p)-pair
|
||||
|
||||
build c.code, info, SelectPair:
|
||||
build c.code, info, SelectValue:
|
||||
c.code.boolVal(info, true)
|
||||
c.code.gotoLabel info, Goto, lab1
|
||||
|
||||
gen(c, n[3])
|
||||
c.patch n, lab1
|
||||
|
||||
buildTyped c.code, info, Asgn, typeToIr(c.m.types, n1.typ):
|
||||
copyTree c.code, a
|
||||
copyTree c.code, src
|
||||
|
||||
else:
|
||||
if isEmpty(d): d = getTemp(c, n)
|
||||
buildTyped c.code, info, Asgn, typeToIr(c.m.types, n1.typ):
|
||||
copyTree c.code, d
|
||||
copyTree c.code, a
|
||||
var op = getAttachedOp(c.m.graph, n.typ, attachedWasMoved)
|
||||
if op == nil or skipTypes(n1.typ, abstractVar+{tyStatic}).kind in {tyOpenArray, tyVarargs}:
|
||||
let m = expandDefault(n1.typ, n1.info)
|
||||
gen c, m, a
|
||||
else:
|
||||
var opB = c.genx(newSymNode(op))
|
||||
buildTyped c.code, info, Call, typeToIr(c.m.types, n.typ):
|
||||
copyTree c.code, opB
|
||||
buildTyped c.code, info, AddrOf, ptrTypeOf(c.m.types.g, typeToIr(c.m.types, n1.typ)):
|
||||
copyTree c.code, a
|
||||
|
||||
proc genDestroy(c: var ProcCon; n: PNode) =
|
||||
let t = n[1].typ.skipTypes(abstractInst)
|
||||
case t.kind
|
||||
of tyString:
|
||||
var unused = default(Value)
|
||||
genUnaryCp(c, n, unused, "nimDestroyStrV1")
|
||||
of tySequence:
|
||||
#[
|
||||
var a = initLocExpr(c, arg)
|
||||
linefmt(c, cpsStmts, "if ($1.p && ($1.p->cap & NIM_STRLIT_FLAG) == 0) {$n" &
|
||||
" #alignedDealloc($1.p, NIM_ALIGNOF($2));$n" &
|
||||
"}$n",
|
||||
[rdLoc(a), getTypeDesc(c.module, t.lastSon)])
|
||||
]#
|
||||
globalError(c.config, n.info, "not implemented: =destroy for seqs")
|
||||
else: discard "nothing to do"
|
||||
|
||||
proc genMagic(c: var ProcCon; n: PNode; d: var Value; m: TMagic) =
|
||||
case m
|
||||
of mAnd: c.genAndOr(n, opcFJmp, d)
|
||||
@@ -1391,9 +1484,9 @@ proc genMagic(c: var ProcCon; n: PNode; d: var Value; m: TMagic) =
|
||||
of mNewString, mNewStringOfCap, mExit: c.genCall(n, d)
|
||||
of mLengthOpenArray, mLengthArray, mLengthSeq, mLengthStr:
|
||||
genArrayLen(c, n, d)
|
||||
of mMulI: genBinaryOp(c, n, d, Mul)
|
||||
of mDivI: genBinaryOp(c, n, d, Div)
|
||||
of mModI: genBinaryOp(c, n, d, Mod)
|
||||
of mMulI: genBinaryOp(c, n, d, CheckedMul)
|
||||
of mDivI: genBinaryOp(c, n, d, CheckedDiv)
|
||||
of mModI: genBinaryOp(c, n, d, CheckedMod)
|
||||
of mAddF64: genBinaryOp(c, n, d, Add)
|
||||
of mSubF64: genBinaryOp(c, n, d, Sub)
|
||||
of mMulF64: genBinaryOp(c, n, d, Mul)
|
||||
@@ -1495,7 +1588,6 @@ proc genMagic(c: var ProcCon; n: PNode; d: var Value; m: TMagic) =
|
||||
localError(c.config, n.info, sizeOfLikeMsg("offsetof"))
|
||||
of mRunnableExamples:
|
||||
discard "just ignore any call to runnableExamples"
|
||||
of mDestroy, mTrace: discard "ignore calls to the default destructor"
|
||||
of mOf: genOf(c, n, d)
|
||||
of mAppendStrStr:
|
||||
unused(c, n, d)
|
||||
@@ -1522,49 +1614,23 @@ proc genMagic(c: var ProcCon; n: PNode; d: var Value; m: TMagic) =
|
||||
of mConStrStr: genStrConcat(c, n, d)
|
||||
of mDefault, mZeroDefault:
|
||||
genDefault c, n, d
|
||||
of mMove: genMove(c, n, d)
|
||||
of mWasMoved, mReset:
|
||||
unused(c, n, d)
|
||||
genWasMoved(c, n)
|
||||
of mDestroy: genDestroy(c, n)
|
||||
#of mAccessEnv: unaryExpr(d, n, d, "$1.ClE_0")
|
||||
#of mAccessTypeField: genAccessTypeField(c, n, d)
|
||||
#of mSlice: genSlice(c, n, d)
|
||||
of mTrace: discard "no code to generate"
|
||||
else:
|
||||
# mGCref, mGCunref,
|
||||
# mGCref, mGCunref: unused by ORC
|
||||
globalError(c.config, n.info, "cannot generate code for: " & $m)
|
||||
|
||||
#[
|
||||
|
||||
of mReset:
|
||||
unused(c, n, d)
|
||||
var d = c.genx(n[1])
|
||||
# XXX use ldNullOpcode() here?
|
||||
c.gABx(n, opcLdNull, d, c.genType(n[1].typ))
|
||||
c.gABC(n, opcNodeToReg, d, d)
|
||||
c.gABx(n, ldNullOpcode(n.typ), d, c.genType(n.typ))
|
||||
|
||||
of mConStrStr: genVarargsABC(c, n, d, opcConcatStr)
|
||||
|
||||
of mRepr: genUnaryABC(c, n, d, opcRepr)
|
||||
|
||||
of mSlice:
|
||||
var
|
||||
d = c.genx(n[1])
|
||||
left = c.genIndex(n[2], n[1].typ)
|
||||
right = c.genIndex(n[3], n[1].typ)
|
||||
if isEmpty(d): d = c.getTemp(n)
|
||||
c.gABC(n, opcNodeToReg, d, d)
|
||||
c.gABC(n, opcSlice, d, left, right)
|
||||
c.freeTemp(left)
|
||||
c.freeTemp(right)
|
||||
c.freeTemp(d)
|
||||
|
||||
of mMove:
|
||||
let arg = n[1]
|
||||
let a = c.genx(arg)
|
||||
if isEmpty(d): d = c.getTemp(arg)
|
||||
gABC(c, arg, whichAsgnOpc(arg, requiresCopy=false), d, a)
|
||||
c.freeTemp(a)
|
||||
of mDup:
|
||||
let arg = n[1]
|
||||
let a = c.genx(arg)
|
||||
if isEmpty(d): d = c.getTemp(arg)
|
||||
gABC(c, arg, whichAsgnOpc(arg, requiresCopy=false), d, a)
|
||||
c.freeTemp(a)
|
||||
|
||||
of mNodeId:
|
||||
c.genUnaryABC(n, d, opcNodeId)
|
||||
|
||||
@@ -1764,6 +1830,63 @@ proc genDeref(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags) =
|
||||
valueIntoDest c, info, d, n.typ, body
|
||||
freeTemp c, tmp
|
||||
|
||||
proc addAddrOfFirstElem(c: var ProcCon; target: var Tree; info: PackedLineInfo; tmp: Value; typ: PType) =
|
||||
let arrType = typ.skipTypes(abstractVar)
|
||||
let elemType = arrayPtrTypeOf(c.m.types.g, typeToIr(c.m.types, arrType.lastSon))
|
||||
case arrType.kind
|
||||
of tyString:
|
||||
let t = typeToIr(c.m.types, typ.lastSon)
|
||||
target.addImmediateVal info, 0
|
||||
buildTyped target, info, AddrOf, elemType:
|
||||
buildTyped target, info, ArrayAt, t:
|
||||
buildTyped target, info, FieldAt, strPayloadPtrType(c.m.types):
|
||||
copyTree target, tmp
|
||||
target.addImmediateVal info, 1 # (len, p)-pair
|
||||
target.addIntVal c.m.integers, info, c.m.nativeIntId, 0
|
||||
# len:
|
||||
target.addImmediateVal info, 1
|
||||
buildTyped target, info, FieldAt, c.m.nativeIntId:
|
||||
copyTree target, tmp
|
||||
target.addImmediateVal info, 0 # (len, p)-pair so len is at index 0
|
||||
|
||||
of tySequence:
|
||||
let t = typeToIr(c.m.types, typ.lastSon)
|
||||
target.addImmediateVal info, 0
|
||||
buildTyped target, info, AddrOf, elemType:
|
||||
buildTyped target, info, ArrayAt, t:
|
||||
buildTyped target, info, FieldAt, seqPayloadPtrType(c.m.types, typ):
|
||||
copyTree target, tmp
|
||||
target.addImmediateVal info, 1 # (len, p)-pair
|
||||
target.addIntVal c.m.integers, info, c.m.nativeIntId, 0
|
||||
# len:
|
||||
target.addImmediateVal info, 1
|
||||
buildTyped target, info, FieldAt, c.m.nativeIntId:
|
||||
copyTree target, tmp
|
||||
target.addImmediateVal info, 0 # (len, p)-pair so len is at index 0
|
||||
|
||||
of tyArray:
|
||||
let t = typeToIr(c.m.types, typ.lastSon)
|
||||
target.addImmediateVal info, 0
|
||||
buildTyped target, info, AddrOf, elemType:
|
||||
buildTyped target, info, ArrayAt, t:
|
||||
copyTree target, tmp
|
||||
target.addIntVal c.m.integers, info, c.m.nativeIntId, 0
|
||||
target.addImmediateVal info, 1
|
||||
target.addIntVal(c.m.integers, info, c.m.nativeIntId, toInt lengthOrd(c.config, typ))
|
||||
else:
|
||||
raiseAssert "addAddrOfFirstElem: " & typeToString(typ)
|
||||
|
||||
proc genToOpenArrayConv(c: var ProcCon; arg: PNode; d: var Value; flags: GenFlags; destType: PType) =
|
||||
let info = toLineInfo(c, arg.info)
|
||||
let tmp = c.genx(arg, flags)
|
||||
let arrType = destType.skipTypes(abstractVar)
|
||||
template body(target) =
|
||||
buildTyped target, info, ObjConstr, typeToIr(c.m.types, arrType):
|
||||
c.addAddrOfFirstElem target, info, tmp, arg.typ
|
||||
|
||||
valueIntoDest c, info, d, arrType, body
|
||||
freeTemp c, tmp
|
||||
|
||||
proc genConv(c: var ProcCon; n, arg: PNode; d: var Value; flags: GenFlags; opc: Opcode) =
|
||||
let targetType = n.typ.skipTypes({tyDistinct})
|
||||
let argType = arg.typ.skipTypes({tyDistinct})
|
||||
@@ -1774,6 +1897,11 @@ proc genConv(c: var ProcCon; n, arg: PNode; d: var Value; flags: GenFlags; opc:
|
||||
gen c, arg, d
|
||||
return
|
||||
|
||||
if opc != Cast and targetType.skipTypes({tyVar, tyLent}).kind in {tyOpenArray, tyVarargs} and
|
||||
argType.skipTypes({tyVar, tyLent}).kind notin {tyOpenArray, tyVarargs}:
|
||||
genToOpenArrayConv c, arg, d, flags, n.typ
|
||||
return
|
||||
|
||||
let info = toLineInfo(c, n.info)
|
||||
let tmp = c.genx(arg, flags)
|
||||
template body(target) =
|
||||
@@ -1850,7 +1978,7 @@ proc genVarSection(c: var ProcCon; n: PNode) =
|
||||
genAsgn2(c, vn, a[2])
|
||||
else:
|
||||
if a[2].kind == nkEmpty:
|
||||
discard "XXX assign default value to location here"
|
||||
genAsgn2(c, vn, expandDefault(vn.typ, vn.info))
|
||||
else:
|
||||
genAsgn2(c, vn, a[2])
|
||||
|
||||
@@ -1922,17 +2050,56 @@ proc genNilLit(c: var ProcCon; n: PNode; d: var Value) =
|
||||
valueIntoDest c, info, d, n.typ, body
|
||||
|
||||
proc genRangeCheck(c: var ProcCon; n: PNode; d: var Value) =
|
||||
# XXX to implement properly
|
||||
gen c, n[0], d
|
||||
if optRangeCheck in c.options:
|
||||
let info = toLineInfo(c, n.info)
|
||||
let tmp = c.genx n[0]
|
||||
let a = c.genx n[1]
|
||||
let b = c.genx n[2]
|
||||
template body(target) =
|
||||
buildTyped target, info, CheckedRange, typeToIr(c.m.types, n.typ):
|
||||
copyTree target, tmp
|
||||
copyTree target, a
|
||||
copyTree target, b
|
||||
target.addLabel info, CheckedGoto, c.exitLabel
|
||||
valueIntoDest c, info, d, n.typ, body
|
||||
freeTemp c, tmp
|
||||
freeTemp c, a
|
||||
freeTemp c, b
|
||||
else:
|
||||
gen c, n[0], d
|
||||
|
||||
type
|
||||
IndexFor = enum
|
||||
ForSeq, ForStr, ForOpenArray
|
||||
|
||||
proc genIndexCheck(c: var ProcCon; n: PNode; a: Value; kind: IndexFor): Value =
|
||||
if optBoundsCheck in c.options:
|
||||
let info = toLineInfo(c, n.info)
|
||||
result = default(Value)
|
||||
let idx = genx(c, n)
|
||||
build result, info, CheckedIndex:
|
||||
copyTree result.Tree, idx
|
||||
case kind
|
||||
of ForSeq, ForStr:
|
||||
buildTyped result, info, FieldAt, c.m.nativeIntId:
|
||||
copyTree result.Tree, a
|
||||
result.addImmediateVal info, 0 # (len, p)-pair
|
||||
of ForOpenArray:
|
||||
buildTyped result, info, FieldAt, c.m.nativeIntId:
|
||||
copyTree result.Tree, a
|
||||
result.addImmediateVal info, 1 # (p, len)-pair
|
||||
result.Tree.addLabel info, CheckedGoto, c.exitLabel
|
||||
freeTemp c, idx
|
||||
else:
|
||||
result = genx(c, n)
|
||||
|
||||
proc genArrAccess(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags) =
|
||||
let arrayKind = n[0].typ.skipTypes(abstractVarRange-{tyTypeDesc}).kind
|
||||
let info = toLineInfo(c, n.info)
|
||||
case arrayKind
|
||||
of tyString:
|
||||
# XXX implement range check
|
||||
let a = genx(c, n[0], flags)
|
||||
let b = genx(c, n[1])
|
||||
let b = genIndexCheck(c, n[1], a, ForStr)
|
||||
let t = typeToIr(c.m.types, n.typ)
|
||||
template body(target) =
|
||||
buildTyped target, info, ArrayAt, t:
|
||||
@@ -1966,9 +2133,8 @@ proc genArrAccess(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags) =
|
||||
|
||||
freeTemp c, a
|
||||
of tyOpenArray, tyVarargs:
|
||||
# XXX implement range check
|
||||
let a = genx(c, n[0], flags)
|
||||
let b = genx(c, n[1])
|
||||
let b = genIndexCheck(c, n[1], a, ForOpenArray)
|
||||
let t = typeToIr(c.m.types, n.typ)
|
||||
template body(target) =
|
||||
buildTyped target, info, ArrayAt, t:
|
||||
@@ -1981,7 +2147,6 @@ proc genArrAccess(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags) =
|
||||
freeTemp c, b
|
||||
freeTemp c, a
|
||||
of tyArray:
|
||||
# XXX implement range check
|
||||
let a = genx(c, n[0], flags)
|
||||
var b = default(Value)
|
||||
genIndex(c, n[1], n[0].typ, b)
|
||||
@@ -1995,7 +2160,7 @@ proc genArrAccess(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags) =
|
||||
freeTemp c, a
|
||||
of tySequence:
|
||||
let a = genx(c, n[0], flags)
|
||||
let b = genx(c, n[1])
|
||||
let b = genIndexCheck(c, n[1], a, ForSeq)
|
||||
let t = typeToIr(c.m.types, n.typ)
|
||||
template body(target) =
|
||||
buildTyped target, info, ArrayAt, t:
|
||||
@@ -2047,7 +2212,7 @@ proc genProc(cOuter: var ProcCon; n: PNode) =
|
||||
var c = initProcCon(cOuter.m, prc, cOuter.m.graph.config)
|
||||
genParams(c, prc.typ.n)
|
||||
|
||||
let body = transformBody(c.m.graph, c.m.idgen, prc, useCache)
|
||||
let body = transformBody(c.m.graph, c.m.idgen, prc, {useCache, keepOpenArrayConversions})
|
||||
|
||||
let info = toLineInfo(c, body.info)
|
||||
build c.code, info, ProcDecl:
|
||||
|
||||
@@ -66,6 +66,9 @@ type
|
||||
SetExc,
|
||||
TestExc,
|
||||
|
||||
CheckedRange,
|
||||
CheckedIndex,
|
||||
|
||||
Call,
|
||||
IndirectCall,
|
||||
CheckedCall, # call that can raise
|
||||
|
||||
@@ -239,6 +239,11 @@ proc ptrTypeOf*(g: var TypeGraph; t: TypeId): TypeId =
|
||||
g.addType t
|
||||
result = sealType(g, f)
|
||||
|
||||
proc arrayPtrTypeOf*(g: var TypeGraph; t: TypeId): TypeId =
|
||||
let f = g.openType AArrayPtrTy
|
||||
g.addType t
|
||||
result = sealType(g, f)
|
||||
|
||||
proc toString*(dest: var string; g: TypeGraph; i: TypeId) =
|
||||
case g[i].kind
|
||||
of VoidTy: dest.add "void"
|
||||
|
||||
@@ -459,7 +459,11 @@ proc typeToIr*(c: var TypesCon; t: PType): TypeId =
|
||||
let a = openType(c.g, LastArrayTy)
|
||||
c.g.addType(elemType)
|
||||
result = sealType(c.g, a)
|
||||
of tyNone, tyEmpty, tyUntyped, tyTyped, tyTypeDesc,
|
||||
of tyUntyped, tyTyped:
|
||||
# this avoids a special case for system.echo which is not a generic but
|
||||
# uses `varargs[typed]`:
|
||||
result = VoidId
|
||||
of tyNone, tyEmpty, tyTypeDesc,
|
||||
tyNil, tyGenericInvocation, tyProxy, tyBuiltInTypeClass,
|
||||
tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass,
|
||||
tyAnd, tyOr, tyNot, tyAnything, tyConcept, tyIterable, tyForward:
|
||||
|
||||
Reference in New Issue
Block a user