Skip to content

Commit 4e438f9

Browse files
authored
const view types; fixes some cases from #15428 (#15488)
1 parent 1e28cea commit 4e438f9

File tree

7 files changed

+94
-47
lines changed

7 files changed

+94
-47
lines changed

compiler/astalgo.nim

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,10 +591,17 @@ proc value(this: var DebugPrinter; value: PNode) =
591591
if this.conf != nil:
592592
this.key "info"
593593
this.value $lineInfoToStr(this.conf, value.info)
594-
if card(value.flags) > 0:
594+
if value.flags != {}:
595595
this.key "flags"
596596
this.value value.flags
597597

598+
if value.typ != nil:
599+
this.key "typ"
600+
this.value value.typ.kind
601+
else:
602+
this.key "typ"
603+
this.value "nil"
604+
598605
case value.kind
599606
of nkCharLit..nkUInt64Lit:
600607
this.key "intVal"

compiler/ccgexprs.nim

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ proc rawConstExpr(p: BProc, n: PNode; d: var TLoc) =
14001400
# expression not found in the cache:
14011401
inc(p.module.labels)
14021402
p.module.s[cfsData].addf("static NIM_CONST $1 $2 = $3;$n",
1403-
[getTypeDesc(p.module, t), d.r, genBracedInit(p, n, isConst = true)])
1403+
[getTypeDesc(p.module, t), d.r, genBracedInit(p, n, isConst = true, t)])
14041404

14051405
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
14061406
if d.k == locNone and n.len > ord(n.kind == nkObjConstr) and n.isDeepConstExpr:
@@ -2485,7 +2485,7 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
24852485
inc(p.module.labels)
24862486
var tmp = "CNSTCLOSURE" & rope(p.module.labels)
24872487
p.module.s[cfsData].addf("static NIM_CONST $1 $2 = $3;$n",
2488-
[getTypeDesc(p.module, n.typ), tmp, genBracedInit(p, n, isConst = true)])
2488+
[getTypeDesc(p.module, n.typ), tmp, genBracedInit(p, n, isConst = true, n.typ)])
24892489
putIntoDest(p, d, n, tmp, OnStatic)
24902490
else:
24912491
var tmp, a, b: TLoc
@@ -2624,7 +2624,7 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
26242624
# expression not found in the cache:
26252625
inc(p.module.labels)
26262626
p.module.s[cfsData].addf("static NIM_CONST $1 $2 = $3;$n",
2627-
[getTypeDesc(p.module, t), tmp, genBracedInit(p, n, isConst = true)])
2627+
[getTypeDesc(p.module, t, skConst), tmp, genBracedInit(p, n, isConst = true, t)])
26282628

26292629
if d.k == locNone:
26302630
fillLoc(d, locData, n, tmp, OnStatic)
@@ -2847,8 +2847,8 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
28472847
else: internalError(p.config, n.info, "expr(" & $n.kind & "); unknown node kind")
28482848

28492849
proc genNamedConstExpr(p: BProc, n: PNode; isConst: bool): Rope =
2850-
if n.kind == nkExprColonExpr: result = genBracedInit(p, n[1], isConst)
2851-
else: result = genBracedInit(p, n, isConst)
2850+
if n.kind == nkExprColonExpr: result = genBracedInit(p, n[1], isConst, n[0].typ)
2851+
else: result = genBracedInit(p, n, isConst, n.typ)
28522852

28532853
proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
28542854
var t = skipTypes(typ, abstractRange+{tyOwned}-{tyTypeDesc})
@@ -2955,10 +2955,10 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode,
29552955
for i in 1..<constOrNil.len:
29562956
if constOrNil[i].kind == nkExprColonExpr:
29572957
if constOrNil[i][0].sym.name.id == field.name.id:
2958-
result.add genBracedInit(p, constOrNil[i][1], isConst)
2958+
result.add genBracedInit(p, constOrNil[i][1], isConst, field.typ)
29592959
return
29602960
elif i == field.position:
2961-
result.add genBracedInit(p, constOrNil[i], isConst)
2961+
result.add genBracedInit(p, constOrNil[i], isConst, field.typ)
29622962
return
29632963
# not found, produce default value:
29642964
result.add getDefaultValue(p, field.typ, info)
@@ -2999,25 +2999,35 @@ proc genConstObjConstr(p: BProc; n: PNode; isConst: bool): Rope =
29992999

30003000
proc genConstSimpleList(p: BProc, n: PNode; isConst: bool): Rope =
30013001
result = rope("{")
3002-
for i in 0..<n.len - 1:
3003-
result.addf("$1,$n", [genNamedConstExpr(p, n[i], isConst)])
3004-
if n.len > 0:
3005-
result.add(genNamedConstExpr(p, n[^1], isConst))
3006-
result.addf("}$n", [])
3002+
for i in 0..<n.len:
3003+
let it = n[i]
3004+
if i > 0: result.add ",\n"
3005+
if it.kind == nkExprColonExpr: result.add genBracedInit(p, it[1], isConst, it[0].typ)
3006+
else: result.add genBracedInit(p, it, isConst, it.typ)
3007+
result.add("}\n")
3008+
3009+
proc genConstTuple(p: BProc, n: PNode; isConst: bool; tup: PType): Rope =
3010+
result = rope("{")
3011+
for i in 0..<n.len:
3012+
let it = n[i]
3013+
if i > 0: result.add ",\n"
3014+
if it.kind == nkExprColonExpr: result.add genBracedInit(p, it[1], isConst, tup[i])
3015+
else: result.add genBracedInit(p, it, isConst, tup[i])
3016+
result.add("}\n")
30073017

30083018
proc genConstSeq(p: BProc, n: PNode, t: PType; isConst: bool): Rope =
30093019
var data = "{{$1, $1 | NIM_STRLIT_FLAG}" % [n.len.rope]
3020+
let base = t.skipTypes(abstractInst)[0]
30103021
if n.len > 0:
30113022
# array part needs extra curlies:
30123023
data.add(", {")
30133024
for i in 0..<n.len:
30143025
if i > 0: data.addf(",$n", [])
3015-
data.add genBracedInit(p, n[i], isConst)
3026+
data.add genBracedInit(p, n[i], isConst, base)
30163027
data.add("}")
30173028
data.add("}")
30183029

30193030
result = getTempName(p.module)
3020-
let base = t.skipTypes(abstractInst)[0]
30213031

30223032
appcg(p.module, cfsData,
30233033
"static $5 struct {$n" &
@@ -3030,14 +3040,14 @@ proc genConstSeq(p: BProc, n: PNode, t: PType; isConst: bool): Rope =
30303040
result = "(($1)&$2)" % [getTypeDesc(p.module, t), result]
30313041

30323042
proc genConstSeqV2(p: BProc, n: PNode, t: PType; isConst: bool): Rope =
3043+
let base = t.skipTypes(abstractInst)[0]
30333044
var data = rope"{"
30343045
for i in 0..<n.len:
30353046
if i > 0: data.addf(",$n", [])
3036-
data.add genBracedInit(p, n[i], isConst)
3047+
data.add genBracedInit(p, n[i], isConst, base)
30373048
data.add("}")
30383049

30393050
let payload = getTempName(p.module)
3040-
let base = t.skipTypes(abstractInst)[0]
30413051

30423052
appcg(p.module, cfsData,
30433053
"static $5 struct {$n" &
@@ -3047,46 +3057,32 @@ proc genConstSeqV2(p: BProc, n: PNode, t: PType; isConst: bool): Rope =
30473057
if isConst: "const" else: ""])
30483058
result = "{$1, ($2*)&$3}" % [rope(n.len), getSeqPayloadType(p.module, t), payload]
30493059

