summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semgnrc.nim11
-rw-r--r--tests/generics/m22373a.nim7
-rw-r--r--tests/generics/m22373b.nim18
-rw-r--r--tests/generics/t22373.nim16
-rw-r--r--tests/generics/timports.nim5
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