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

Generic parameters void and not void clash #1188

Open
disruptek opened this issue Feb 15, 2024 · 3 comments
Open

Generic parameters void and not void clash #1188

disruptek opened this issue Feb 15, 2024 · 3 comments
Labels
bug Something isn't working compiler/sem Related to semantic-analysis system of the compiler

Comments

@disruptek
Copy link
Contributor

Specification

Generic parameters void and not void clash with Error: overloaded 'test' leads to ambiguous calls

Example

type
  A[T] = object
    when T isnot void:
      x: T

proc test[T: void](): A[T] = discard

proc test[T: not void](): A[T] = discard

discard test[void]()
discard test[float]()

Actual Output

Error: overloaded 'test' leads to ambiguous calls

Expected Output

Possible Solution

Better error message.

Additional Information

Nimskull Compiler Version 0.1.0-dev.21221 [linux: amd64]

Source hash: bd28145a33ab7540d08258b0fd306c65947c3f02
Source date: 2024-02-11

active boot switches: -d:release -d:danger⏎
@disruptek disruptek added the bug Something isn't working label Feb 15, 2024
@zerbina zerbina added the compiler/sem Related to semantic-analysis system of the compiler label Feb 15, 2024
@zerbina
Copy link
Collaborator

zerbina commented Feb 15, 2024

This is a general problem not strictly related to void. Generic parameters are ignored when comparing routine signatures for the purpose of disallowing re-definitions (refer to searchForProcAux). For example:

proc test[T: int]() = discard
proc test[T: float]() = discard
# error: re-definition of test

proc test2[T: int](): T = discard
proc test2[T: float](): T = discard
# error: would lead to ambiguous calls

@saem
Copy link
Collaborator

saem commented Feb 15, 2024

I think discriminating based on generic parameter constraint types is reasonable, but looking for more input on that as well. Does it make sense that we differentiate based on generic parameters, in some fashion?


Assuming the above is true, then my mind turns to more practical concerns wrt implementation. I'm not sure if the current implementation can handle the weirder cases all that well, such as those involving type operations e.g.:

proc test[T: int]() = discard
proc test[T: float or int and not int]() = discard

proc test2[T: int](): T = discard
proc test2[T: float or int and not int](): T = discard

Perhaps we could start by swapping generic parameters for their constraints when considering signatures, that would mean test would still result in a redefinition, as no parameters would take the constraints of their respective T, and test2 would now work. At least the test scenario veers into the whole aliases vs phantom types (branding).

@disruptek
Copy link
Contributor Author

I would feel better about the branding situation if I could figure out how to .borrow. distinct generics. I mean, I know that's already two sides of the pentagram of pain, but still...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler/sem Related to semantic-analysis system of the compiler
Projects
None yet
Development

No branches or pull requests

3 participants