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

3 lines to break the compiler: proc [T], assignment and SIGSEGV #7141

Closed
Feinbube opened this issue Jan 26, 2018 · 4 comments
Closed

3 lines to break the compiler: proc [T], assignment and SIGSEGV #7141

Feinbube opened this issue Jan 26, 2018 · 4 comments

Comments

@Feinbube
Copy link

proc foo[T](x: T) =
  discard

var fun = if true: foo else: foo

Results in:

SIGSEGV: Illegal storage access. (Attempt to read from nil?)

This works, though:

proc foo(x: int) =
  discard

var fun = if true: foo else: foo

What I really wanted to do was something like this: (again, [T] breaks the compiler, int is fine)

proc foo[T](x: T) =
  echo "foo " & $(x)

proc bar[T](x: T) =
  echo "bar " &  $(x)

var cond = true
var fun = if cond: foo else: foo
fun(3)

I think this issue might be related to:
#4042, #3846 and #6137

@andreaferretti
Copy link
Collaborator

This should not break the compiler, but of course the line var fun = if true: foo else: foo cannot compile. The reason is that foo is not a concrete procedure, hence it cannot be assigned to a variable as a value.

Generic procedures are a recipe that will be later instantiated to a concrete procedure when a type is passed. If the procedure is called two times with two different type arguments, there will be two different versions in the generated code. If the procedure is never called, it will not even appear in the generated code at all.

When you assig a procedure to a variable, you essentially store a pointer to where the code of the procedure lives. You cannot do this for a generic procedure, because it does not correspond to a section in the generated code - a concrete one does

@GULPF
Copy link
Member

GULPF commented Jan 26, 2018

For reference, you make the code work by turning foo into a concrete proc at the assignment:

proc foo[T](x: T) =
  echo "foo " & $(x)

proc bar[T](x: T) =
  echo "bar " &  $(x)

var cond = true
var fun = if cond: foo[int] else: foo[int]
fun(3)

@Feinbube
Copy link
Author

Makes sense from a compilers perspective. Thanks for the explanations! :)

It would still be helpful to get a meaningful compiler output (e.g. with a line number) instead of a crash.

@mratsim
Copy link
Collaborator

mratsim commented Aug 8, 2018

Does not crash anymore, we get cannot instantiate [T], close it?

Araq pushed a commit that referenced this issue Aug 8, 2018
* Add tests to confirm #7231 is fixed.

* Add test for closed #6137

* Add test for #7141
timotheecour pushed a commit to timotheecour/Nim that referenced this issue Aug 8, 2018
* Add tests to confirm nim-lang#7231 is fixed.

* Add test for closed nim-lang#6137

* Add test for nim-lang#7141
timotheecour pushed a commit to timotheecour/Nim that referenced this issue Aug 8, 2018
* Add tests to confirm nim-lang#7231 is fixed.

* Add test for closed nim-lang#6137

* Add test for nim-lang#7141
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants