-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Impossible generic parameters shouldn't compile #18752
Comments
this would hurt generic code when defined foo:
type A = uint|int
else:
type A = uint
proc f[T: A and int]() |
In the first case it should compile, but why should it compile in the second case? Is it not misleading to allow a proc that can't be called to compile? Maybe at least a compiler warning |
for the same reason as we allow a warning might be acceptable |
But |
Is it technically possible with the current type system to determine that there isn't an intersection between |
"possible", sure, probably but there is no problem to solve here. The error manifests as soon as you try to use the proc |
I cannot agree more. note that, using the same argument, we don't need to type-check generics at declaration time (which causes many issues / complications, refs #8677 + similar issues with nimvm construct). Any attempt to instantiate the generic would trigger such issues. Refactorings that don't have that generic instantiated in a test suite could let errors slip by, but that's a moot argument given that it caters to code with poor test coverage, and more importantly, that generic prepass can only catch a small amount of the issues that could be found with generic instantiation, not to mention all the issues this causes (eg timotheecour#355 + others). A generic pre-pass that restricts itself to symbol binding could be a possibly better design (there are ways to deal with scope injecting macros/templates called inside generics). link to recent discussion: https://discord.com/channels/371759389889003530/768367394547957761/880763539021791263
not possible in the general case, it ends up being a hard (possibly undecidable) constraint satisfaction problem, eg: type A = concept x
compiles(x.foo)
type B = concept x
not compiles(x.foo)
proc main(a: A and B) = discard I'm not even sure it's worth solving the "easy cases" (whatever that means); as mentioned in #18752 (comment), this would not work well in generic code. |
I'm not sure what you mean here, I brought up type-checking of generics as a possible evolutionary path, but currently we don't do it at all and the pre-pass does only do symbol lookups. |
However, the error message is misleading that the issue is at the callsite |
Generic that are constrained that have no possible resolution (
T: SomeFloat and string
) shouldn't compileExample
Current Output
Compiles totally fine
Expected Output
Shouldn't compile
The text was updated successfully, but these errors were encountered: