From 10eabec6d442cb32c2c74f7c56cc9fff3be40104 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 14 Apr 2020 06:00:02 -0700 Subject: [PATCH] fix #12864 static params were mutating arg types during sigmatch; fix #12713 ; refs #13529 (#13976) * fix #12864 static params were mutating arg types during sigmatch * fix test * fix StaticParam * also fixes #12713; added test case --- compiler/sigmatch.nim | 1 + lib/pure/typetraits.nim | 9 +++--- tests/metatype/tstaticparams.nim | 24 ++++++++++++++++ tests/metatype/ttypetraits.nim | 1 + tests/statictypes/t9255.nim | 2 +- tests/statictypes/tstatictypes.nim | 46 ++++++++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 6 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 04ceb47b82..d819afb425 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -2004,6 +2004,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, let typ = newTypeS(tyStatic, c) typ.sons = @[evaluated.typ] typ.n = evaluated + arg = copyTree(arg) # fix #12864 arg.typ = typ a = typ else: diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 8f83a9dda9..84d57a45e2 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -93,7 +93,7 @@ since (1, 1): # Note: `[]` currently gives: `Error: no generic parameters allowed for ...` type(default(T)[i]) - type StaticParam*[value] = object + type StaticParam*[value: static type] = object ## used to wrap a static value in `genericParams` # NOTE: See https://github.com/nim-lang/Nim/issues/13758 - `import std/macros` does not work on OpenBSD @@ -118,13 +118,12 @@ macro genericParamsImpl(T: typedesc): untyped = let ai = impl[i] var ret: NimNode case ai.typeKind - of ntyStatic: - since (1, 1): - ret = newTree(nnkBracketExpr, @[bindSym"StaticParam", ai]) of ntyTypeDesc: ret = ai + of ntyStatic: doAssert false else: - assert false, $(ai.typeKind, ai.kind) + since (1, 1): + ret = newTree(nnkBracketExpr, @[bindSym"StaticParam", ai]) result.add ret break else: diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index 09d505f941..de80d46ae8 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -171,3 +171,27 @@ echo inSize([ [1, 2, 3], [4, 5, 6] ]) + +block: # #12864 + template fun() = + type Object = object + proc fun(f: Object): int = 1 + proc fun(f: static[int]): int = 2 + doAssert fun(Object()) == 1 + + var a: Object + doAssert fun(a) == 1 + + proc fun2(f: Object): int = 1 + proc fun2(f: static[Object]): int = 2 + doAssert fun2(Object()) == 2 + doAssert fun2(a) == 1 + const a2 = Object() + doAssert fun2(a2) == 2 + + fun() + static: fun() + +when true: #12864 original snippet + import times + discard times.format(initDateTime(30, mMar, 2017, 0, 0, 0, 0, utc()), TimeFormat()) diff --git a/tests/metatype/ttypetraits.nim b/tests/metatype/ttypetraits.nim index db8c8e5de5..eb2384afbe 100644 --- a/tests/metatype/ttypetraits.nim +++ b/tests/metatype/ttypetraits.nim @@ -145,6 +145,7 @@ block genericParams: doAssert genericParams(Bar3).get(0) is StaticParam doAssert genericParams(Bar3).get(0).value == 3 doAssert genericParams(Bar[3, float]).get(0).value == 3 + static: doAssert genericParams(Bar[3, float]).get(0).value == 3 type VectorElementType = SomeNumber | bool diff --git a/tests/statictypes/t9255.nim b/tests/statictypes/t9255.nim index 86bc8c7f1b..99ca2a23c5 100644 --- a/tests/statictypes/t9255.nim +++ b/tests/statictypes/t9255.nim @@ -1,6 +1,6 @@ discard """ errormsg: ''' -type mismatch: got +type mismatch: got ''' line: 13 """ diff --git a/tests/statictypes/tstatictypes.nim b/tests/statictypes/tstatictypes.nim index afd15b67d6..1aab6e1241 100644 --- a/tests/statictypes/tstatictypes.nim +++ b/tests/statictypes/tstatictypes.nim @@ -170,3 +170,49 @@ var s: StringValue16 echo s + +block: #13529 + block: + type Foo[T: static type] = object + var foo: Foo["test"] + doAssert $foo == "()" + doAssert foo.T is string + static: doAssert foo.T == "test" + doAssert not compiles( + block: + type Foo2[T: static type] = object + x: T) + + block: + type Foo[T: static[float]] = object + var foo: Foo[1.2] + doAssert $foo == "()" + doAssert foo.T == 1.2 + + block: # routines also work + proc fun(a: static) = (const a2 = a) + fun(1) + fun(1.2) + block: # routines also work + proc fun(a: static type) = (const a2 = a) + fun(1) + fun(1.2) + + block: # this also works + proc fun[T](a: static[T]) = (const a2 = a) + fun(1) + fun(1.2) + +block: # #12713 + block: + type Cell = object + c: int + proc test(c: static string) = discard #Remove this and it compiles + proc test(c: Cell) = discard + test Cell(c: 0) + block: + type Cell = object + c: int + proc test(c: static string) = discard #Remove this and it compiles + proc test(c: Cell) = discard + test Cell()