clean-up some obsolete code; close #602

This commit is contained in:
Zahary Karadjov
2013-12-31 12:39:43 +02:00
parent ed3ab6539d
commit 8e0941576f
6 changed files with 73 additions and 205 deletions

View File

@@ -158,8 +158,6 @@ var
const oKeepVariableNames* = true
const oUseLateInstantiation* = false
proc mainCommandArg*: string =
## This is intended for commands like check or parse
## which will work on the main project file unless

View File

@@ -131,157 +131,20 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
s.ast.sons[genericParamsPos].kind == nkEmpty:
c.threadEntries.add(s)
proc lateInstantiateGeneric(c: PContext, invocation: PType, info: TLineInfo): PType =
internalAssert invocation.kind == tyGenericInvokation
let cacheHit = searchInstTypes(invocation)
if cacheHit != nil:
result = cacheHit
else:
let s = invocation.sons[0].sym
let oldScope = c.currentScope
c.currentScope = s.typScope
openScope(c)
pushInfoContext(info)
for i in 0 .. <s.typ.n.sons.len:
let genericParam = s.typ.n[i].sym
let symKind = if genericParam.typ.kind == tyStatic: skConst
else: skType
var boundSym = newSym(symKind, s.typ.n[i].sym.name, s, info)
boundSym.typ = invocation.sons[i+1].skipTypes({tyStatic})
boundSym.ast = invocation.sons[i+1].n
addDecl(c, boundSym)
# XXX: copyTree would have been unnecessary here if semTypeNode
# didn't modify its input parameters. Currently, it does modify
# at least the record lists of the passed object and tuple types
var instantiated = semTypeNode(c, copyTree(s.ast[2]), nil)
popInfoContext()
closeScope(c)
c.currentScope = oldScope
if instantiated != nil:
result = invocation
result.kind = tyGenericInst
result.sons.add instantiated
cacheTypeInst result
proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
allowMetaTypes = false): PType =
when oUseLateInstantiation:
lateInstantiateGeneric(c, header, info)
else:
var cl: TReplTypeVars
initIdTable(cl.symMap)
initIdTable(cl.typeMap)
initIdTable(cl.localCache)
cl.info = info
cl.c = c
cl.allowMetaTypes = allowMetaTypes
result = replaceTypeVarsT(cl, header)
var cl: TReplTypeVars
initIdTable(cl.symMap)
initIdTable(cl.typeMap)
initIdTable(cl.localCache)
cl.info = info
cl.c = c
cl.allowMetaTypes = allowMetaTypes
result = replaceTypeVarsT(cl, header)
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
result = instGenericContainer(c, n.info, header)
proc fixupProcType(c: PContext, genericType: PType,
inst: TInstantiation): PType =
# XXX: This is starting to look suspiciously like ReplaceTypeVarsT
# there are few apparent differences, but maybe the code could be
# moved over.
# * the code here uses the new genericSym.position property when
# doing lookups.
# * the handling of tyTypeDesc seems suspicious in ReplaceTypeVarsT
# typedesc params were previously handled in the second pass of
# semParamList
# * void (nkEmpty) params doesn't seem to be stripped in ReplaceTypeVarsT
result = genericType
if result == nil: return
case genericType.kind
of tyGenericParam, tyTypeClasses:
result = inst.concreteTypes[genericType.sym.position]
of tyTypeDesc:
result = inst.concreteTypes[genericType.sym.position]
if tfUnresolved in genericType.flags:
result = result.sons[0]
of tyStatic:
result = inst.concreteTypes[genericType.sym.position]
of tyGenericInst:
result = fixupProcType(c, result.lastSon, inst)
of tyObject:
var recList = genericType.n
for i in 0 .. <recList.sonsLen:
let field = recList[i].sym
let changed = fixupProcType(c, field.typ, inst)
if field.typ != changed:
if result == genericType:
result = copyType(genericType, genericType.owner, false)
result.n = copyTree(recList)
result.n.sons[i].sym = copySym(recList[i].sym, true)
result.n.sons[i].typ = changed
result.n.sons[i].sym.typ = changed
of tyOpenArray, tyArray, tySet, tySequence, tyTuple, tyProc,
tyPtr, tyVar, tyRef, tyOrdinal, tyRange, tyVarargs:
if genericType.sons == nil: return
var head = 0
for i in 0 .. <genericType.sons.len:
let origType = genericType.sons[i]
var changed = fixupProcType(c, origType, inst)
if changed != genericType.sons[i]:
var changed = changed.skipIntLit
if result == genericType:
# the first detected change initializes the result
result = copyType(genericType, genericType.owner, false)
if genericType.n != nil:
result.n = copyTree(genericType.n)
# XXX: doh, we have to treat seq and arrays as special case
# because sometimes the `@` magic will be applied to an empty
# sequence having the type tySequence(tyEmpty)
if changed.kind == tyEmpty and
genericType.kind notin {tyArray, tySequence}:
if genericType.kind == tyProc and i == 0:
# return types of procs are overwritten with nil
changed = nil
else:
# otherwise, `empty` is just erased from the signature
result.sons[i..i] = []
if result.n != nil: result.n.sons[i..i] = []
continue
result.sons[head] = changed
result.size = 0
if result.n != nil:
if result.n.kind == nkRecList:
for son in result.n.sons:
if son.typ == origType:
son.typ = changed
son.sym = copySym(son.sym, true)
son.sym.typ = changed
if result.n.kind == nkFormalParams:
if i != 0:
let origParam = result.n.sons[head].sym
var param = copySym(origParam)
param.typ = changed
param.ast = origParam.ast
result.n.sons[head] = newSymNode(param)
# won't be advanced on empty (void) nodes
inc head
of tyGenericInvokation:
result = newTypeWithSons(c, tyGenericInvokation, genericType.sons)
for i in 1 .. <genericType.sons.len:
result.sons[i] = fixupProcType(c, result.sons[i], inst)
result = instGenericContainer(c, getInfoContext(-1), result)
else: discard
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
info: TLineInfo): PSym =
# no need to instantiate generic templates/macros:
@@ -311,7 +174,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
var entry = TInstantiation.new
entry.sym = result
instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[])
# let t1 = fixupProcType(c, fn.typ, entry[])
result.typ = generateTypeInstance(c, pt, info, fn.typ)
n.sons[genericParamsPos] = ast.emptyNode
var oldPrc = genericCacheGet(fn, entry[])

View File

@@ -740,16 +740,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
# like: mydata.seq
rawAddSon(s.typ, newTypeS(tyEmpty, c))
s.ast = a
when oUseLateInstantiation:
var body: PType = nil
s.typScope = c.currentScope.parent
else:
inc c.inGenericContext
var body = semTypeNode(c, a.sons[2], nil)
dec c.inGenericContext
if body != nil:
body.sym = s
body.size = -1 # could not be computed properly
inc c.inGenericContext
var body = semTypeNode(c, a.sons[2], nil)
dec c.inGenericContext
if body != nil:
body.sym = s
body.size = -1 # could not be computed properly
s.typ.sons[sonsLen(s.typ) - 1] = body
popOwner()
closeScope(c)

View File

@@ -600,7 +600,8 @@ template shouldHaveMeta(t) =
proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
paramType: PType, paramName: string,
info: TLineInfo, anon = false): PType =
if paramType == nil: return # (e.g. proc return type)
proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType =
let finalTypId = if typId != nil: typId
else: getIdent(paramName & ":type")
@@ -621,7 +622,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
s.position = genericParams.len
genericParams.addSon(newSymNode(s))
result = typeClass
# XXX: There are codegen errors if this is turned into a nested proc
template liftingWalk(typ: PType, anonFlag = false): expr =
liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
@@ -655,14 +656,15 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
# disable the bindOnce behavior for the type class
result = liftingWalk(paramType.sons[0], true)
of tySequence, tySet, tyArray, tyOpenArray:
of tySequence, tySet, tyArray, tyOpenArray,
tyVar, tyPtr, tyRef, tyProc:
# XXX: this is a bit strange, but proc(s: seq)
# produces tySequence(tyGenericParam, null).
# This also seems to be true when creating aliases
# like: type myseq = distinct seq.
# Maybe there is another better place to associate
# the seq type class with the seq identifier.
if paramType.lastSon == nil:
if paramType.kind == tySequence and paramType.lastSon == nil:
let typ = c.newTypeWithSons(tyBuiltInTypeClass,
@[newTypeS(paramType.kind, c)])
result = addImplicitGeneric(typ)
@@ -720,7 +722,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
result = liftingWalk(paramType.lastSon)
else:
result = addImplicitGeneric(newTypeS(tyAnything, c))
else: nil
# result = liftingWalk(paramType)
@@ -881,14 +883,8 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
localError(n.info, errCannotInstantiateX, s.name.s)
result = newOrPrevType(tyError, prev, c)
else:
when oUseLateInstantiation:
result = lateInstantiateGeneric(c, result, n.info)
else:
result = instGenericContainer(c, n.info, result,
allowMetaTypes = not isConcrete)
if not isConcrete and result.kind == tyGenericInst:
result.lastSon.shouldHaveMeta
result = instGenericContainer(c, n.info, result,
allowMetaTypes = false)
proc semTypeExpr(c: PContext, n: PNode): PType =
var n = semExprWithType(c, n, {efDetermineType})

