Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[concepts] using a parameter : SomeConcept gives: Error: object constructor needs an object type #9071

Open
timotheecour opened this issue Sep 25, 2018 · 0 comments
Labels

Comments

@timotheecour
Copy link
Member

timotheecour commented Sep 25, 2018

a parameter typed by a concept (parameter : SomeConcept) used in a routine body can give Error: object constructor needs an object type, see below (with -d:case1); the workaround (-d:case3) is not DRY, and prevents UFCS; in more complex cases (as in my original use case from which this was reduced), explicitly instantiating the types in initMyseq can be tricky.

This was reduced from a more complex example in a tensor library.
I could've reduced a bit more but wanted to show a bit where it came from.

template elementType*(T:typedesc):typedesc=
  type ret = type(
    block:
      proc elementTypeAux(T2:typedesc):auto=
        var a:T2
        for ai in a:
          return ai
      elementTypeAux(T)
    )
  ret

type Myseq[Iter] = object
  # container that can hold a seq or proc pointer to define its elements
  iter: Iter

proc initMyseq[Iter](iter: Iter):auto=Myseq[Iter](iter: iter)

iterator items[T](a: Myseq[T]): auto=
  for i in 0..3:
    when a.iter.type is seq:
      yield a.iter[i]
    else:
      yield a.iter(i)

type SomeConcept[T] = concept x
  elementType(T) is type(x)

type isMySeq = concept x
  type(x) is Myseq[x.type.Iter]

proc collect[T: isMySeq](a: T, b: var seq[SomeConcept[T]]): auto =
  b.setLen 0
  for ai in a: b.add ai
  when defined(case1):
    # Error: object constructor needs an object type
    result = initMyseq(b)
  when defined(case2):
    # same error: can't use UFCS
    result = b.initMyseq[seq[elementType(T)]]()
  when defined(case3):
    # workaround: not DRY; disallows UFCS, in my case, it's more complicated
    result = initMyseq[seq[elementType(T)]](b)

block:
  var a0 = initMyseq(@[1,2,3,4])
  proc fun(a: int): auto {.inline.} = a*10
  var a = initMyseq(fun)
  for ai in a:
    echo ai

  var s: seq[int]
  discard collect(a, s)
  echo s

  var s2: seq[float]
  assert: not compiles(collect(a, s2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants