summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semdata.nim1
-rw-r--r--compiler/semexprs.nim19
-rw-r--r--compiler/semtypes.nim5
-rw-r--r--compiler/sigmatch.nim24
-rw-r--r--compiler/types.nim9
-rw-r--r--tests/metatype/tusertypeclasses.nim13
6 files changed, 39 insertions, 32 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 0bc52d6b7..234526054 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -213,7 +213,6 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
 
 proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
   let typedesc = makeTypeDesc(c, typ)
-  rawAddSon(typedesc, newTypeS(tyNone, c))
   let sym = newSym(skType, idAnon, getCurrOwner(), info).linkTo(typedesc)
   return newSymNode(sym, info)
 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 30ab344c2..f09ee1295 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -346,22 +346,21 @@ proc semIs(c: PContext, n: PNode): PNode =
 
   result = n
   n.typ = getSysType(tyBool)
-  
-  n.sons[1] = semExprWithType(c, n[1], {efDetermineType})
-  
+ 
+  n.sons[1] = semExprWithType(c, n[1], {efDetermineType, efWantIterator})
   if n[2].kind notin {nkStrLit..nkTripleStrLit}:
     let t2 = semTypeNode(c, n[2], nil)
     n.sons[2] = newNodeIT(nkType, n[2].info, t2)
 
-  if n[1].typ.kind != tyTypeDesc:
-    n.sons[1] = makeTypeSymNode(c, n[1].typ, n[1].info)
-  elif n[1].typ.sonsLen == 0:
+  let lhsType = n[1].typ
+  if lhsType.kind != tyTypeDesc:
+    n.sons[1] = makeTypeSymNode(c, lhsType, n[1].info)
+  elif lhsType.base.kind == tyNone:
     # this is a typedesc variable, leave for evals
     return
 
-  let t1 = n[1].typ.sons[0]
   # BUGFIX: don't evaluate this too early: ``T is void``
-  if not containsGenericType(t1): result = isOpImpl(c, n)
+  if not n[1].typ.base.containsGenericType: result = isOpImpl(c, n)
 
 proc semOpAux(c: PContext, n: PNode) =
   const flags = {efDetermineType}
@@ -918,8 +917,8 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
   var ty = n.sons[0].typ
   var f: PSym = nil
   result = nil
-  if isTypeExpr(n.sons[0]) or ty.kind == tyTypeDesc and ty.len == 1:
-    if ty.kind == tyTypeDesc: ty = ty.sons[0]
+  if isTypeExpr(n.sons[0]) or ty.kind == tyTypeDesc and ty.base.kind != tyNone:
+    if ty.kind == tyTypeDesc: ty = ty.base
     case ty.kind
     of tyEnum:
       # look up if the identifier belongs to the enum:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 44e414e9c..184aca4f8 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1030,9 +1030,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
       if s.kind != skError: localError(n.info, errTypeExpected)
       result = newOrPrevType(tyError, prev, c)
     elif s.kind == skParam and s.typ.kind == tyTypeDesc:
-      assert s.typ.len > 0
-      internalAssert prev == nil
-      result = s.typ.sons[0]
+      internalAssert s.typ.base.kind != tyNone and prev == nil
+      result = s.typ.base
     elif prev == nil:
       result = s.typ
     else: 
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 227228f6e..fce0bdf48 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -866,7 +866,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
           else:
             internalAssert a.sons != nil and a.sons.len > 0
             c.typedescMatched = true
-            result = typeRel(c, f.sons[0], a.sons[0])
+            result = typeRel(c, f.base, a.base)
         else:
           result = isNone
       else:
@@ -896,22 +896,20 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
       result = isNone
 
   of tyTypeDesc:
+    if a.kind != tyTypeDesc: return isNone
+    
     var prev = PType(idTableGet(c.bindings, f))
     if prev == nil:
-      if a.kind == tyTypeDesc:
-        if f.sons[0].kind == tyNone:
-          result = isGeneric
-        else:
-          result = typeRel(c, f.sons[0], a.sons[0])
-        if result != isNone:
-          put(c.bindings, f, a)
+      if f.base.kind == tyNone:
+        result = isGeneric
       else:
-        result = isNone
+        result = typeRel(c, f.base, a.base)
+      if result != isNone:
+        put(c.bindings, f, a)
     else:
-      internalAssert prev.sonsLen == 1
       let toMatch = if tfUnresolved in f.flags: a
-                    else: a.sons[0]
-      result = typeRel(c, prev.sons[0], toMatch)
+                    else: a.base
+      result = typeRel(c, prev.base, toMatch)
   
   of tyStmt:
     result = isGeneric
@@ -1015,7 +1013,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
       argType = arg.typ
  
   var
-    a = if c.inTypeClass > 0: argType.skipTypes({tyTypeDesc})
+    a = if c.inTypeClass > 0: argType.skipTypes({tyTypeDesc, tyFieldAccessor})
         else: argType
  
     r = typeRel(m, f, a)
diff --git a/compiler/types.nim b/compiler/types.nim
index db75cd3c0..ef73ea783 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -431,8 +431,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
       add(result, typeToString(t.sons[i]))
     add(result, ']')
   of tyTypeDesc:
-    if t.len == 0: result = "typedesc"
-    else: result = "typedesc[" & typeToString(t.sons[0]) & "]"
+    if t.base.kind == tyNone: result = "typedesc"
+    else: result = "typedesc[" & typeToString(t.base) & "]"
   of tyStatic:
     internalAssert t.len > 0
     result = "static[" & typeToString(t.sons[0]) & "]"
@@ -1231,8 +1231,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
   of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter:
     result = computeSizeAux(lastSon(typ), a)
   of tyTypeDesc:
-    result = if typ.len == 1: computeSizeAux(typ.sons[0], a)
-             else: szUnknownSize
+    result = computeSizeAux(typ.base, a)
   of tyForward: return szIllegalRecursion
   else:
     #internalError("computeSizeAux()")
@@ -1258,7 +1257,7 @@ proc containsGenericTypeIter(t: PType, closure: PObject): bool =
     return true
 
   if t.kind == tyTypeDesc:
-    if t.sons[0].kind == tyNone: return true
+    if t.base.kind == tyNone: return true
     if containsGenericTypeIter(t.base, closure): return true
     return false
   
diff --git a/tests/metatype/tusertypeclasses.nim b/tests/metatype/tusertypeclasses.nim
index 4c2f07b85..4c8c0fc56 100644
--- a/tests/metatype/tusertypeclasses.nim
+++ b/tests/metatype/tusertypeclasses.nim
@@ -26,3 +26,16 @@ foo 10
 foo "test"
 foo(@[TObj(x: 10), TObj(x: 20)])
 
+proc intval(x: int) = discard
+
+# check real and virtual fields
+type
+  TFoo = generic T
+    intval T.x
+    intval T.y
+
+proc y(x: TObj): int = 10
+
+proc testFoo(x: TFoo) = discard
+testFoo(TObj(x: 10))
+