Relax the restrictions on the index types (#9412)

This commit is contained in:
LemonBoy 2018-10-18 11:08:05 +02:00 • committed by Andreas Rumpf
commit 6ef198e07b
2 changed files with 18 additions and 20 deletions

View file

@ -1357,28 +1357,23 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
arr = arr.base arr = arr.base
case arr.kind case arr.kind
of tyArray, tyOpenArray, tyVarargs, tySequence, tyString, of tyArray, tyOpenArray, tyVarargs, tySequence, tyString, tyCString,
tyCString: tyUncheckedArray:
if n.len != 2: return nil if n.len != 2: return nil
n.sons[0] = makeDeref(n.sons[0]) n.sons[0] = makeDeref(n.sons[0])
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
n.sons[i] = semExprWithType(c, n.sons[i], n.sons[i] = semExprWithType(c, n.sons[i],
flags*{efInTypeof, efDetermineType}) flags*{efInTypeof, efDetermineType})
var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(c.graph, n.info, tyInt) # Arrays index type is dictated by the range's type
if arr.kind == tyArray:
var indexType = arr.sons[0]
var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1]) var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1])
if arg != nil: if arg != nil:
n.sons[1] = arg n.sons[1] = arg
result = n result = n
result.typ = elemType(arr) result.typ = elemType(arr)
#GlobalError(n.info, errIndexTypesDoNotMatch) # Other types have a bit more of leeway
of tyUncheckedArray: elif n.sons[1].typ.skipTypes(abstractRange-{tyDistinct}).kind in
if n.len != 2: return nil
n.sons[0] = makeDeref(n.sons[0])
for i in countup(1, sonsLen(n) - 1):
n.sons[i] = semExprWithType(c, n.sons[i],
flags*{efInTypeof, efDetermineType})
# index into unchecked array must be some integer type:
if n.sons[1].typ.skipTypes(abstractRange-{tyDistinct}).kind in
{tyInt..tyInt64, tyUInt..tyUInt64}: {tyInt..tyInt64, tyUInt..tyUInt64}:
result = n result = n
result.typ = elemType(arr) result.typ = elemType(arr)

View file

@ -533,6 +533,9 @@ block t7818:
doAssert(testOpenArray(@[u.addr, v.addr, w.addr]) == "123") doAssert(testOpenArray(@[u.addr, v.addr, w.addr]) == "123")
doAssert(testOpenArray(@[w.addr, u.addr, v.addr]) == "312") doAssert(testOpenArray(@[w.addr, u.addr, v.addr]) == "312")
# regression regarding unchecked array indexing: block trelaxedindextyp:
proc foo(x: ptr UncheckedArray[int]; idx: uint64) = # any integral type is allowed as index
echo x[idx] proc foo(x: ptr UncheckedArray[int]; idx: uint64) = echo x[idx]
proc foo(x: seq[int]; idx: uint64) = echo x[idx]
proc foo(x: string|cstring; idx: uint64) = echo x[idx]
proc foo(x: openArray[int]; idx: uint64) = echo x[idx]