This commit is contained in:
Araq 2015-03-05 22:03:26 +01:00
commit 4d8cd34c9e
3 changed files with 33 additions and 18 deletions

View file

@ -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()

View file

@ -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:

View 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