3050-
proc genBracedInit(p: BProc, n: PNode; isConst: bool): Rope =
3060+
proc genBracedInit(p: BProc, n: PNode; isConst: bool; optionalType: PType): Rope =
30513061
case n.kind
30523062
of nkHiddenStdConv, nkHiddenSubConv:
3053-
when false:
3054-
# XXX The frontend doesn't keep conversions to openArray for us. :-(
3055-
# We need to change 'transformConv' first, but that is hard.
3056-
if n.typ.kind == tyOpenArray:
3057-
assert n[1].kind == nkBracket
3058-
let data = genBracedInit(p, n[1], isConst)
3059-
3060-
let payload = getTempName(p.module)
3061-
let ctype = getTypeDesc(p.module, n.typ.skipTypes(abstractInst)[0])
3062-
let arrLen = n[1].len
3063-
appcg(p.module, cfsData,
3064-
"static $5 $1 $3[$2] = $4;$n", [
3065-
ctype, arrLen, payload, data,
3066-
if isConst: "const" else: ""])
3067-
result = "{($1*)&$2, $3}" % [ctype, payload, rope arrLen]
3068-
else:
3069-
result = genBracedInit(p, n[1], isConst)
3063+
result = genBracedInit(p, n[1], isConst, n.typ)
30703064
else:
30713065
var ty = tyNone
3072-
if n.typ == nil:
3066+
var typ: PType = nil
3067+
if optionalType == nil:
30733068
if n.kind in nkStrKinds:
30743069
ty = tyString
30753070
else:
30763071
internalError(p.config, n.info, "node has no type")
30773072
else:
3078-
ty = skipTypes(n.typ, abstractInstOwned + {tyStatic}).kind
3073+
typ = skipTypes(optionalType, abstractInstOwned + {tyStatic})
3074+
ty = typ.kind
30793075
case ty
30803076
of tySet:
30813077
let cs = toBitSet(p.config, n)
30823078
result = genRawSetData(cs, int(getSize(p.config, n.typ)))
30833079
of tySequence:
30843080
if optSeqDestructors in p.config.globalOptions:
3085-
result = genConstSeqV2(p, n, n.typ, isConst)
3081+
result = genConstSeqV2(p, n, typ, isConst)
30863082
else:
3087-
result = genConstSeq(p, n, n.typ, isConst)
3083+
result = genConstSeq(p, n, typ, isConst)
30883084
of tyProc:
3089-
if n.typ.callConv == ccClosure and n.len > 1 and n[1].kind == nkNilLit:
3085+
if typ.callConv == ccClosure and n.len > 1 and n[1].kind == nkNilLit:
30903086
# Conversion: nimcall -> closure.
30913087
# this hack fixes issue that nkNilLit is expanded to {NIM_NIL,NIM_NIL}
30923088
# this behaviour is needed since closure_var = nil must be
@@ -3099,13 +3095,30 @@ proc genBracedInit(p: BProc, n: PNode; isConst: bool): Rope =
30993095
else:
31003096
var d: TLoc
31013097
initLocExpr(p, n[0], d)
3102-
result = "{(($1) $2),NIM_NIL}" % [getClosureType(p.module, n.typ, clHalfWithEnv), rdLoc(d)]
3098+
result = "{(($1) $2),NIM_NIL}" % [getClosureType(p.module, typ, clHalfWithEnv), rdLoc(d)]
31033099
else:
31043100
var d: TLoc
31053101
initLocExpr(p, n, d)
31063102
result = rdLoc(d)
3107-
of tyArray, tyTuple, tyOpenArray, tyVarargs:
3103+
of tyArray, tyVarargs:
31083104
result = genConstSimpleList(p, n, isConst)
3105+
of tyTuple:
3106+
result = genConstTuple(p, n, isConst, typ)
3107+
of tyOpenArray:
3108+
if n.kind != nkBracket:
3109+
internalError(p.config, n.info, "const openArray expression is not an array construction")
3110+
3111+
let data = genConstSimpleList(p, n, isConst)
3112+
3113+
let payload = getTempName(p.module)
3114+
let ctype = getTypeDesc(p.module, typ[0])
3115+
let arrLen = n.len
3116+
appcg(p.module, cfsData,
3117+
"static $5 $1 $3[$2] = $4;$n", [
3118+
ctype, arrLen, payload, data,
3119+
if isConst: "const" else: ""])
3120+
result = "{($1*)&$2, $3}" % [ctype, payload, rope arrLen]
3121+
31093122
of tyObject:
31103123
result = genConstObjConstr(p, n, isConst)
31113124
of tyString, tyCString:

