From 644d645ea774dc667feaf5cf8f45035a328a7b5a Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 12 Aug 2016 16:45:28 +0300 Subject: [PATCH] implement the special treatment of explicit type params in concepts --- compiler/ast.nim | 2 ++ compiler/semmagic.nim | 2 +- compiler/semtypes.nim | 1 + compiler/sigmatch.nim | 4 +++- tests/concepts/tmatrixconcept.nim | 2 +- tests/concepts/tusertypeclasses.nim | 14 ++++++++++++-- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 5adac92dfe..78c2a6087c 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -494,6 +494,8 @@ type tfGenericTypeParam tfImplicitTypeParam tfInferrableStatic + tfExplicit # for typedescs, marks types explicitly prefixed with the + # `type` operator (e.g. type int) tfWildcard # consider a proc like foo[T, I](x: Type[T, I]) # T and I here can bind to both typedesc and static types # before this is determined, we'll consider them to be a diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 5eed1e7025..e4ae60aba2 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -24,7 +24,7 @@ proc semTypeOf(c: PContext; n: PNode): PNode = result = newNodeI(nkTypeOfExpr, n.info) let typExpr = semExprWithType(c, n, {efInTypeof}) result.add typExpr - result.typ = makeTypeDesc(c, typExpr.typ.skipTypes({tyTypeDesc})) + result.typ = makeTypeDesc(c, typExpr.typ) type SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index eef83c2a72..082fa8dc1c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1239,6 +1239,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = let typExpr = semExprWithType(c, n.sons[0], {efInTypeof}) fixupTypeOf(c, prev, typExpr) result = typExpr.typ + if result.kind == tyTypeDesc: result.flags.incl tfExplicit of nkPar: if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) else: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ca9cdcaf8a..a46f03ff64 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -638,6 +638,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, if modifier != tyNone: dummyName = param[0] dummyType = c.makeTypeWithModifier(modifier, a) + if modifier == tyTypeDesc: dummyType.flags.incl tfExplicit else: dummyName = param dummyType = a @@ -833,7 +834,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = var useTypeLoweringRuleInTypeClass = c.c.inTypeClass > 0 and not c.isNoCall and - f.kind != tyTypeDesc + f.kind != tyTypeDesc and + tfExplicit notin aOrig.flags aOrig = if useTypeLoweringRuleInTypeClass: aOrig.skipTypes({tyTypeDesc, tyFieldAccessor}) diff --git a/tests/concepts/tmatrixconcept.nim b/tests/concepts/tmatrixconcept.nim index 4bc002dd45..cbb40f791c 100644 --- a/tests/concepts/tmatrixconcept.nim +++ b/tests/concepts/tmatrixconcept.nim @@ -25,7 +25,7 @@ type # more complicated static param inference cases m.data is array[TotalElements, T] - M.foo(array[0..FromFoo, type m[int, 10]]) + m.foo(array[0..FromFoo, type m[int, 10]]) MyMatrix[M, K: static[int]; T] = object data: array[M*K, T] diff --git a/tests/concepts/tusertypeclasses.nim b/tests/concepts/tusertypeclasses.nim index e1aaa851cd..533bd528d3 100644 --- a/tests/concepts/tusertypeclasses.nim +++ b/tests/concepts/tusertypeclasses.nim @@ -15,6 +15,9 @@ type TObj = object x: int + JSonValue = object + val: string + Sortable = concept x, y (x < y) is bool @@ -49,9 +52,14 @@ type staticproc(static[T]) + typeproc T + T.typeproc typeproc o.type o.type.typeproc + o.to(type string) + o.to(type JsonValue) + refproc(r, intref) varproc(v) p.ptrproc(string) @@ -59,9 +67,9 @@ type typeproc(T) const TypeName = T.name - type MappedType = type(T.y) + type MappedType = type(o.y) - intval T.y + intval y(o) let z = intval(o.y) static: @@ -80,6 +88,8 @@ proc refproc(x: ref TObj, y: ref int) = discard proc ptrproc(x: ptr TObj, y: string) = discard proc staticproc(x: static[TObj]) = discard proc typeproc(t: type TObj) = discard +proc to(x: TObj, t: type string) = discard +proc to(x: TObj, t: type JSonValue) = discard proc testFoo(x: TFoo) = echo x.TypeName