clean-up some obsolete code; close #602
This commit is contained in:
parent
ed3ab6539d
commit
8e0941576f
6 changed files with 73 additions and 205 deletions
|
|
@ -158,8 +158,6 @@ var
|
||||||
|
|
||||||
const oKeepVariableNames* = true
|
const oKeepVariableNames* = true
|
||||||
|
|
||||||
const oUseLateInstantiation* = false
|
|
||||||
|
|
||||||
proc mainCommandArg*: string =
|
proc mainCommandArg*: string =
|
||||||
## This is intended for commands like check or parse
|
## This is intended for commands like check or parse
|
||||||
## which will work on the main project file unless
|
## which will work on the main project file unless
|
||||||
|
|
|
||||||
|
|
@ -131,157 +131,20 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
|
||||||
s.ast.sons[genericParamsPos].kind == nkEmpty:
|
s.ast.sons[genericParamsPos].kind == nkEmpty:
|
||||||
c.threadEntries.add(s)
|
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,
|
proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
|
||||||
allowMetaTypes = false): PType =
|
allowMetaTypes = false): PType =
|
||||||
when oUseLateInstantiation:
|
var cl: TReplTypeVars
|
||||||
lateInstantiateGeneric(c, header, info)
|
initIdTable(cl.symMap)
|
||||||
else:
|
initIdTable(cl.typeMap)
|
||||||
var cl: TReplTypeVars
|
initIdTable(cl.localCache)
|
||||||
initIdTable(cl.symMap)
|
cl.info = info
|
||||||
initIdTable(cl.typeMap)
|
cl.c = c
|
||||||
initIdTable(cl.localCache)
|
cl.allowMetaTypes = allowMetaTypes
|
||||||
cl.info = info
|
result = replaceTypeVarsT(cl, header)
|
||||||
cl.c = c
|
|
||||||
cl.allowMetaTypes = allowMetaTypes
|
|
||||||
result = replaceTypeVarsT(cl, header)
|
|
||||||
|
|
||||||
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
|
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
|
||||||
result = instGenericContainer(c, n.info, header)
|
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,
|
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
info: TLineInfo): PSym =
|
info: TLineInfo): PSym =
|
||||||
# no need to instantiate generic templates/macros:
|
# no need to instantiate generic templates/macros:
|
||||||
|
|
@ -311,7 +174,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
var entry = TInstantiation.new
|
var entry = TInstantiation.new
|
||||||
entry.sym = result
|
entry.sym = result
|
||||||
instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[])
|
instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[])
|
||||||
# let t1 = fixupProcType(c, fn.typ, entry[])
|
|
||||||
result.typ = generateTypeInstance(c, pt, info, fn.typ)
|
result.typ = generateTypeInstance(c, pt, info, fn.typ)
|
||||||
n.sons[genericParamsPos] = ast.emptyNode
|
n.sons[genericParamsPos] = ast.emptyNode
|
||||||
var oldPrc = genericCacheGet(fn, entry[])
|
var oldPrc = genericCacheGet(fn, entry[])
|
||||||
|
|
|
||||||
|
|
@ -740,16 +740,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
# like: mydata.seq
|
# like: mydata.seq
|
||||||
rawAddSon(s.typ, newTypeS(tyEmpty, c))
|
rawAddSon(s.typ, newTypeS(tyEmpty, c))
|
||||||
s.ast = a
|
s.ast = a
|
||||||
when oUseLateInstantiation:
|
inc c.inGenericContext
|
||||||
var body: PType = nil
|
var body = semTypeNode(c, a.sons[2], nil)
|
||||||
s.typScope = c.currentScope.parent
|
dec c.inGenericContext
|
||||||
else:
|
if body != nil:
|
||||||
inc c.inGenericContext
|
body.sym = s
|
||||||
var body = semTypeNode(c, a.sons[2], nil)
|
body.size = -1 # could not be computed properly
|
||||||
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
|
s.typ.sons[sonsLen(s.typ) - 1] = body
|
||||||
popOwner()
|
popOwner()
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
|
||||||
|
|
@ -600,7 +600,8 @@ template shouldHaveMeta(t) =
|
||||||
proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
paramType: PType, paramName: string,
|
paramType: PType, paramName: string,
|
||||||
info: TLineInfo, anon = false): PType =
|
info: TLineInfo, anon = false): PType =
|
||||||
|
if paramType == nil: return # (e.g. proc return type)
|
||||||
|
|
||||||
proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType =
|
proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType =
|
||||||
let finalTypId = if typId != nil: typId
|
let finalTypId = if typId != nil: typId
|
||||||
else: getIdent(paramName & ":type")
|
else: getIdent(paramName & ":type")
|
||||||
|
|
@ -621,7 +622,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
s.position = genericParams.len
|
s.position = genericParams.len
|
||||||
genericParams.addSon(newSymNode(s))
|
genericParams.addSon(newSymNode(s))
|
||||||
result = typeClass
|
result = typeClass
|
||||||
|
|
||||||
# XXX: There are codegen errors if this is turned into a nested proc
|
# XXX: There are codegen errors if this is turned into a nested proc
|
||||||
template liftingWalk(typ: PType, anonFlag = false): expr =
|
template liftingWalk(typ: PType, anonFlag = false): expr =
|
||||||
liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
|
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
|
# disable the bindOnce behavior for the type class
|
||||||
result = liftingWalk(paramType.sons[0], true)
|
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)
|
# XXX: this is a bit strange, but proc(s: seq)
|
||||||
# produces tySequence(tyGenericParam, null).
|
# produces tySequence(tyGenericParam, null).
|
||||||
# This also seems to be true when creating aliases
|
# This also seems to be true when creating aliases
|
||||||
# like: type myseq = distinct seq.
|
# like: type myseq = distinct seq.
|
||||||
# Maybe there is another better place to associate
|
# Maybe there is another better place to associate
|
||||||
# the seq type class with the seq identifier.
|
# 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,
|
let typ = c.newTypeWithSons(tyBuiltInTypeClass,
|
||||||
@[newTypeS(paramType.kind, c)])
|
@[newTypeS(paramType.kind, c)])
|
||||||
result = addImplicitGeneric(typ)
|
result = addImplicitGeneric(typ)
|
||||||
|
|
@ -720,7 +722,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result = liftingWalk(paramType.lastSon)
|
result = liftingWalk(paramType.lastSon)
|
||||||
else:
|
else:
|
||||||
result = addImplicitGeneric(newTypeS(tyAnything, c))
|
result = addImplicitGeneric(newTypeS(tyAnything, c))
|
||||||
|
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
# result = liftingWalk(paramType)
|
# 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)
|
localError(n.info, errCannotInstantiateX, s.name.s)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
else:
|
else:
|
||||||
when oUseLateInstantiation:
|
result = instGenericContainer(c, n.info, result,
|
||||||
result = lateInstantiateGeneric(c, result, n.info)
|
allowMetaTypes = false)
|
||||||
else:
|
|
||||||
result = instGenericContainer(c, n.info, result,
|
|
||||||
allowMetaTypes = not isConcrete)
|
|
||||||
if not isConcrete and result.kind == tyGenericInst:
|
|
||||||
result.lastSon.shouldHaveMeta
|
|
||||||
|
|
||||||
|
|
||||||
proc semTypeExpr(c: PContext, n: PNode): PType =
|
proc semTypeExpr(c: PContext, n: PNode): PType =
|
||||||
var n = semExprWithType(c, n, {efDetermineType})
|
var n = semExprWithType(c, n, {efDetermineType})
|
||||||
|
|
|
||||||
|
|
@ -432,7 +432,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
template bindingRet(res) =
|
template bindingRet(res) =
|
||||||
when res == isGeneric: put(c.bindings, f, aOrig)
|
when res == isGeneric: put(c.bindings, f, aOrig)
|
||||||
return res
|
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
|
case a.kind
|
||||||
of tyOr:
|
of tyOr:
|
||||||
# seq[int|string] vs seq[number]
|
# 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
|
if a.kind == tyEmpty: result = isEqual
|
||||||
|
|
||||||
of tyGenericInst:
|
of tyGenericInst:
|
||||||
if a.kind == tyGenericInst and a.base == f.base:
|
let roota = a.skipGenericAlias
|
||||||
for i in 1 .. f.sonsLen-2:
|
let rootf = f.skipGenericAlias
|
||||||
result = typeRel(c, f.sons[i], a.sons[i])
|
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
|
if result == isNone: return
|
||||||
result = isGeneric
|
result = isGeneric
|
||||||
else:
|
else:
|
||||||
result = typeRel(c, lastSon(f), a)
|
result = typeRel(c, lastSon(f), a)
|
||||||
|
|
||||||
of tyGenericBody:
|
of tyGenericBody:
|
||||||
if a.kind == tyGenericInst and a.sons[0] == f:
|
considerPreviousT:
|
||||||
return isGeneric
|
if a.kind == tyGenericInst and a.sons[0] == f:
|
||||||
let ff = lastSon(f)
|
bindingRet isGeneric
|
||||||
if ff != nil: result = typeRel(c, ff, a)
|
let ff = lastSon(f)
|
||||||
|
if ff != nil: result = typeRel(c, ff, a)
|
||||||
|
|
||||||
of tyGenericInvokation:
|
of tyGenericInvokation:
|
||||||
var x = a.skipGenericAlias
|
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)
|
put(c.bindings, f.sons[i], x)
|
||||||
|
|
||||||
of tyAnd:
|
of tyAnd:
|
||||||
for branch in f.sons:
|
considerPreviousT:
|
||||||
if typeRel(c, branch, aOrig) == isNone:
|
for branch in f.sons:
|
||||||
return isNone
|
if typeRel(c, branch, aOrig) == isNone:
|
||||||
|
return isNone
|
||||||
|
|
||||||
bindingRet isGeneric
|
bindingRet isGeneric
|
||||||
|
|
||||||
of tyOr:
|
of tyOr:
|
||||||
for branch in f.sons:
|
considerPreviousT:
|
||||||
if typeRel(c, branch, aOrig) != isNone:
|
for branch in f.sons:
|
||||||
bindingRet isGeneric
|
if typeRel(c, branch, aOrig) != isNone:
|
||||||
|
bindingRet isGeneric
|
||||||
return isNone
|
|
||||||
|
return isNone
|
||||||
|
|
||||||
of tyNot:
|
of tyNot:
|
||||||
for branch in f.sons:
|
considerPreviousT:
|
||||||
if typeRel(c, branch, aOrig) != isNone:
|
for branch in f.sons:
|
||||||
return isNone
|
if typeRel(c, branch, aOrig) != isNone:
|
||||||
|
return isNone
|
||||||
bindingRet isGeneric
|
|
||||||
|
bindingRet isGeneric
|
||||||
|
|
||||||
of tyAnything:
|
of tyAnything:
|
||||||
var prev = PType(idTableGet(c.bindings, f))
|
considerPreviousT:
|
||||||
if prev == nil:
|
|
||||||
var concrete = concreteType(c, a)
|
var concrete = concreteType(c, a)
|
||||||
if concrete != nil and doBind:
|
if concrete != nil and doBind:
|
||||||
put(c.bindings, f, concrete)
|
put(c.bindings, f, concrete)
|
||||||
return isGeneric
|
return isGeneric
|
||||||
else:
|
|
||||||
return typeRel(c, prev, a)
|
|
||||||
|
|
||||||
of tyBuiltInTypeClass:
|
of tyBuiltInTypeClass:
|
||||||
var prev = PType(idTableGet(c.bindings, f))
|
considerPreviousT:
|
||||||
if prev == nil:
|
|
||||||
let targetKind = f.sons[0].kind
|
let targetKind = f.sons[0].kind
|
||||||
if targetKind == a.skipTypes({tyRange, tyGenericInst}).kind or
|
if targetKind == a.skipTypes({tyRange, tyGenericInst}).kind or
|
||||||
(targetKind in {tyProc, tyPointer} and a.kind == tyNil):
|
(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
|
return isGeneric
|
||||||
else:
|
else:
|
||||||
return isNone
|
return isNone
|
||||||
else:
|
|
||||||
result = typeRel(c, prev, a)
|
|
||||||
|
|
||||||
of tyCompositeTypeClass:
|
of tyCompositeTypeClass:
|
||||||
var prev = PType(idTableGet(c.bindings, f))
|
considerPreviousT:
|
||||||
if prev == nil:
|
|
||||||
if typeRel(c, f.sons[1], a) != isNone:
|
if typeRel(c, f.sons[1], a) != isNone:
|
||||||
put(c.bindings, f, a)
|
put(c.bindings, f, a)
|
||||||
return isGeneric
|
return isGeneric
|
||||||
else:
|
else:
|
||||||
return isNone
|
return isNone
|
||||||
else:
|
|
||||||
result = typeRel(c, prev, a)
|
|
||||||
|
|
||||||
of tyGenericParam, tyTypeClass:
|
of tyGenericParam, tyTypeClass:
|
||||||
var x = PType(idTableGet(c.bindings, f))
|
var x = PType(idTableGet(c.bindings, f))
|
||||||
|
|
|
||||||
|
|
@ -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 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]))
|
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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue