summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semtypes.nim6
-rw-r--r--compiler/sigmatch.nim8
-rw-r--r--tests/metatype/ttypedesc2.nim24
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)