diff options
author | metagn <metagngn@gmail.com> | 2023-08-09 07:12:14 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-09 06:12:14 +0200 |
commit | 3aaef9e4cf014d5df65a686efe6b8bd99d3ea465 (patch) | |
tree | 3f073e3f9e704515da6c215fe428e4247e7f6932 | |
parent | d136af012298b58be5abfb5e095cabd158feeb2e (diff) | |
download | Nim-3aaef9e4cf014d5df65a686efe6b8bd99d3ea465.tar.gz |
block ambiguous type conversion dotcalls in generics (#22375)
fixes #22373
-rw-r--r-- | compiler/semgnrc.nim | 11 | ||||
-rw-r--r-- | tests/generics/m22373a.nim | 7 | ||||
-rw-r--r-- | tests/generics/m22373b.nim | 18 | ||||
-rw-r--r-- | tests/generics/t22373.nim | 16 | ||||
-rw-r--r-- | tests/generics/timports.nim | 5 |
5 files changed, 57 insertions, 0 deletions
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 43b8d4bac..c8eda9c37 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -168,6 +168,17 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, elif s.isMixedIn: result = newDot(result, symChoice(c, n, s, scForceOpen)) else: + if s.kind == skType and candidates.len > 1: + var ambig = false + let s2 = searchInScopes(c, ident, ambig) + if ambig: + # this is a type conversion like a.T where T is ambiguous with + # other types or routines + # in regular code, this never considers a type conversion and + # skips to routine overloading + # so symchoices are used which behave similarly with type symbols + result = newDot(result, symChoice(c, n, s, scForceOpen)) + return let syms = semGenericStmtSymbol(c, n, s, ctx, flags, fromDotExpr=true) result = newDot(result, syms) diff --git a/tests/generics/m22373a.nim b/tests/generics/m22373a.nim new file mode 100644 index 000000000..28e087ca6 --- /dev/null +++ b/tests/generics/m22373a.nim @@ -0,0 +1,7 @@ +# module a for t22373 + +# original: +type LightClientHeader* = object + +# simplified: +type TypeOrTemplate* = object diff --git a/tests/generics/m22373b.nim b/tests/generics/m22373b.nim new file mode 100644 index 000000000..67ee4211b --- /dev/null +++ b/tests/generics/m22373b.nim @@ -0,0 +1,18 @@ +# module b for t22373 + +import m22373a + +# original: +type + LightClientDataFork* {.pure.} = enum + None = 0, + Altair = 1 +template LightClientHeader*(kind: static LightClientDataFork): auto = + when kind == LightClientDataFork.Altair: + typedesc[m22373a.LightClientHeader] + else: + static: raiseAssert "Unreachable" + +# simplified: +template TypeOrTemplate*(num: int): untyped = + typedesc[m22373a.TypeOrTemplate] diff --git a/tests/generics/t22373.nim b/tests/generics/t22373.nim new file mode 100644 index 000000000..ecfaf0f1b --- /dev/null +++ b/tests/generics/t22373.nim @@ -0,0 +1,16 @@ +# issue #22373 + +import m22373a +import m22373b + +# original: +template lazy_header(name: untyped): untyped {.dirty.} = + var `name _ ptr`: ptr[data_fork.LightClientHeader] # this data_fork.Foo part seems required to reproduce +proc createLightClientUpdates(data_fork: static LightClientDataFork) = + lazy_header(attested_header) +createLightClientUpdates(LightClientDataFork.Altair) + +# simplified: +proc generic[T](abc: T) = + var x: abc.TypeOrTemplate +generic(123) diff --git a/tests/generics/timports.nim b/tests/generics/timports.nim index 43f096664..6b71cb6d3 100644 --- a/tests/generics/timports.nim +++ b/tests/generics/timports.nim @@ -46,6 +46,11 @@ block tdotlookup: x.set("hello", "world") result = x doAssert abc(5) == 10 + block: # ensure normal call is consistent with dot call + proc T(x: int): float = x.float + proc foo[T](x: int) = + doAssert typeof(T(x)) is typeof(x.T) + foo[uint](123) block tmodule_same_as_proc: # bug #1965 |