-
-
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
Inconsisten Symbol Binding Rules in Templates/Generics #11184
Comments
comment from Araq: This should work, and private sort should not bind to anything from instantiation context. proc privateSort(...)
proc sort[T]() = privateSort(...) # delegate
bind privateSort <- this is not necessary |
With the potential design described in #22605 (comment), each Ident "foo0"
OpenSymChoice
Sym "foo1" {preferred}
OpenSymChoice
Sym "foo2"
Sym "foo2"
# neither preferred because name is ambiguous at template declaration Technically just Related/same issue #3542 |
I would prefer the original solution where everything is open by default. It's easier to understand, and less likely to break just because a template definition was moved around. |
fixes nim-lang#11184, fixes nim-lang#22605, fixes nim-lang#20000
fixes nim-lang#11184, fixes nim-lang#22605, fixes nim-lang#20000
* Explicitly bind logging procs in templates The logging templates in `logger` reference procs like `error`, `info`, `warn` etc. from the `logging` module. These are implicitly bound, as they have exactly 1 overload in the scope of the template definitions (nim-lang/Nim#11184). If this behavior of Nim or the context in `logger` were to change, these would start preferring procs like `macros.error` instead and cause issues. Explicitly binding them keeps the current behavior consistent. An alternative would be to directly call `logging.error join(args)` etc. * also update frameLog
The original `->` in `edge` sorts the parameters before forming the edge, but helpers.`->` doesn't do this. helpers.`->` also has a more precise signature (on `tuple[x, y: float]` rather than the `Point` concept), which means generic procs can prefer it if `->` is considered to be overloaded. This has not been an issue in this package because the generic procs that use `->` only have access to 1 overload of it and so Nim considers them not overloaded. However this behavior is not reliable: nim-lang/Nim#11184, and so attempts to fix this cause issues in this library's tests. Alternatively the tests can use another operator to form unsorted edges, or the signature of helpers.`->` can be made equally as precise as the one in `edge` (i.e. defined on `Point`).
The issue that I want to talk about is the following for both templates and generic function implementations:
When a function symbol can't be resolved in the template definition, it stays as an identifier. Thi identifier will then be resolved in the context where the template is expanded. So the identifier can be resolved to a symbol from expansion context.
When a function symbol has soveral overloads, the identifier becomes an open sym choice. Open sym choice means the identifier can be resolved to a symbol from the euxpansion context.
The surprising and therefore problematic behavior happens when a symbol is resolved to a single symbol. Then the identifier becomes a node of
nnkSym
, thatmeans it cannot be resolved to a symbol from the expansion context anymore.
Example
file1.nim
file2.nim
Possible Solution
Everything should be an OpenSymChoice for consistent behavior. Since nim currently really gets confused with empty open sym choices I think the empty open sym choice can remain a ident node. But I like to think about an identifier like an open sym choice with no elements. This is currently the generated AST from the templates.
Additional Information
The text was updated successfully, but these errors were encountered: