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

Cannot extract generic parameter from normal parameter in proc heading #8459

Open
awr1 opened this issue Jul 27, 2018 · 8 comments
Open

Cannot extract generic parameter from normal parameter in proc heading #8459

awr1 opened this issue Jul 27, 2018 · 8 comments
Labels

Comments

@awr1
Copy link
Contributor

awr1 commented Jul 27, 2018

type
  Foo[T] = object
    a: T
  Bar[T] = object
    b: T

proc doThing(foo: Foo): Bar[foo.T] =
  result.b = foo.a

var foo: Foo[int]
foo.a = 100
let what = doThing(foo)

output:

c:/nimtests $ nim c paramextract.nim
Hint: used config file 'c:\Nim\config\nim.cfg' [Conf]
Hint: system [Processing]
Hint: paramextract [Processing]
paramextract.nim(13, 19) template/generic instantiation from here
paramextract.nim(8, 28) Error: cannot instantiate: 'result:type'
@andreaferretti
Copy link
Collaborator

This is probably a bug, but just in case you don't know, the simplest and more readable way to write this would be

proc doThing[T](foo: Foo[T]): Bar[T] =
  result.b = foo.a

@mratsim
Copy link
Collaborator

mratsim commented Jul 27, 2018

Iirc, this only works for static, and is completely undocumented. I'm also not super fan of this because the "T" or "N" seems to come from nowhere:

Static compiles

type
  Foo[N: static[int]] = object
    a: array[N, int]
  Bar[N: static[int]] = object
    b: array[N, float]

proc doThing(foo: Foo): Bar[Foo.N] =
  for i, v in foo.a:
    result.b[i] = v.float

var foo: Foo[2]
foo.a = [100, 200]
let what = doThing(foo)

cc @zah

@GULPF
Copy link
Member

GULPF commented Jul 27, 2018

It is documented (a few paragraphs down) and it should work even for non-static: https://nim-lang.org/docs/manual.html#generics-type-classes

This works:

type
  Foo[T] = object
    a: T

proc doThing(foo: Foo): Foo.T =
  result = foo.a

var foo: Foo[int]
foo.a = 100
let what = doThing(foo)

But this doesn't:

type
  Foo[T] = object
    a: T
  Bar[T] = object
    b: T

proc doThing(foo: Foo): Bar[Foo.T] =
  result.b = foo.a

var foo: Foo[int]
foo.a = 100
let what = doThing(foo)

@mratsim
Copy link
Collaborator

mratsim commented Jul 27, 2018

Duplicate of #8433

@timotheecour
Copy link
Member

@awr1 should we close as duplicate?

@awr1
Copy link
Contributor Author

awr1 commented Aug 1, 2018

will close then as a duplicate of #8433

@awr1 awr1 closed this as completed Aug 1, 2018
@zah
Copy link
Member

zah commented Aug 3, 2018

I don't consider this a duplicate of #8433, due to the particulars of the compiler internal structures (seq is not a regular generic type).

@timotheecour
Copy link
Member

indeed this wasn't a duplicate of #8433 : just sent a PR #8554 that provides a better workaround for #8433, but doesn't address this issue. This isssue could in fact be related to #8551 ; it looks like root cause is that type inference is incomplete for return type; I feel like the issue here with [Foo.T] could be just a symptom of that. in #8551, when i try the example from #8459 (comment) I fall into the else branch of extractGeneric, with kind = nnkNilLit

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

6 participants