diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 8445b25e71b8..fd0b6a109ab8 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -641,7 +641,7 @@ proc explicitGenericInstError(c: PContext; n: PNode): PNode = proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = # binding has to stay 'nil' for this to work! var m = newCandidate(c, s, nil) - + inc c.inExplicitGenericSym for i in 1.. 0 if we are in a ``compiles`` magic compilesContextIdGenerator*: int inGenericInst*: int # > 0 if we are instantiating a generic + inExplicitGenericSym*: int converters*: seq[PSym] patterns*: seq[PSym] # sequence of pattern matchers optionStack*: seq[POptionEntry] diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index ae118159cf0c..ca3f3772da6b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1293,7 +1293,8 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = if s.astdef.safeLen == 0: result = inlineConst(c, n, s) else: result = newSymNode(s, n.info) of tyStatic: - if typ.n != nil: + let staticDuringGenericInst = (c.inStaticContext > 0 and c.inGenericInst > 0) + if (c.inExplicitGenericSym <= 0 or staticDuringGenericInst or efInTypeof in flags) and typ.n != nil: result = typ.n result.typ = typ.base else: diff --git a/tests/generics/t10833.nim b/tests/generics/t10833.nim new file mode 100644 index 000000000000..bb815ee97a8b --- /dev/null +++ b/tests/generics/t10833.nim @@ -0,0 +1,19 @@ +type Foo*[A; B; C: static[int]] = object + s: string + f: typeof(C) + +proc build*[A; B; C: static[int]](s: string;): Foo[A, B, C] = + const d = C + doAssert d == 1 + result.s = s + result.f = C + +proc build*[A; B; C: static[int]](): Foo[A, B, C] = + build[A, B, C]("foo") + +type + Bar = object + Baz = object +let r = build[Bar, Baz, 1]() +doAssert r.s == "foo" +doAssert r.f == 1 diff --git a/tests/generics/t10833_2.nim b/tests/generics/t10833_2.nim new file mode 100644 index 000000000000..0471b3ba86bb --- /dev/null +++ b/tests/generics/t10833_2.nim @@ -0,0 +1,27 @@ +type MyObject = object + x, y: int + s: string + +const c = MyObject(x: 1, y: 2, s: "") + +type Foo[A, B; C: static MyObject] = object + s: string + f: typeof(C) + +proc build*[A; B; C: static MyObject](s: string;): Foo[A, B, C] = + const d = C + doAssert d.x == c.x + doAssert d.x == 1 + result.f = d + result.s = s + +proc build*[A; B; C: static MyObject](): Foo[A, B, C] = + build[A, B, C]("foo") + +type + Bar = object + Baz = object + +let r = build[Bar, Baz, c]() +doAssert r.s == "foo" +doAssert r.f == c diff --git a/tests/generics/t10833_3.nim b/tests/generics/t10833_3.nim new file mode 100644 index 000000000000..1c703c9cadae --- /dev/null +++ b/tests/generics/t10833_3.nim @@ -0,0 +1,27 @@ +type MyObject = object + x, y: int + s: string + +const c = @[MyObject(x: 1, y: 2, s: "")] + +type Foo[A, B; C: static seq[MyObject]] = object + s: string + f: typeof(C) + +proc build*[A; B; C: static seq[MyObject]](s: string;): Foo[A, B, C] = + const d = C + doAssert d[0].x == c[0].x + doAssert d[0].x == 1 + result.f = d + result.s = s + +proc build*[A; B; C: static seq[MyObject]](): Foo[A, B, C] = + build[A, B, C]("foo") + +type + Bar = object + Baz = object + +let r = build[Bar, Baz, c]() +doAssert r.s == "foo" +doAssert r.f == c