Skip to content

Commit

Permalink
block ambiguous type conversion dotcalls in generics
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Aug 3, 2023
1 parent b40da81 commit 41d6322
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 0 deletions.
11 changes: 11 additions & 0 deletions compiler/semgnrc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,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)

Expand Down
7 changes: 7 additions & 0 deletions tests/generics/m22373a.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# module a for t22373

# original:
type LightClientHeader* = object

# simplified:
type TypeOrTemplate* = object
18 changes: 18 additions & 0 deletions tests/generics/m22373b.nim
Original file line number Diff line number Diff line change
@@ -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]
16 changes: 16 additions & 0 deletions tests/generics/t22373.nim
Original file line number Diff line number Diff line change
@@ -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)
5 changes: 5 additions & 0 deletions tests/generics/timports.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 41d6322

Please sign in to comment.