From b18fef7bcd600aea1cd3a54cb533e93fdd6cf223 Mon Sep 17 00:00:00 2001 From: bung Date: Thu, 25 May 2023 21:21:43 +0800 Subject: [PATCH 1/2] fix #10833 type expected error for proc resolution with static[int] --- compiler/semcall.nim | 3 ++- compiler/semdata.nim | 1 + compiler/semexprs.nim | 3 ++- tests/generics/t10833.nim | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/generics/t10833.nim 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..0753240a2fe6 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) 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..eec2c15b446b --- /dev/null +++ b/tests/generics/t10833.nim @@ -0,0 +1,16 @@ +type Foo*[A; B; C: static[int]] = object + s: string +# d: typeof(C) + +proc build*[A; B; C: static[int]](s: string;): Foo[A, B, C] = + const d = C + result.s = s + +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" \ No newline at end of file From e40c35f861365f5f8de830644bde15595465c838 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Sep 2022 20:24:41 +0800 Subject: [PATCH 2/2] add more test cases --- compiler/semexprs.nim | 2 +- tests/generics/t10833.nim | 7 +++++-- tests/generics/t10833_2.nim | 27 +++++++++++++++++++++++++++ tests/generics/t10833_3.nim | 27 +++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 tests/generics/t10833_2.nim create mode 100644 tests/generics/t10833_3.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 0753240a2fe6..ca3f3772da6b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1294,7 +1294,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = else: result = newSymNode(s, n.info) of tyStatic: let staticDuringGenericInst = (c.inStaticContext > 0 and c.inGenericInst > 0) - if (c.inExplicitGenericSym <= 0 or staticDuringGenericInst) and typ.n != nil: + 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 index eec2c15b446b..bb815ee97a8b 100644 --- a/tests/generics/t10833.nim +++ b/tests/generics/t10833.nim @@ -1,10 +1,12 @@ type Foo*[A; B; C: static[int]] = object s: string -# d: typeof(C) + 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") @@ -13,4 +15,5 @@ type Bar = object Baz = object let r = build[Bar, Baz, 1]() -doAssert r.s == "foo" \ No newline at end of file +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