fixes #794
This commit is contained in:
parent
1a9f266e50
commit
4d8cd34c9e
3 changed files with 33 additions and 18 deletions
|
|
@ -11,12 +11,12 @@
|
||||||
# included from sem.nim
|
# included from sem.nim
|
||||||
|
|
||||||
proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
|
proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
|
||||||
entry: var TInstantiation) =
|
entry: var TInstantiation) =
|
||||||
if n.kind != nkGenericParams:
|
if n.kind != nkGenericParams:
|
||||||
internalError(n.info, "instantiateGenericParamList; no generic params")
|
internalError(n.info, "instantiateGenericParamList; no generic params")
|
||||||
newSeq(entry.concreteTypes, n.len)
|
newSeq(entry.concreteTypes, n.len)
|
||||||
for i, a in n.pairs:
|
for i, a in n.pairs:
|
||||||
if a.kind != nkSym:
|
if a.kind != nkSym:
|
||||||
internalError(a.info, "instantiateGenericParamList; no symbol")
|
internalError(a.info, "instantiateGenericParamList; no symbol")
|
||||||
var q = a.sym
|
var q = a.sym
|
||||||
if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses:
|
if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses:
|
||||||
|
|
@ -27,13 +27,13 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
|
||||||
var t = PType(idTableGet(pt, q.typ))
|
var t = PType(idTableGet(pt, q.typ))
|
||||||
if t == nil:
|
if t == nil:
|
||||||
if tfRetType in q.typ.flags:
|
if tfRetType in q.typ.flags:
|
||||||
# keep the generic type and allow the return type to be bound
|
# keep the generic type and allow the return type to be bound
|
||||||
# later by semAsgn in return type inference scenario
|
# later by semAsgn in return type inference scenario
|
||||||
t = q.typ
|
t = q.typ
|
||||||
else:
|
else:
|
||||||
localError(a.info, errCannotInstantiateX, s.name.s)
|
localError(a.info, errCannotInstantiateX, s.name.s)
|
||||||
t = errorType(c)
|
t = errorType(c)
|
||||||
elif t.kind == tyGenericParam:
|
elif t.kind == tyGenericParam:
|
||||||
localError(a.info, errCannotInstantiateX, q.name.s)
|
localError(a.info, errCannotInstantiateX, q.name.s)
|
||||||
t = errorType(c)
|
t = errorType(c)
|
||||||
elif t.kind == tyGenericInvocation:
|
elif t.kind == tyGenericInvocation:
|
||||||
|
|
@ -58,17 +58,17 @@ proc genericCacheGet(genericSym: PSym, entry: TInstantiation): PSym =
|
||||||
if sameInstantiation(entry, inst[]):
|
if sameInstantiation(entry, inst[]):
|
||||||
return inst.sym
|
return inst.sym
|
||||||
|
|
||||||
proc removeDefaultParamValues(n: PNode) =
|
proc removeDefaultParamValues(n: PNode) =
|
||||||
# we remove default params, because they cannot be instantiated properly
|
# we remove default params, because they cannot be instantiated properly
|
||||||
# and they are not needed anyway for instantiation (each param is already
|
# and they are not needed anyway for instantiation (each param is already
|
||||||
# provided).
|
# provided).
|
||||||
when false:
|
when false:
|
||||||
for i in countup(1, sonsLen(n)-1):
|
for i in countup(1, sonsLen(n)-1):
|
||||||
var a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if a.kind != nkIdentDefs: IllFormedAst(a)
|
if a.kind != nkIdentDefs: IllFormedAst(a)
|
||||||
var L = a.len
|
var L = a.len
|
||||||
if a.sons[L-1].kind != nkEmpty and a.sons[L-2].kind != nkEmpty:
|
if a.sons[L-1].kind != nkEmpty and a.sons[L-2].kind != nkEmpty:
|
||||||
# ``param: typ = defaultVal``.
|
# ``param: typ = defaultVal``.
|
||||||
# We don't need defaultVal for semantic checking and it's wrong for
|
# We don't need defaultVal for semantic checking and it's wrong for
|
||||||
# ``cmp: proc (a, b: T): int = cmp``. Hm, for ``cmp = cmp`` that is
|
# ``cmp: proc (a, b: T): int = cmp``. Hm, for ``cmp = cmp`` that is
|
||||||
# not possible... XXX We don't solve this issue here.
|
# not possible... XXX We don't solve this issue here.
|
||||||
|
|
@ -97,7 +97,7 @@ proc addProcDecls(c: PContext, fn: PSym) =
|
||||||
var param = fn.typ.n.sons[i].sym
|
var param = fn.typ.n.sons[i].sym
|
||||||
param.owner = fn
|
param.owner = fn
|
||||||
addParamOrResult(c, param, fn.kind)
|
addParamOrResult(c, param, fn.kind)
|
||||||
|
|
||||||
maybeAddResult(c, fn, fn.ast)
|
maybeAddResult(c, fn, fn.ast)
|
||||||
|
|
||||||
proc instantiateBody(c: PContext, n, params: PNode, result: PSym) =
|
proc instantiateBody(c: PContext, n, params: PNode, result: PSym) =
|
||||||
|
|
@ -132,9 +132,9 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
||||||
proc sideEffectsCheck(c: PContext, s: PSym) =
|
proc sideEffectsCheck(c: PContext, s: PSym) =
|
||||||
if {sfNoSideEffect, sfSideEffect} * s.flags ==
|
if {sfNoSideEffect, sfSideEffect} * s.flags ==
|
||||||
{sfNoSideEffect, sfSideEffect}:
|
{sfNoSideEffect, sfSideEffect}:
|
||||||
localError(s.info, errXhasSideEffects, s.name.s)
|
localError(s.info, errXhasSideEffects, s.name.s)
|
||||||
|
|
||||||
proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
|
proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
|
||||||
|
|
@ -162,18 +162,18 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||||
# Alas, doing this here is probably not enough, because another
|
# Alas, doing this here is probably not enough, because another
|
||||||
# proc signature could appear in the params:
|
# proc signature could appear in the params:
|
||||||
# proc foo[T](a: proc (x: T, b: type(x.y))
|
# proc foo[T](a: proc (x: T, b: type(x.y))
|
||||||
#
|
#
|
||||||
# The solution would be to move this logic into semtypinst, but
|
# The solution would be to move this logic into semtypinst, but
|
||||||
# at this point semtypinst have to become part of sem, because it
|
# at this point semtypinst have to become part of sem, because it
|
||||||
# will need to use openScope, addDecl, etc.
|
# will need to use openScope, addDecl, etc.
|
||||||
addDecl(c, prc)
|
addDecl(c, prc)
|
||||||
|
|
||||||
pushInfoContext(info)
|
pushInfoContext(info)
|
||||||
var cl = initTypeVars(c, pt, info)
|
var cl = initTypeVars(c, pt, info)
|
||||||
var result = instCopyType(cl, prc.typ)
|
var result = instCopyType(cl, prc.typ)
|
||||||
let originalParams = result.n
|
let originalParams = result.n
|
||||||
result.n = originalParams.shallowCopy
|
result.n = originalParams.shallowCopy
|
||||||
|
|
||||||
for i in 1 .. <result.len:
|
for i in 1 .. <result.len:
|
||||||
# twrong_field_caching requires these 'resetIdTable' calls:
|
# twrong_field_caching requires these 'resetIdTable' calls:
|
||||||
if i > 1: resetIdTable(cl.symMap)
|
if i > 1: resetIdTable(cl.symMap)
|
||||||
|
|
@ -198,10 +198,10 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||||
resetIdTable(cl.symMap)
|
resetIdTable(cl.symMap)
|
||||||
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
|
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
|
||||||
result.n.sons[0] = originalParams[0].copyTree
|
result.n.sons[0] = originalParams[0].copyTree
|
||||||
|
|
||||||
eraseVoidParams(result)
|
eraseVoidParams(result)
|
||||||
skipIntLiteralParams(result)
|
skipIntLiteralParams(result)
|
||||||
|
|
||||||
prc.typ = result
|
prc.typ = result
|
||||||
maybeAddResult(c, prc, prc.ast)
|
maybeAddResult(c, prc, prc.ast)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
|
||||||
|
|
@ -823,8 +823,13 @@ proc sameEnumTypes*(a, b: PType): bool {.inline.} =
|
||||||
proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
|
proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
|
||||||
if a == b:
|
if a == b:
|
||||||
result = true
|
result = true
|
||||||
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
elif a != nil and b != nil and a.kind == b.kind:
|
||||||
if sameTypeOrNilAux(a.typ, b.typ, c):
|
var x = a.typ
|
||||||
|
var y = b.typ
|
||||||
|
if IgnoreTupleFields in c.flags:
|
||||||
|
if x != nil: x = skipTypes(x, {tyRange, tyGenericInst})
|
||||||
|
if y != nil: y = skipTypes(y, {tyRange, tyGenericInst})
|
||||||
|
if sameTypeOrNilAux(x, y, c):
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
# same symbol as string is enough:
|
# same symbol as string is enough:
|
||||||
|
|
|
||||||
10
tests/ccgbugs/tstringslice.nim
Normal file
10
tests/ccgbugs/tstringslice.nim
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
# bug #794
|
||||||
|
type TRange = range[0..3]
|
||||||
|
|
||||||
|
const str = "123456789"
|
||||||
|
|
||||||
|
for i in TRange.low .. TRange.high:
|
||||||
|
echo str[i] #This works fine
|
||||||
|
echo str[int(i) .. int(TRange.high)] #So does this
|
||||||
|
echo str[i .. TRange.high] #The compiler complains about this
|
||||||
Loading…
Add table
Add a link
Reference in a new issue