diff options
-rw-r--r-- | compiler/semexprs.nim | 15 | ||||
-rw-r--r-- | tests/compile/tgenericdefaults.nim | 29 | ||||
-rw-r--r-- | tests/compile/ttypeclasses.nim | 21 | ||||
-rw-r--r-- | tests/run/tstaticparams.nim | 17 |
4 files changed, 78 insertions, 4 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index daad93a85..0ac71bedf 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -111,7 +111,11 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # var len = 0 # but won't be called # genericThatUsesLen(x) # marked as taking a closure? of skGenericParam: - if s.ast != nil: result = semExpr(c, s.ast) + if s.typ.kind == tyExpr: + result = newSymNode(s, n.info) + result.typ = s.typ.lastSon + elif s.ast != nil: + result = semExpr(c, s.ast) else: InternalError(n.info, "no default for") result = emptyNode @@ -883,10 +887,13 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = let tbody = ty.sons[0] for s in countup(0, tbody.len-2): let tParam = tbody.sons[s] - assert tParam.kind == tyGenericParam if tParam.sym.name == i: - let foundTyp = makeTypeDesc(c, ty.sons[s + 1]) - return newSymNode(copySym(tParam.sym).linkTo(foundTyp), n.info) + let rawTyp = ty.sons[s + 1] + if rawTyp.kind == tyExpr: + return rawTyp.n + else: + let foundTyp = makeTypeDesc(c, rawTyp) + return newSymNode(copySym(tParam.sym).linkTo(foundTyp), n.info) return else: # echo "TYPE FIELD ACCESS" diff --git a/tests/compile/tgenericdefaults.nim b/tests/compile/tgenericdefaults.nim new file mode 100644 index 000000000..ad96f1851 --- /dev/null +++ b/tests/compile/tgenericdefaults.nim @@ -0,0 +1,29 @@ +type + TFoo[T, U, R = int] = object + x: T + y: U + z: R + + TBar[T] = TFoo[T, array[4, T], T] + +var x1: TFoo[int, float] + +static: + assert type(x1.x) is int + assert type(x1.y) is float + assert type(x1.z) is int + +var x2: TFoo[string, R = float, U = seq[int]] + +static: + assert type(x2.x) is string + assert type(x2.y) is seq[int] + assert type(x2.z) is float + +var x3: TBar[float] + +static: + assert type(x3.x) is float + assert type(x3.y) is array[4, float] + assert type(x3.z) is float + diff --git a/tests/compile/ttypeclasses.nim b/tests/compile/ttypeclasses.nim index 5e23e8489..677229868 100644 --- a/tests/compile/ttypeclasses.nim +++ b/tests/compile/ttypeclasses.nim @@ -5,6 +5,8 @@ type T1 = expr T2 = expr + Numeric = int|float + proc takesExpr(x, y) = echo x, y @@ -32,3 +34,22 @@ takesFoo(f, f) takes2Types(1, 1, "string") takes2Types[string, int]("test", "test", 1) +proc takesSeq(x: seq) = + echo "seq" + +takesSeq(@[1, 2, 3]) +takesSeq(@["x", "y", "z"]) + +proc takesSeqOfFoos(x: seq[TFoo]) = + echo "foo seq" + +var sf = newSeq[TFoo[int]](3) + +takesSeq(sf) +takesSeqOfFoos(sf) + +proc takesFooOfNumeric(x: TFoo[Numeric]) = + echo "foo of numeric" + +takesFooOfNumeric(sf[0]) + diff --git a/tests/run/tstaticparams.nim b/tests/run/tstaticparams.nim new file mode 100644 index 000000000..3e501ed8b --- /dev/null +++ b/tests/run/tstaticparams.nim @@ -0,0 +1,17 @@ +discard """ + file: "tstaticparams.nim" + output: "abracadabra\ntest" +""" + +type + TFoo[T; Val: expr[string]] = object + data: array[4, T] + +proc takeFoo(x: TFoo) = + echo "abracadabra" + echo TFoo.Val + +var x: TFoo[int, "test"] + +takeFoo(x) + |