compiler/ccgstmts.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,15 +272,15 @@ proc genGotoVar(p: BProc; value: PNode) =
272272
else:
273273
lineF(p, cpsStmts, "goto NIMSTATE_$#;$n", [value.intVal.rope])
274274

275-
proc genBracedInit(p: BProc, n: PNode; isConst: bool): Rope
275+
proc genBracedInit(p: BProc, n: PNode; isConst: bool; optionalType: PType): Rope
276276

277277
proc potentialValueInit(p: BProc; v: PSym; value: PNode): Rope =
278278
if lfDynamicLib in v.loc.flags or sfThread in v.flags or p.hcrOn:
279279
result = nil
280280
elif sfGlobal in v.flags and value != nil and isDeepConstExpr(value, p.module.compileToCpp) and
281281
p.withinLoop == 0 and not containsGarbageCollectedRef(v.typ):
282282
#echo "New code produced for ", v.name.s, " ", p.config $ value.info
283-
result = genBracedInit(p, value, isConst = false)
283+
result = genBracedInit(p, value, isConst = false, v.typ)
284284
else:
285285
result = nil
286286

compiler/cgen.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,8 @@ proc requestConstImpl(p: BProc, sym: PSym) =
11951195
# add a suffix for hcr - will later init the global pointer with this data
11961196
let actualConstName = if m.hcrOn: sym.loc.r & "_const" else: sym.loc.r
11971197
q.s[cfsData].addf("N_LIB_PRIVATE NIM_CONST $1 $2 = $3;$n",
1198-
[getTypeDesc(q, sym.typ), actualConstName, genBracedInit(q.initProc, sym.ast, isConst = true)])
1198+
[getTypeDesc(q, sym.typ), actualConstName,
1199+
genBracedInit(q.initProc, sym.ast, isConst = true, sym.typ)])
11991200
if m.hcrOn:
12001201
# generate the global pointer with the real name
12011202
q.s[cfsVars].addf("static $1* $2;$n", [getTypeDesc(m, sym.loc.t, skVar), sym.loc.r])

compiler/typeallowed.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ proc classifyViewTypeAux(marker: var IntSet, t: PType): ViewTypeKind =
217217
case t.kind
218218
of tyVar:
219219
result = mutableView
220-
of tyLent, tyVarargs, tyOpenArray:
220+
of tyLent, tyOpenArray:
221221
result = immutableView
222222
of tyGenericInst, tyDistinct, tyAlias, tyInferred, tySink, tyOwned,
223223
tyUncheckedArray, tySequence, tyArray, tyRef, tyStatic:

compiler/vmgen.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
18071807
result.add getNullValue(t[i], info, conf)
18081808
of tySet:
18091809
result = newNodeIT(nkCurly, info, t)
1810-
of tySequence:
1810+
of tySequence, tyOpenArray:
18111811
result = newNodeIT(nkBracket, info, t)
18121812
else:
18131813
globalError(conf, info, "cannot create null element for: " & $t.kind)

tests/views/tconst_views.nim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
discard """
2+
cmd: "nim c --experimental:views $file"
3+
output: '''(data: [1, 2, 3], other: 4)
4+
[1, 20, 3]'''
5+
"""
6+
7+
type
8+
Foo = object
9+
data: openArray[int]
10+
other: int
11+
12+
const
13+
c = Foo(data: [1, 2, 3], other: 4)
14+
15+
c2 = Foo(data: [1, 20, 3], other: 4)
16+
17+
proc `$`(x: openArray[int]): string =
18+
result = "["
19+
for i in x:
20+
if result.len > 1: result.add ", "
21+
result.add $i
22+
result.add "]"
23+
24+
echo c
25+
echo c2.data
26+

0 commit comments

Comments
 (0)