mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-16 08:04:20 +00:00
fixes #186 and the ttypedesc1 test case
This commit is contained in:
@@ -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) =
|
||||
|
||||
|
||||
@@ -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, ", ")
|
||||
|
||||
@@ -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.} =
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user