diff options
Diffstat (limited to 'compiler/sigmatch.nim')
-rw-r--r-- | compiler/sigmatch.nim | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 19f10def8..662268380 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -522,8 +522,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = template bindingRet(res) = when res == isGeneric: - let bound = aOrig.skipTypes({tyRange}).skipIntLit - put(c.bindings, f, bound) + if doBind: + let bound = aOrig.skipTypes({tyRange}).skipIntLit + if doBind: put(c.bindings, f, bound) return res template considerPreviousT(body: stmt) {.immediate.} = @@ -620,8 +621,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: fRange = prev result = typeRel(c, f.sons[1], a.sons[1]) - if result < isGeneric: result = isNone - elif lengthOrd(fRange) != lengthOrd(a): result = isNone + if result < isGeneric: + result = isNone + elif lengthOrd(fRange) != lengthOrd(a): + result = isNone else: discard of tyOpenArray, tyVarargs: case a.kind @@ -867,7 +870,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # any value" and what we need is "match any type", which can be encoded # by a tyTypeDesc params. Unfortunately, this requires more substantial # changes in semtypinst and elsewhere. - if a.kind == tyTypeDesc: + if tfWildcard in a.flags: + result = isGeneric + elif a.kind == tyTypeDesc: if f.sonsLen == 0: result = isGeneric else: @@ -883,11 +888,16 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = result = isGeneric if result == isGeneric: - var concrete = concreteType(c, a) - if concrete == nil: - result = isNone + var concrete = a + if tfWildcard in a.flags: + a.sym.kind = skType + a.flags.excl tfWildcard else: - if doBind: put(c.bindings, f, concrete) + concrete = concreteType(c, a) + if concrete == nil: + return isNone + if doBind: + put(c.bindings, f, concrete) elif a.kind == tyEmpty: result = isGeneric elif x.kind == tyGenericParam: @@ -937,8 +947,19 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyProxy: result = isEqual + + of tyFromExpr: + # fix the expression, so it contains the already instantiated types + let instantiated = replaceTypesInBody(c.c, c.bindings, f.n) + let reevaluted = c.c.semExpr(c.c, instantiated) + if reevaluted.typ.kind != tyTypeDesc: + localError(f.n.info, errTypeExpected) + result = isNone + else: + result = typeRel(c, a, reevaluted.typ.base) - else: internalAssert false + else: + internalAssert false proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation = var m: TCandidate @@ -1025,17 +1046,31 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, arg = argSemantized argType = argType c = m.c - + if tfHasStatic in fMaybeStatic.flags: # XXX: When implicit statics are the default # this will be done earlier - we just have to # make sure that static types enter here - var evaluated = c.semTryConstExpr(c, arg) - if evaluated != nil: - arg.typ = newTypeS(tyStatic, c) - arg.typ.sons = @[evaluated.typ] - arg.typ.n = evaluated - argType = arg.typ + + # XXX: weaken tyGenericParam and call it tyGenericPlaceholder + # and finally start using tyTypedesc for generic types properly. + if argType.kind == tyGenericParam and tfWildcard in argType.flags: + argType.assignType(f) + # put(m.bindings, f, argType) + return argSemantized + + if argType.kind == tyStatic: + if m.calleeSym.kind == skType: + result = newNodeI(nkType, argOrig.info) + result.typ = makeTypeFromExpr(c, arg) + return + else: + var evaluated = c.semTryConstExpr(c, arg) + if evaluated != nil: + arg.typ = newTypeS(tyStatic, c) + arg.typ.sons = @[evaluated.typ] + arg.typ.n = evaluated + argType = arg.typ var a = if c.inTypeClass > 0: argType.skipTypes({tyTypeDesc, tyFieldAccessor}) |