View File

@@ -432,7 +432,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
template bindingRet(res) =
when res == isGeneric: put(c.bindings, f, aOrig)
return res
template considerPreviousT(body: stmt) {.immediate.} =
var prev = PType(idTableGet(c.bindings, f))
if prev == nil: body
else: return typeRel(c, prev, a)
case a.kind
of tyOr:
# seq[int|string] vs seq[number]
@@ -658,19 +663,22 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
if a.kind == tyEmpty: result = isEqual
of tyGenericInst:
if a.kind == tyGenericInst and a.base == f.base:
for i in 1 .. f.sonsLen-2:
result = typeRel(c, f.sons[i], a.sons[i])
let roota = a.skipGenericAlias
let rootf = f.skipGenericAlias
if a.kind == tyGenericInst and roota.base == rootf.base:
for i in 1 .. rootf.sonsLen-2:
result = typeRel(c, rootf.sons[i], roota.sons[i])
if result == isNone: return
result = isGeneric
else:
result = typeRel(c, lastSon(f), a)
of tyGenericBody:
if a.kind == tyGenericInst and a.sons[0] == f:
return isGeneric
let ff = lastSon(f)
if ff != nil: result = typeRel(c, ff, a)
considerPreviousT:
if a.kind == tyGenericInst and a.sons[0] == f:
bindingRet isGeneric
let ff = lastSon(f)
if ff != nil: result = typeRel(c, ff, a)
of tyGenericInvokation:
var x = a.skipGenericAlias
@@ -697,39 +705,38 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
put(c.bindings, f.sons[i], x)
of tyAnd:
for branch in f.sons:
if typeRel(c, branch, aOrig) == isNone:
return isNone
considerPreviousT:
for branch in f.sons:
if typeRel(c, branch, aOrig) == isNone:
return isNone
bindingRet isGeneric
bindingRet isGeneric
of tyOr:
for branch in f.sons:
if typeRel(c, branch, aOrig) != isNone:
bindingRet isGeneric
return isNone
considerPreviousT:
for branch in f.sons:
if typeRel(c, branch, aOrig) != isNone:
bindingRet isGeneric
return isNone
of tyNot:
for branch in f.sons:
if typeRel(c, branch, aOrig) != isNone:
return isNone
bindingRet isGeneric
considerPreviousT:
for branch in f.sons:
if typeRel(c, branch, aOrig) != isNone:
return isNone
bindingRet isGeneric
of tyAnything:
var prev = PType(idTableGet(c.bindings, f))
if prev == nil:
considerPreviousT:
var concrete = concreteType(c, a)
if concrete != nil and doBind:
put(c.bindings, f, concrete)
return isGeneric
else:
return typeRel(c, prev, a)
of tyBuiltInTypeClass:
var prev = PType(idTableGet(c.bindings, f))
if prev == nil:
considerPreviousT:
let targetKind = f.sons[0].kind
if targetKind == a.skipTypes({tyRange, tyGenericInst}).kind or
(targetKind in {tyProc, tyPointer} and a.kind == tyNil):
@@ -737,19 +744,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
return isGeneric
else:
return isNone
else:
result = typeRel(c, prev, a)
of tyCompositeTypeClass:
var prev = PType(idTableGet(c.bindings, f))
if prev == nil:
considerPreviousT:
if typeRel(c, f.sons[1], a) != isNone:
put(c.bindings, f, a)
return isGeneric
else:
return isNone
else:
result = typeRel(c, prev, a)
of tyGenericParam, tyTypeClass:
var x = PType(idTableGet(c.bindings, f))

View File

@@ -43,3 +43,17 @@ proc f[T](a: TVecT[T], b: TVecT[T]): T = discard
var x: float = f([0.0'f32, 0.0'f32], [0.0'f32, 0.0'f32])
var y = f(TVec2([0.0'f32, 0.0'f32]), TVec2([0.0'f32, 0.0'f32]))
# https://github.com/Araq/Nimrod/issues/602
type
TTest = object
TTest2* = object
TUnion = TTest | TTest2
proc f(src: ptr TUnion, dst: ptr TUnion) =
echo("asd")
var tx: TTest
var ty: TTest2
accept f(addr tx, addr tx)
reject f(addr tx, addr ty)