diff options
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/semexprs.nim | 19 | ||||
-rw-r--r-- | compiler/semtypes.nim | 5 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 24 | ||||
-rw-r--r-- | compiler/types.nim | 9 | ||||
-rw-r--r-- | tests/metatype/tusertypeclasses.nim | 13 |
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)) + |