-
-
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
top-down type inference, implements rfc 149 #20091
Conversation
Awesome and bounty-worthy! |
Just out of curiosity (I have practically no experience working with the compiler), why use an extra parameter over adding a new field to PContext? |
If it could be refactored to that, I would do it, but I am not too confident about it. It would be really hard to keep track of (you would need to think about it for every I guess also for now I want the behavior of having |
b0bfba8
to
33b6f87
Compare
Based on what I understand from [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year), 2001 does not have 53 weeks, but 2004, 2009, 2015, 2020 do. The years 2000 and 2001 seem to be copy pasted from the `getDaysInYear` example above. The result of `getWeeksInIsoYear` also seem to match up with Wikipedia. That means these runnableExamples were never tested. Why is this the case? I only discovered this in nim-lang#20091.
Based on what I understand from [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year), 2001 does not have 53 weeks, but 2004, 2009, 2015, 2020 do. The years 2000 and 2001 seem to be copy pasted from the `getDaysInYear` example above. The result of `getWeeksInIsoYear` also seem to match up with Wikipedia. That means these runnableExamples were never tested. Why is this the case? I only discovered this in #20091.
Based on what I understand from [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year), 2001 does not have 53 weeks, but 2004, 2009, 2015, 2020 do. The years 2000 and 2001 seem to be copy pasted from the `getDaysInYear` example above. The result of `getWeeksInIsoYear` also seem to match up with Wikipedia. That means these runnableExamples were never tested. Why is this the case? I only discovered this in nim-lang#20091.
Not copying the full call tree before the typedesc call check in `semIndirectOp` is also a small performance improvement.
* Improve error message for `strutils.addf` (#20157) Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> * fixes #20153; do not escape `_` for mysql [backport] (#20164) * fixes #20153; do not escape `_` for mysql * add a test * Update db_mysql.nim * Update tdb_mysql.nim Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com> * [minor] don't find `"Hint: gc"` for action (#20170) * fixes links in the readme (#20167) * update the docs of arc following up #19749 (#19752) Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> * fixes broken ssl tests (#20181) * bootstrap the compiler with nimPreviewSlimSystem (#20176) * bootstrap the compiler with nimPreviewSlimSystem * threads * docs: fix some spelling errors (#19816) * docs: fix some spelling errors * contributing: fix spelling error Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> * Update contributing.md * Update intern.md * Update manual.md * Update manual_experimental_strictnotnil.md * Update nimgrep_cmdline.txt * Update pegdocs.txt * Update testament.md * Update tut1.md Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com> * Build compiler with --noNimblePath (#20168) - Fixes #18840 * help our poor CI; don't run CI on other branches for push (#20184) * fix broken runnableExamples for getWeeksInIsoYear (#20193) Based on what I understand from [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year), 2001 does not have 53 weeks, but 2004, 2009, 2015, 2020 do. The years 2000 and 2001 seem to be copy pasted from the `getDaysInYear` example above. The result of `getWeeksInIsoYear` also seem to match up with Wikipedia. That means these runnableExamples were never tested. Why is this the case? I only discovered this in #20091. * improve deprecation error messages (#20197) * Show beatutiful html instead of ugly markdown preview (#20196) * closes #6559; add testcase (#20200) * CI upgrade to ubuntu-20.04 (#20182) * CI upgrade to ubuntu-20.04 The ubuntu-18.04 environment is deprecated, consider switching to ubuntu-20.04(ubuntu-latest), or ubuntu-22.04 instead. For more details see actions/runner-images#6002 * Update azure-pipelines.yml * Markdown code blocks part 4 (#20189) No logic was added, just 8 more files have been migrated. * closes #15316; add testcase (#20213) * add version-1-6 and version-1-2 to triggered branches (#20214) * add version-1-6 and version-1-2 to triggered branches * Update .github/workflows/ci_packages.yml * use quote * closes #12955; add testcase (#20223) * add more Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com> Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> Co-authored-by: ee7 <45465154+ee7@users.noreply.github.com> Co-authored-by: Ivan Yonchovski <yyoncho@users.noreply.github.com> Co-authored-by: metagn <metagngn@gmail.com> Co-authored-by: Andrey Makarov <ph.makarov@gmail.com>
Forgot to comment this is ready for review, it just might be a little painful to do so. |
Thanks for your hard work on this PR! Hint: mm: orc; threads: on; opt: speed; options: -d:release |
Based on what I understand from [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year), 2001 does not have 53 weeks, but 2004, 2009, 2015, 2020 do. The years 2000 and 2001 seem to be copy pasted from the `getDaysInYear` example above. The result of `getWeeksInIsoYear` also seem to match up with Wikipedia. That means these runnableExamples were never tested. Why is this the case? I only discovered this in nim-lang#20091.
* micro implementation of rfc 149 refs nim-lang/RFCs#149 * number/array/seq literals, more statements * try fix number literal alias issue * renew expectedType with if/case/try branch types * fix (nerf) index type handling and float typed int * use typeAllowed * tweaks + const test (tested locally) [skip ci] * fill out more of the checklist * more literals, change @ order, type conversions Not copying the full call tree before the typedesc call check in `semIndirectOp` is also a small performance improvement. * disable self-conversion warning * revert type conversions (maybe separate op later) * deal with CI for now (seems unrelated), try enums * workaround CI different way * proper fix * again * see sizes * lol * overload selection, simplify int literal -> float * range, new @ solution, try use fitNode for nil * use new magic * try fix ranges, new magic, deal with nim-lang#20193 * add documentation, support templates Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
* micro implementation of rfc 149 refs nim-lang/RFCs#149 * number/array/seq literals, more statements * try fix number literal alias issue * renew expectedType with if/case/try branch types * fix (nerf) index type handling and float typed int * use typeAllowed * tweaks + const test (tested locally) [skip ci] * fill out more of the checklist * more literals, change @ order, type conversions Not copying the full call tree before the typedesc call check in `semIndirectOp` is also a small performance improvement. * disable self-conversion warning * revert type conversions (maybe separate op later) * deal with CI for now (seems unrelated), try enums * workaround CI different way * proper fix * again * see sizes * lol * overload selection, simplify int literal -> float * range, new @ solution, try use fitNode for nil * use new magic * try fix ranges, new magic, deal with #20193 * add documentation, support templates Co-authored-by: Andreas Rumpf <rumpf_a@web.de> (cherry picked from commit 0014b9c)
refs #23586 (comment) In #20091 a bad kind of type inference was mistakenly left in where if an identifier `abc` had an expected type of an enum type `Enum`, and `Enum` had a member called `abc`, the identifier would change to be that enum member. This causes bugs where a local symbol can have the same name as an enum member but have a different value. I had assumed this behavior was removed since but it wasn't, and CI seems to pass having it removed. A separate PR needs to be made for the 2.0 branch because these lines were moved around during a refactoring in #23123 which is not in 2.0.
refs #23586 (comment) In #20091 a bad kind of type inference was mistakenly left in where if an identifier `abc` had an expected type of an enum type `Enum`, and `Enum` had a member called `abc`, the identifier would change to be that enum member. This causes bugs where a local symbol can have the same name as an enum member but have a different value. I had assumed this behavior was removed since but it wasn't, and CI seems to pass having it removed. A separate PR needs to be made for the 2.0 branch because these lines were moved around during a refactoring in #23123 which is not in 2.0. (cherry picked from commit c101490)
fixes nim-lang#24164, regression from nim-lang#20091
…4165) fixes #24164, regression from #20091 The expression `nil` as the default value of template parameter `x: untyped` is typechecked with expected type `untyped` since #20091. The expected type is checked if it matches the `nil` literal with a match better than a subtype match, and the type is set to it if it does. However `untyped` matches with a generic match which is better, so the `nil` literal has type `untyped`. This breaks type matching for the literal. So if the expected type is `untyped` or `typed`, it is now ignored and the `nil` literal just has the `nil` type.
…4165) fixes #24164, regression from #20091 The expression `nil` as the default value of template parameter `x: untyped` is typechecked with expected type `untyped` since #20091. The expected type is checked if it matches the `nil` literal with a match better than a subtype match, and the type is set to it if it does. However `untyped` matches with a generic match which is better, so the `nil` literal has type `untyped`. This breaks type matching for the literal. So if the expected type is `untyped` or `typed`, it is now ignored and the `nil` literal just has the `nil` type. (cherry picked from commit b9de2bb)
refs nim-lang/RFCs#149, closes nim-lang/RFCs#36
Name copied from Haxe manual
Proof of concept for adding top-down type inference on top of the validating style inference used by
fitNode
. (I think this is called "bidirectional typing"). Each expression can opt-in to this and define their own behaviors.Todo
@
is overloaded, only activates if you callsystem.`@`
)expectedType
?Notes
Performance should be considered. The biggest performance pitfalls I can think of are the passing of the
expectedType
parameter everywhere (which isn't that bad because it's basically just anint
) and theexpectedType != nil
checks. Theoretically it should be negligible.Keeping this as compatible as possible is best, but if needed, it can be made into a compile option (
--topDownInference:on
) or experimental switch.fitNode
already has errors, so new errors/enforcingexpectedType
are probably not needed.Type conversions are left alone.
Current incompatibilities:
Potential extensions outside this PR, can go in new RFC after merge
new magic like
infer(x: untyped, T: type): T
orx as T
as opposed toT(x)
to ensure compile-time only, costless conversionlambda/
do
signature inference. not because it would be hard but because I don't want to botherMost useful potential application: Routine arguments. I am not equipped to start this yet but I can think of some ways to do it. All of them could have bad performance.
untyped
arguments) until only 1 overload remains. For example if there are overloads that are like(A, X, Y)
,(B, X, Y)
,(C, X, Y)
, you sem the first argument (not accounting for named arguments) and get A, then only the overload of(A, X, Y)
remains, so you know to use X and Y for the remaining arguments. This has the advantage of working with method-style signatures much better. I think this would also be the easiest to do efficiently.(A, X, T1)
and(B, X, T2)
, you can't infer the first argument, you can infer the second argument because the common types areX
, but 2 overloads are still remaining, so you can't infer the third argument. This is stronger than 2 (2 cannot inferX
) but slower because of the common type calculation.I do not see myself doing this any time soon so the implementation details don't have to be up to me.