Skip to content

Commit

Permalink
treat generic proc param/return type like generic type body
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Aug 21, 2024
1 parent 12b90d7 commit 74590b8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 8 deletions.
21 changes: 14 additions & 7 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
result = newProcType(c, n.info, prev)
var check = initIntSet()
var counter = 0
template isCurrentlyGeneric: bool =
# genericParams might update as implicit generic params are added
genericParams != nil and genericParams.len > 0

for i in 1..<n.len:
var a = n[i]
Expand All @@ -1332,7 +1335,10 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
hasDefault = a[^1].kind != nkEmpty

if hasType:
let isGeneric = isCurrentlyGeneric()
inc c.inGenericContext, ord(isGeneric)
typ = semParamType(c, a[^2], constraint)
dec c.inGenericContext, ord(isGeneric)
# TODO: Disallow typed/untyped in procs in the compiler/stdlib
if kind in {skProc, skFunc} and (typ.kind == tyTyped or typ.kind == tyUntyped):
if not isMagic(getCurrOwner(c)):
Expand All @@ -1353,7 +1359,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
message(c.config, a.info, warnImplicitDefaultValue, msg)
block determineType:
var defTyp = typ
if genericParams != nil and genericParams.len > 0:
if isCurrentlyGeneric():
defTyp = nil
def = semGenericStmt(c, def)
if hasUnresolvedArgs(c, def):
Expand Down Expand Up @@ -1432,11 +1438,12 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
onDef(a[j].info, arg)
a[j] = newSymNode(arg)

var r: PType =
if n[0].kind != nkEmpty:
semTypeNode(c, n[0], nil)
else:
nil
var r: PType = nil
if n[0].kind != nkEmpty:
let isGeneric = isCurrentlyGeneric()
inc c.inGenericContext, ord(isGeneric)
r = semTypeNode(c, n[0], nil)
dec c.inGenericContext, ord(isGeneric)

if r != nil and kind in {skMacro, skTemplate} and r.kind == tyTyped:
# XXX: To implement the proposed change in the warning, just
Expand Down Expand Up @@ -1489,7 +1496,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
result.flags.excl tfHasMeta
result.n.typ = r

if genericParams != nil and genericParams.len > 0:
if isCurrentlyGeneric():
for n in genericParams:
if {sfUsed, sfAnon} * n.sym.flags == {}:
result.flags.incl tfUnresolved
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/t8545.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ proc main() =
proc foo2(a: static[bool]): bar(a) = 1
doAssert foo2(true) == 1

proc foo3(a: static[bool]): bar(cast[static[bool]](a)) = 1
proc foo3(a: static[bool]): bar(cast[bool](a)) = 1
doAssert foo3(true) == 1

proc foo4(a: static[bool]): bar(static(a)) = 1
Expand Down
71 changes: 71 additions & 0 deletions tests/proc/tstaticsignature.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
when false: # issue #22607, needs proper nkWhenStmt handling
proc test[x: static bool](
t: (
when x:
int
else:
float
)
) = discard
test[true](1.int)
test[false](1.0)
doAssert not compiles(test[])

block: # expanded version of t8545
template bar(a: static[bool]): untyped =
when a:
int
else:
float

proc main() =
proc foo1(a: static[bool]): auto = 1
doAssert foo1(true) == 1

proc foo2(a: static[bool]): bar(a) = 1
doAssert foo2(true) == 1
doAssert foo2(true) is int
doAssert foo2(false) == 1.0
doAssert foo2(false) is float

proc foo3(a: static[bool]): bar(cast[bool](a)) = 1
doAssert foo3(true) == 1
doAssert foo3(true) is int
doAssert foo3(false) == 1.0
doAssert foo3(false) is float

proc foo4(a: static[bool]): bar(static(a)) = 1
doAssert foo4(true) == 1
doAssert foo4(true) is int
doAssert foo4(false) == 1.0
doAssert foo4(false) is float

static: main()
main()

block: # issue #8406
macro f(x: static[int]): untyped = discard
proc g[X: static[int]](v: f(X)) = discard

import macros

block: # issue #8551
macro distinctBase2(T: typedesc): untyped =
let typeNode = getTypeImpl(T)
expectKind(typeNode, nnkBracketExpr)
if typeNode[0].typeKind != ntyTypeDesc:
error "expected typeDesc, got " & $typeNode[0]
var typeSym = typeNode[1]

typeSym = getTypeImpl(typeSym)

if typeSym.typeKind != ntyDistinct:
error "type is not distinct: " & $typeSym.typeKind

typeSym = typeSym[0]
typeSym

func distinctBase[T](a: T): distinctBase2(T) = distinctBase2(T)(a)

type T = distinct int
doAssert distinctBase(T(0)) is int

0 comments on commit 74590b8

Please sign in to comment.