diff options
-rw-r--r-- | compiler/semtypes.nim | 6 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 8 | ||||
-rw-r--r-- | tests/metatype/ttypedesc2.nim | 24 |
3 files changed, 35 insertions, 3 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 0e2421e8b..4d628e6ec 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1040,6 +1040,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tyGenericInvocation: for i in 1 ..< paramType.len: + #if paramType[i].kind != tyTypeDesc: let lifted = recurse(paramType.sons[i]) if lifted != nil: paramType.sons[i] = lifted @@ -1355,7 +1356,10 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = for i in 1 ..< m.call.len: var typ = m.call[i].typ - if typ.kind == tyTypeDesc and typ.sons[0].kind == tyNone: + # is this a 'typedesc' *parameter*? If so, use the typedesc type, + # unstripped. + if m.call[i].kind == nkSym and m.call[i].sym.kind == skParam and + typ.kind == tyTypeDesc and containsGenericType(typ): isConcrete = false addToResult(typ) else: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 952c8f991..327537595 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1654,8 +1654,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyGenericParam: var x = PType(idTableGet(c.bindings, f)) if x == nil: - if c.callee.kind == tyGenericBody and - f.kind == tyGenericParam and not c.typedescMatched: + if c.callee.kind == tyGenericBody and not c.typedescMatched: # XXX: The fact that generic types currently use tyGenericParam for # their parameters is really a misnomer. tyGenericParam means "match # any value" and what we need is "match any type", which can be encoded @@ -1700,6 +1699,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, c.inheritancePenalty = oldInheritancePenalty - c.inheritancePenalty - 100 * ord(result == isEqual) result = isGeneric + elif a.kind == tyTypeDesc: + # somewhat special typing rule, the following is illegal: + # proc p[T](x: T) + # p(int) + result = isNone else: result = isGeneric diff --git a/tests/metatype/ttypedesc2.nim b/tests/metatype/ttypedesc2.nim index 94a7367e7..37399784b 100644 --- a/tests/metatype/ttypedesc2.nim +++ b/tests/metatype/ttypedesc2.nim @@ -48,3 +48,27 @@ doAssert hasDefault2(int) == "int" doAssert hasDefault2(string) == "string" doAssert hasDefault2() == "string" + +# bug #9195 +type + Error = enum + erA, erB, erC + Result[T, U] = object + x: T + u: U + PB = object + +proc decodeUVarint*(itzzz: typedesc[SomeUnsignedInt], + data: openArray[char]): Result[itzzz, Error] = + result = Result[itzzz, Error](x: 0, u: erC) + +discard decodeUVarint(uint32, "abc") + +type + X = object + Y[T] = object + +proc testObj(typ: typedesc[object]): Y[typ] = + discard + +discard testObj(X) |