fixes #186 and the ttypedesc1 test case

This commit is contained in:
Zahary Karadjov
2012-09-23 19:33:54 +03:00
parent 15dcb9a6a6
commit 27dc9fcb8f
5 changed files with 30 additions and 28 deletions

View File

@@ -121,7 +121,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
# this is a hotspot in the compiler
initLocExpr(p, ri.sons[0], op)
var pl = con(op.r, "(")
var params: PRope
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
@@ -129,13 +129,13 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
for i in countup(1, length - 1):
assert(sonsLen(typ) == sonsLen(typ.n))
if ri.sons[i].typ.isCompileTimeOnly: continue
if params != nil: app(params, ", ")
if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym)
app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym))
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym))
else:
app(pl, genArgNoParam(p, ri.sons[i]))
if i < length - 1: app(pl, ", ")
fixupCall(p, le, ri, d, pl)
app(params, genArgNoParam(p, ri.sons[i]))
fixupCall(p, le, ri, d, con(op.r, "(".toRope, params))
proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =

View File

@@ -290,6 +290,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
if t.n.sons[i].kind != nkSym: InternalError(t.n.info, "genProcParams")
var param = t.n.sons[i].sym
if isCompileTimeOnly(param.typ): continue
if params != nil: app(params, ", ")
fillLoc(param.loc, locParam, param.typ, mangleName(param), OnStack)
app(params, getParamTypeDesc(m, param.typ, check))
if ccgIntroducedPtr(param):
@@ -309,7 +310,6 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
appff(params, ", NI $1Len$2", ", @NI $1Len$2", [param.loc.r, j.toRope])
inc(j)
arr = arr.sons[0]
if i < sonsLen(t.n) - 1: app(params, ", ")
if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
var arr = t.sons[0]
if params != nil: app(params, ", ")

View File

@@ -257,31 +257,31 @@ proc tupleRel(c: var TCandidate, f, a: PType): TTypeRelation =
var y = a.n.sons[i].sym
if x.name.id != y.name.id: return isNone
proc matchTypeClass(c: var TCandidate, f, a: PType): TTypeRelation =
for i in countup(0, f.sonsLen - 1):
let son = f.sons[i]
var match = son.kind == skipTypes(a, {tyRange, tyGenericInst}).kind
proc matchTypeClass(c: var TCandidate, typeClass, t: PType): TTypeRelation =
for i in countup(0, typeClass.sonsLen - 1):
let req = typeClass.sons[i]
var match = req.kind == skipTypes(t, {tyRange, tyGenericInst}).kind
if not match:
case son.kind
case req.kind
of tyGenericBody:
if a.kind == tyGenericInst and a.sons[0] == son:
if t.kind == tyGenericInst and t.sons[0] == req:
match = true
put(c.bindings, f, a)
put(c.bindings, typeClass, t)
of tyTypeClass:
match = matchTypeClass(c, son, a) == isGeneric
match = matchTypeClass(c, req, t) == isGeneric
else: nil
elif t.kind in {tyTypeDesc, tyObject}:
match = sameType(t, req)
if tfAny in f.flags:
if match:
return isGeneric
if tfAny in typeClass.flags:
if match: return isGeneric
else:
if not match:
return isNone
if not match: return isNone
# if the loop finished without returning, either all constraints matched
# or none of them matched.
result = if tfAny in f.flags: isNone else: isGeneric
result = if tfAny in typeClass.flags: isNone else: isGeneric
proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
proc inconsistentVarTypes(f, a: PType): bool {.inline.} =

View File

@@ -431,7 +431,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
add(result, typeToString(t.sons[i]))
add(result, ']')
of tyTypeDesc:
if t.sons.len == 0: result = "typedesc"
if t.sons == nil or t.sons.len == 0: result = "typedesc"
else: result = "typedesc[" & constraintsToStr(t) & "]"
of tyTypeClass:
result = constraintsToStr(t)

View File

@@ -19,16 +19,18 @@ proc foo(T: typedesc[int or bool]): string =
template foo(T: typedesc[seq]): expr = "seq"
test "types can be used as proc params":
check foo(TFoo[int, float], 1000) == "TFoo 1000"
# XXX: `check` needs to know that TFoo[int, float] is a type and
# cannot be assigned for a local variable for later inspection
check ((foo(TFoo[int, float], 1000) == "TFoo 1000"))
var f = 10.0
check foo(float, "long string") == "float true"
check foo(type(f), [1, 2, 3]) == "float false"
check ((foo(float, "long string") == "float true"))
check ((foo(type(f), [1, 2, 3]) == "float false"))
check foo(int) == "int or bool 10"
check ((foo(int) == "int or bool 10"))
check foo(seq[int]) == "seq"
check foo(seq[TFoo[bool, string]]) == "seq"
check ((foo(seq[int]) == "seq"))
check ((foo(seq[TFoo[bool, string]]) == "seq"))
when false:
proc foo(T: typedesc[seq], s: T) = nil