Skip to content

Commit

Permalink
Generic parameters now can constrain statics in type definitions (#19362
Browse files Browse the repository at this point in the history
)

* Parameters now can constrain static in type definitions

resolved regression with generic procedures

* Update compiler/sigmatch.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
  • Loading branch information
beef331 and Araq authored Jan 13, 2022
1 parent 9b9ae8a commit a93f6e7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
14 changes: 12 additions & 2 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1739,11 +1739,22 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let prev = PType(idTableGet(c.bindings, f))
if prev == nil:
if aOrig.kind == tyStatic:
if f.base.kind != tyNone:
if f.base.kind notin {tyNone, tyGenericParam}:
result = typeRel(c, f.base, a, flags)
if result != isNone and f.n != nil:
if not exprStructuralEquivalent(f.n, aOrig.n):
result = isNone
elif f.base.kind == tyGenericParam:
# Handling things like `type A[T; Y: static T] = object`
if f.base.len > 0: # There is a constraint, handle it
result = typeRel(c, f.base.lastSon, a, flags)
else:
# No constraint
if tfGenericTypeParam in f.flags:
result = isGeneric
else:
# for things like `proc fun[T](a: static[T])`
result = typeRel(c, f.base, a, flags)
else:
result = isGeneric
if result != isNone: put(c, f, aOrig)
Expand Down Expand Up @@ -1993,7 +2004,6 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
arg = argSemantized
a = a
c = m.c

if tfHasStatic in fMaybeStatic.flags:
# XXX: When implicit statics are the default
# this will be done earlier - we just have to
Expand Down
42 changes: 42 additions & 0 deletions tests/generics/tstatic_constrained.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
discard """
cmd: "nim check --hints:off --warnings:off $file"
action: "reject"
nimout:'''
tstatic_constrained.nim(41, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
got: <typedesc[int], int literal(10)>
but expected: <T: float or string, Y>
tstatic_constrained.nim(41, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
got: <typedesc[int], int literal(10)>
but expected: <T: float or string, Y>
tstatic_constrained.nim(41, 29) Error: object constructor needs an object type [proxy]
tstatic_constrained.nim(41, 29) Error: expression '' has no type (or is ambiguous)
tstatic_constrained.nim(42, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
got: <typedesc[byte], uint8>
but expected: <T: float or string, Y>
tstatic_constrained.nim(42, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
got: <typedesc[byte], uint8>
but expected: <T: float or string, Y>
tstatic_constrained.nim(42, 32) Error: object constructor needs an object type [proxy]
tstatic_constrained.nim(42, 32) Error: expression '' has no type (or is ambiguous)
'''
"""

type
MyType[T; X: static T] = object
data: T
MyOtherType[T: float or string, Y: static T] = object

func f[T,X](a: MyType[T,X]): MyType[T,X] =
when T is string:
MyType[T,X](data: a.data & X)
else:
MyType[T,X](data: a.data + X)

discard MyType[int, 2](data: 1)
discard MyType[string, "Helelello"](data: "Hmmm")
discard MyType[int, 2](data: 1).f()
discard MyType[string, "Helelello"](data: "Hmmm").f()
discard MyOtherType[float, 1.3]()
discard MyOtherType[string, "Hello"]()
discard MyOtherType[int, 10]()
discard MyOtherType[byte, 10u8]()

0 comments on commit a93f6e7

Please sign in to comment.