Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

don't construct array type for already typed nkBracket node #24224

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 43 additions & 22 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -722,29 +722,41 @@ proc arrayConstrType(c: PContext, n: PNode): PType =

proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
result = newNodeI(nkBracket, n.info)
result.typ = newTypeS(tyArray, c)
# nkBracket nodes can also be produced by the VM as seq constant nodes
# in which case, we cannot produce a new array type for the node,
# as this might lose type info even when the node has array type
let constructType = n.typ.isNil
var expectedElementType, expectedIndexType: PType = nil
if expectedType != nil:
let expected = expectedType.skipTypes(abstractRange-{tyDistinct})
case expected.kind
var expectedBase: PType = nil
if constructType:
result.typ = newTypeS(tyArray, c)
rawAddSon(result.typ, nil) # index type
if expectedType != nil:
expectedBase = expectedType.skipTypes(abstractRange-{tyDistinct})
else:
result.typ = n.typ
expectedBase = n.typ.skipTypes(abstractRange) # include tyDistinct this time
if expectedBase != nil:
case expectedBase.kind
of tyArray:
expectedIndexType = expected[0]
expectedElementType = expected[1]
of tyOpenArray:
expectedElementType = expected[0]
expectedIndexType = expectedBase[0]
expectedElementType = expectedBase[1]
of tyOpenArray, tySequence:
# typed bracket expressions can also have seq type
expectedElementType = expectedBase[0]
else: discard
rawAddSon(result.typ, nil) # index type
var
firstIndex, lastIndex: Int128 = Zero
indexType = getSysType(c.graph, n.info, tyInt)
lastValidIndex = lastOrd(c.config, indexType)
if n.len == 0:
rawAddSon(result.typ,
if expectedElementType != nil and
typeAllowed(expectedElementType, skLet, c) == nil:
expectedElementType
else:
newTypeS(tyEmpty, c)) # needs an empty basetype!
if constructType:
rawAddSon(result.typ,
if expectedElementType != nil and
typeAllowed(expectedElementType, skLet, c) == nil:
expectedElementType
else:
newTypeS(tyEmpty, c)) # needs an empty basetype!
lastIndex = toInt128(-1)
else:
var x = n[0]
Expand All @@ -761,9 +773,13 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
x = x[1]

let yy = semExprWithType(c, x, {efTypeAllowed}, expectedElementType)
var typ = yy.typ
if expectedElementType == nil:
expectedElementType = typ
var typ: PType
if constructType:
typ = yy.typ
if expectedElementType == nil:
expectedElementType = typ
else:
typ = expectedElementType
result.add yy
#var typ = skipTypes(result[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
for i in 1..<n.len:
Expand All @@ -783,15 +799,20 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp

let xx = semExprWithType(c, x, {efTypeAllowed}, expectedElementType)
result.add xx
typ = commonType(c, typ, xx.typ)
if constructType:
typ = commonType(c, typ, xx.typ)
#n[i] = semExprWithType(c, x, {})
#result.add fitNode(c, typ, n[i])
inc(lastIndex)
addSonSkipIntLit(result.typ, typ, c.idgen)
if constructType:
addSonSkipIntLit(result.typ, typ, c.idgen)
for i in 0..<result.len:
result[i] = fitNode(c, typ, result[i], result[i].info)
result.typ.setIndexType makeRangeType(c, toInt64(firstIndex), toInt64(lastIndex), n.info,
indexType)
if constructType:
result.typ.setIndexType(
makeRangeType(c,
toInt64(firstIndex), toInt64(lastIndex),
n.info, indexType))

proc fixAbstractType(c: PContext, n: PNode) =
for i in 1..<n.len:
Expand Down
29 changes: 29 additions & 0 deletions tests/vm/tconstarrayresem.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# issue #23010

type
Result[T, E] = object
case oResult: bool
of false:
discard
of true:
vResult: T

Opt[T] = Result[T, void]

template ok[T, E](R: type Result[T, E], x: untyped): R =
R(oResult: true, vResult: x)

template c[T](v: T): Opt[T] = Opt[T].ok(v)

type
FixedBytes[N: static[int]] = distinct array[N, byte]

H = object
d: FixedBytes[2]

const b = default(H)
template g(): untyped =
const t = default(H)
b

discard c(g())
Loading