From 6e9988a195e95b5af731295d0255edec3793b908 Mon Sep 17 00:00:00 2001 From: metagn Date: Fri, 5 May 2023 08:28:06 +0300 Subject: [PATCH] consistent use of scForceOpen for generic dot field symbols (#21738) * always force open generic dot field symbols? fixes #21724 but might break code * alternative, should fix CI * other alternative, add test for previous CI failure * not needed * make sure call doesn't compile too * ok actual second test * ok final actual correct test * apply performance idea * don't make fromDotExpr static --- compiler/semgnrc.nim | 22 ++++++------- tests/generics/mdotlookup.nim | 5 +++ tests/generics/tbaddeprecated.nim | 55 +++++++++++++++++++++++++++++++ tests/generics/timports.nim | 3 +- 4 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 tests/generics/tbaddeprecated.nim diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7241a470205ae..543bd1132dc15 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -61,12 +61,19 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, fromDotExpr=false): PNode = semIdeForTemplateOrGenericCheck(c.config, n, ctx.cursorInBody) incl(s.flags, sfUsed) + template maybeDotChoice(c: PContext, n: PNode, s: PSym, fromDotExpr: bool) = + if fromDotExpr: + result = symChoice(c, n, s, scForceOpen) + if result.len == 1: + result.transitionSonsKind(nkClosedSymChoice) + else: + result = symChoice(c, n, s, scOpen) case s.kind of skUnknown: # Introduced in this pass! Leave it as an identifier. result = n - of skProc, skFunc, skMethod, skIterator, skConverter, skModule: - result = symChoice(c, n, s, scOpen) + of skProc, skFunc, skMethod, skIterator, skConverter, skModule, skEnumField: + maybeDotChoice(c, n, s, fromDotExpr) of skTemplate, skMacro: # alias syntax, see semSym for skTemplate, skMacro if sfNoalias notin s.flags and not fromDotExpr: @@ -79,7 +86,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, result = semGenericStmt(c, result, {}, ctx) discard c.friendModules.pop() else: - result = symChoice(c, n, s, scOpen) + maybeDotChoice(c, n, s, fromDotExpr) of skGenericParam: if s.typ != nil and s.typ.kind == tyStatic: if s.typ.n != nil: @@ -99,8 +106,6 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, else: result = n onUse(n.info, s) - of skEnumField: - result = symChoice(c, n, s, scOpen) else: result = newSymNode(s, n.info) onUse(n.info, s) @@ -157,12 +162,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, result = newDot(result, symChoice(c, n, s, scForceOpen)) else: let syms = semGenericStmtSymbol(c, n, s, ctx, flags, fromDotExpr=true) - if syms.kind == nkSym: - let choice = symChoice(c, n, s, scForceOpen) - choice.transitionSonsKind(nkClosedSymChoice) - result = newDot(result, choice) - else: - result = newDot(result, syms) + result = newDot(result, syms) proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) = let s = newSymS(skUnknown, getIdentNode(c, n), c) diff --git a/tests/generics/mdotlookup.nim b/tests/generics/mdotlookup.nim index 3112c133f1797..b69a56dafd8a0 100644 --- a/tests/generics/mdotlookup.nim +++ b/tests/generics/mdotlookup.nim @@ -14,3 +14,8 @@ var intset = initHashSet[int]() proc fn*[T](a: T) = if a in intset: echo("true") else: echo("false") + +import strutils + +proc doStrip*[T](a: T): string = + result = ($a).strip() diff --git a/tests/generics/tbaddeprecated.nim b/tests/generics/tbaddeprecated.nim new file mode 100644 index 0000000000000..335234a25b133 --- /dev/null +++ b/tests/generics/tbaddeprecated.nim @@ -0,0 +1,55 @@ +discard """ + output: ''' +not deprecated +not deprecated +not error +not error +''' +""" + +# issue #21724 + +block: # deprecated + {.push warningAsError[Deprecated]: on.} + type + SomeObj = object + hey: bool + proc hey() {.deprecated: "Shouldn't use this".} = echo "hey" + proc gen(o: auto) = + doAssert not compiles(o.hey()) + if o.hey: + echo "not deprecated" + gen(SomeObj(hey: true)) + doAssert not (compiles do: + proc hey(o: SomeObj) {.deprecated: "Shouldn't use this".} = echo "hey" + proc gen2(o: auto) = + if o.hey(): + echo "not deprecated" + gen2(SomeObj(hey: true))) + proc hey(o: SomeObj) {.deprecated: "Shouldn't use this".} = echo "hey" + proc gen3(o: auto) = + if o.hey: + echo "not deprecated" + gen3(SomeObj(hey: true)) + {.pop.} +block: # error + type + SomeObj = object + hey: bool + proc hey() {.error: "Shouldn't use this".} = echo "hey" + proc gen(o: auto) = + doAssert not compiles(o.hey()) + if o.hey: + echo "not error" + gen(SomeObj(hey: true)) + doAssert not (compiles do: + proc hey(o: SomeObj) {.error: "Shouldn't use this".} = echo "hey" + proc gen2(o: auto) = + if o.hey(): + echo "not error" + gen2(SomeObj(hey: true))) + proc hey(o: SomeObj) {.error: "Shouldn't use this".} = echo "hey" + proc gen3(o: auto) = + if o.hey: + echo "not error" + gen3(SomeObj(hey: true)) diff --git a/tests/generics/timports.nim b/tests/generics/timports.nim index 800ae7f889561..b619c48cf6eab 100644 --- a/tests/generics/timports.nim +++ b/tests/generics/timports.nim @@ -31,12 +31,13 @@ block tclosed_sym: proc same(r:R, d:int) = echo "TEST1" doIt(Data[int](d:123), R()) +import strutils, unicode # ambiguous `strip` block tdotlookup: foo(7) # bug #1444 fn(4) - + doAssert doStrip(123) == "123" block tmodule_same_as_proc: # bug #1965