-
-
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
block ambiguous type conversion dotcalls in generics #22375
Conversation
Shouldn't instead we always treat |
You mean like # a.nim
type T* = uint
# b.nim
template T*(x: int): float = float(x)
# c.nim
import a, b
# or
import b, a
doAssert T(123) is uint ? This would require that we check all routine symbols for ambiguity with a type symbol, then check if such a type symbol is not ambiguous with another type symbol, and then pick the type symbol. This is more complex IMO than just making type symbols "weak" in calls and picking them only when it's clear we are dealing with a single type (the behavior in regular Nim and the behavior in generics with this PR). |
In your example |
Putting this logic in overload resolution would be a hefty refactor. And honestly I don't think it's worth it, types and routines having the same name is a niche case, the logic is good enough IMO and we can focus on compatibility. |
I don't agree, it's fundamentally the right thing to do instead of this rats nest of special cases. But it improves the situation so I merged it. |
Thanks for your hard work on this PR! Hint: mm: orc; opt: speed; options: -d:release |
…le types in symchoices (#23997) fixes #23898, supersedes #23966 and #23990 Since #20631 ambiguous type symbols in templates are rejected outright, now we generate a symchoice for type nodes if they're ambiguous, a generalization of what was done in #22375. This is done for generics as well. Symchoices also handle type symbols better now, ensuring their type is a `typedesc` type; this probably isn't necessary for everything to work but it makes the logic more robust. Similar to #23989, we have to prepare for the fact that ambiguous type symbols behave differently than normal type symbols and either error normally or relegate to other routine symbols if the symbol is being called. Generating a symchoice emulates this behavior, `semExpr` will find the type symbol first, but since the symchoice has other symbols, it will count as an ambiguous type symbol. I know it seems spammy to carry around an ambiguity flag everywhere, but in the future when we have something like #23104 we could just always generate a symchoice, and the symchoice itself would carry the info of whether the first symbol was ambiguous. But this could harm compiler performance/memory use, it might be better to generate it only when we have to, which in the case of type symbols is only when they're ambiguous.
…le types in symchoices (#23997) fixes #23898, supersedes #23966 and #23990 Since #20631 ambiguous type symbols in templates are rejected outright, now we generate a symchoice for type nodes if they're ambiguous, a generalization of what was done in #22375. This is done for generics as well. Symchoices also handle type symbols better now, ensuring their type is a `typedesc` type; this probably isn't necessary for everything to work but it makes the logic more robust. Similar to #23989, we have to prepare for the fact that ambiguous type symbols behave differently than normal type symbols and either error normally or relegate to other routine symbols if the symbol is being called. Generating a symchoice emulates this behavior, `semExpr` will find the type symbol first, but since the symchoice has other symbols, it will count as an ambiguous type symbol. I know it seems spammy to carry around an ambiguity flag everywhere, but in the future when we have something like #23104 we could just always generate a symchoice, and the symchoice itself would carry the info of whether the first symbol was ambiguous. But this could harm compiler performance/memory use, it might be better to generate it only when we have to, which in the case of type symbols is only when they're ambiguous. (cherry picked from commit 09dcff7)
fixes #22373
In normal code, when an ambiguous type symbol is called, a type conversion is not considered and routine overloading is done instead:
Nim/compiler/semexprs.nim
Lines 3113 to 3115 in b40da81
For the same situation in generic code with dotcalls, replace the ambiguous type symbol with a sym choice, which similarly ignores type conversions and performs normal routine overloading.