├── .github ├── ISSUE_TEMPLATE │ ├── blank_issue.md │ ├── deep_dive_proposal.md │ └── major_change.md └── workflows │ └── main.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── book.toml ├── minutes ├── 2022-03-18-mir-formality-goals-and-reality.md ├── 2022-04-28-lazy-type-alias-impl-trait-compiler.md ├── 2022-04-28-lazy-type-alias-impl-trait-user-facing.md ├── 2022-05-27-mir-formality-roadmap.md ├── 2022-06-03-planning-meeting.md ├── 2022-06-10-backlog-bonanza.md ├── 2022-06-17-backlog-bonanza.md ├── 2022-06-24-backlog-bonanza.md ├── 2022-07-01-planning-meeting.md ├── 2022-07-08-implied-bounds-and-wf-checking.md ├── 2022-07-15-backlog-bonanza.md ├── 2022-07-29-nominated-triage.md ├── 2022-09-02-planning-meeting.md ├── 2022-09-09-projection-equality.md ├── 2022-09-16-TAIT-stabilization-finalizations.md ├── 2022-09-23-RPITIT-support.md ├── 2022-09-30-chalk-integration.md ├── 2022-10-07-planning-meeting.md ├── 2022-10-21-issue-triage.md ├── 2022-10-28-roadmap.md ├── 2022-11-04-planning-meeting.md ├── 2022-11-11-RPIT-self-PR.md ├── 2022-11-16-closure-return-type-outlives.md ├── README.md ├── design-2019-10-16.md ├── design-2019-10-21.md ├── design-2019-10-28.md ├── design-2019-11-04.md ├── design-2019-11-11.md ├── design-2019-11-18.md ├── design-2019-12-02.md ├── design-2019-12-09.md ├── design-2019-12-16.md ├── design-2019-12-30.md ├── design-2020-01-06.md ├── design-2020-01-13.md ├── design-2020-02-11.md ├── design-2020-02-25.md ├── design-2020-03-03.md ├── design-2020-03-10.md ├── design-2020-03-17.md ├── design-2020-03-24.md ├── design-2020-03-31.md ├── design-2020-04-07.md ├── design-2020-04-14.md ├── design-2020-04-21.md ├── design-2020-04-28.md ├── design-2020-05-05.md ├── design-2020-05-12.md ├── triage-2019-02-24.md ├── triage-2019-03-04.md └── triage-2019-03-11.md ├── roadmap.toml ├── sprints ├── 2020-1.md └── 2020-2.md ├── src ├── SUMMARY.md ├── minutes.md ├── roadmap.md └── welcome.md └── triagebot.toml /.github/ISSUE_TEMPLATE/blank_issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Blank Issue 3 | about: Create a blank issue. 4 | --- 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/deep_dive_proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Deep dive proposal 3 | about: Propose a deep dive 4 | labels: deep-dive-proposal, T-types 5 | --- 6 | 7 | ### Summary 8 | 11 | 12 | 13 | ### Rationale 14 | 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/major_change.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Major change proposal (MCP) 3 | about: Propose a major change. 4 | title: "(My major change proposal)" 5 | labels: major-change, T-types 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Proposal 11 | 12 | *Insert your proposal here, overwriting this text and the text under "Mentors or Reviewers", leaving the rest of the template untouched. Please include the complete proposal, rather than linking to a gist or other external document.* 13 | 14 | *Your proposal doesn't have to be long. It should however be in sufficient detail that people familiar with the code can clearly envision what you are planning to do. Be sure to link to any relevant issues, PRs, or other sources.* 15 | 16 | *When picking a title (that is, when replacing the "(My major change proposal)" text above), keep in mind that Zulip truncates text that extends beyond a certain length, replacing the truncated suffix with "…" in the topic name it creates. Therefore, consider keeping your title to <= 40 characters, if possible.* 17 | 18 | # Mentors or Reviewers 19 | 20 | *If you have a reviewer or mentor in mind for this work, mention then 21 | here. You can put your own name here if you are planning to mentor the 22 | work.* 23 | 24 | # Process 25 | 26 | The main points of the [Major Change Process][MCP] are as follows: 27 | 28 | * [x] File an issue describing the proposal. 29 | * [ ] A types team member or contributor who is knowledgeable in the area can **second** by writing `@rustbot second`. 30 | * Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a `-C flag`, then full team check-off is required. 31 | * Types team members can initiate a check-off via `@rfcbot fcp merge` on either the MCP or the PR. 32 | * [ ] Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered **approved**. 33 | 34 | You can read [more about Major Change Proposals on forge][MCP]. 35 | 36 | [MCP]: https://forge.rust-lang.org/types/mcp.html 37 | 38 | # Comments 39 | 40 | **This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.** 41 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | book-test: 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: Install mdbook 18 | run: | 19 | cargo install --version "^0.4.5" mdbook 20 | cargo install --version "^1.3.1" skill-tree 21 | 22 | - name: mdbook test 23 | run: | 24 | mdbook build 25 | mdbook test 26 | 27 | - name: check skill-tree 28 | run: skill-tree roadmap.toml book/roadmap 29 | 30 | - name: Deploy GitHub Pages 31 | if: github.ref == 'refs/heads/master' 32 | run: | 33 | git worktree add gh-pages gh-pages 34 | git config user.name "Deploy from CI" 35 | git config user.email "" 36 | cd gh-pages 37 | # Delete the ref to avoid keeping history. 38 | git update-ref -d refs/heads/gh-pages 39 | rm -rf * 40 | mv ../book/* . 41 | git add . 42 | git commit -m "Deploy $GITHUB_SHA to gh-pages" 43 | git push --force 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # The Rust Code of Conduct 2 | 3 | A version of this document [can be found online](https://www.rust-lang.org/conduct.html). 4 | 5 | ## Conduct 6 | 7 | **Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org) 8 | 9 | * We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. 10 | * On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. 11 | * Please be kind and courteous. There's no need to be mean or rude. 12 | * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. 13 | * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. 14 | * We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. 15 | * Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. 16 | * Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. 17 | 18 | ## Moderation 19 | 20 | 21 | These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team]. 22 | 23 | 1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) 24 | 2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. 25 | 3. Moderators will first respond to such remarks with a warning. 26 | 4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. 27 | 5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. 28 | 6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. 29 | 7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. 30 | 8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. 31 | 32 | In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. 33 | 34 | And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. 35 | 36 | The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. 37 | 38 | *Adapted from the [Node.js Policy on Trolling](https://blog.izs.me/2012/08/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* 39 | 40 | [mod_team]: https://www.rust-lang.org/team.html#Moderation-team 41 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Types Team 2 | 3 | ## Scope and purpose 4 | 5 | The **types** team is dedicated to improving the trait 6 | system implementation in rustc. This team is a collaboration 7 | between the [lang team] and the compiler team. We have a number of inter-related 8 | goals: 9 | 10 | - designing new trait-related language features; 11 | - documenting and specifying the semantics of traits in Rust today; and, 12 | - improving the trait solver implementation in rustc. 13 | 14 | [lang team]: https://github.com/rust-lang/lang-team/ 15 | 16 | A big part of this work is transitioning the compiler to use a 17 | [Chalk-style] solver, but along the way we hope to make targeted fixes 18 | to the existing solver where needed. 19 | 20 | [Chalk-style]: https://github.com/rust-lang-nursery/chalk 21 | 22 | ## Design meetings 23 | 24 | We hold weekly design meetings where we talk in depth about various 25 | topics ([calendar event][ce-design]). These meetings take place on Zulip (see below). The goal is 26 | not just to figure out what we want to do, it's also a way to spread 27 | knowledge. Feel free to come and lurk! 28 | 29 | [ce-design]: https://calendar.google.com/calendar/u/0/embed?src=6u5rrtce6lrtv07pfi3damgjus@group.calendar.google.com 30 | 31 | You'll find minutes from past meetings in [the minutes directory](minutes). 32 | 33 | ## Chat forum 34 | 35 | On [the rust-lang Zulip][z], in [the `#t-types` stream][s]. 36 | 37 | [z]: https://rust-lang.zulipchat.com/ 38 | [s]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types 39 | 40 | ## Dedicated repository 41 | 42 | Documents related to the types team are stored on a 43 | dedicated repository, [rust-lang/types-team]. This repository contains 44 | meeting minutes, past sprints, as well as draft RFCs and other 45 | documents. 46 | 47 | [rust-lang/types-team]: https://github.com/rust-lang/types-team 48 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Niko Matsakis"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "The Types Team" 7 | -------------------------------------------------------------------------------- /minutes/2022-04-28-lazy-type-alias-impl-trait-compiler.md: -------------------------------------------------------------------------------- 1 | # Lazy TAIT Inference Algorithm Implications 2 | 3 | This write-up documents the effects of the new "lazy TAIT" inference algorithm implemented in [PR #94081](https://github.com/rust-lang/rust/pull/94081). 4 | 5 | It begins with a write-up explaining the algorithm "from first principles" -- i.e., how a user should understand it. It then explains some of the implications, and cases where this differences from the current stabilized behavior. 6 | 7 | ## Algorithm from first principles 8 | 9 | When you define an impl trait in "existential" position: 10 | 11 | ```rust 12 | type Foo = impl Debug; 13 | fn foo() -> Foo { 22_u32 } 14 | 15 | // Or, (mostly) equivalently: 16 | fn foo() -> impl Debug { 22_u32 } 17 | ``` 18 | 19 | this corresponds to an "opaque type" `O`. For each opaque type, the compiler has the job of determining exactly what type `T_hidden` it represents (`u32`, in our example). This is called the *hidden type* of O. `T_hidden` is called the *hidden type* because, for the most part, other code cannot rely on it. Instead, that code treats `O` opaquely -- i.e., as "some type that implements `Debug`". This means that it can determine that `O: Debug`, but not that `O: Eq`, even though `u32: Eq` is true. The only exception is with autotraits: other code can figure out that `O: Send` because `u32: Send`. This is called "auto trait leakage", and it will be discussed later. 20 | 21 | ### How the compiler infers the hidden type 22 | 23 | The compiler infers the hidden type for an opaque type by looking at how that opaque type is used within its *defining scope*. The defining scope is defined as all code within whatever "container" declared the opaque type: 24 | 25 | 1. For type-alias-impl-trait (`type Foo = impl Debug`), the defining scope is the enclosing function, module, or impl. 26 | 2. For return-position-impl-trait (`fn foo() -> impl Debug`), the defining scope is the body of the function `foo`. 27 | 28 | For the remainder of this discussion, we'll work with the example of a type-alias-impl-trait like so: 29 | 30 | ```rust 31 | type Foo = impl Debug; 32 | ``` 33 | 34 | When type-checking code within the defining scope of `Foo`, we may encounter variables or values that are declared to be of type `Foo`, like the local variable `x` in this example: 35 | 36 | ```rust 37 | type Foo = impl Debug; 38 | 39 | fn example() { 40 | let x: Foo = 22_u32; 41 | ... 42 | } 43 | ``` 44 | 45 | To be well-typed, this code requires that `u32` be a subtype of `Foo`. **Outside of the defining scope**, that would be an error -- but **inside** the defining scope, it is instead adopted as a constraint on what type `Foo` can represent. Therefore, `example` constrains `Foo`'s hidden type to be `u32` in this case. 46 | 47 | The same applies to the more common case of a function whose return type is declared as an opaque type: 48 | 49 | ```rust 50 | type Foo = impl Debug; 51 | 52 | fn make_foo() -> Foo { 53 | 22_u32 54 | } 55 | ``` 56 | 57 | `make_foo` also constrains `Foo`'s hidden type to be `u32`. 58 | 59 | Another way to get a value of an opaque type is through a recursive call, or through a call to another function within the defining scope: 60 | 61 | ```rust 62 | type Foo = impl Debug; 63 | 64 | fn make_foo() -> Foo { 65 | let mut x: Foo = make_foo(); 66 | x = 22_u32; 67 | x 68 | } 69 | 70 | fn make_bar() -> Foo { 71 | let x: Foo = make_foo(); 72 | 22_u32 73 | } 74 | ``` 75 | 76 | These functions both constrain `Foo` to be equal to `u32`. 77 | 78 | ### Incomplete constraints 79 | 80 | When a function imposes a constraint, it must be a complete type: 81 | 82 | ```rust 83 | type Foo = impl Debug; 84 | 85 | fn insufficient() { 86 | // ERROR: Requires `Foo = Option`, but what is `T`? 87 | let x: Foo = None; 88 | } 89 | ``` 90 | 91 | Note though that the function can apply multiple constraints, which together suffice to fully specify the hidden type: 92 | 93 | ```rust 94 | type Foo = impl Debug; 95 | 96 | // Constrains `Foo = Result` 97 | fn sufficient() { 98 | let x: Foo = Ok(22_u32); // Requires `Result` 99 | let y: Foo = Err(22_i32); // Requires `Result<_, i32>` 100 | } 101 | ``` 102 | 103 | This does not work across functions. Every function must declare a full hidden type. The following example will thus not work: 104 | 105 | ```rust 106 | type Foo = impl Debug; 107 | 108 | fn foo() -> Foo { Ok(42) } 109 | fn bar() -> Foo { Err(69) } 110 | ``` 111 | 112 | ### Functions that impose no constraints 113 | 114 | Even within the defining scope, it is possible for a function to reference values of the type `Foo` without imposing any constraints on them: 115 | 116 | ```rust 117 | type Foo = impl Debug; 118 | fn take_foo(f: Foo) { 119 | // Requires that `Foo: Debug`, but that is given 120 | // from the declared constraints. 121 | println!("{f:?}"); 122 | } 123 | ``` 124 | 125 | ### Multiple functions that all impose constraints 126 | 127 | When an opaque type is defined at the module level, it is possible for there to be multiple functions which each constrain the same opaque type: 128 | 129 | ```rust 130 | type Foo = impl Debug; 131 | 132 | fn example() { let x: Foo = 22_u32; } // Adds constraint: `Foo = u32` 133 | fn make_foo() -> Foo { 22_u32 } // Adds constraint: `Foo = u32` 134 | fn take_foo(f: Foo) { println!("{f:?}"); } // No constraint. 135 | ``` 136 | 137 | This is allowed, so long as all of the following are true: 138 | 139 | * all functions impose the same constraint 140 | * each function imposes a complete constraint without type variables 141 | * there is at least one constraint 142 | 143 | Examples that do *not* meet those rules: 144 | 145 | ```rust 146 | type Foo = impl Debug; 147 | 148 | fn make_u32() -> Foo { 22_u32 } 149 | fn make_i32() -> Foo { 22_i32 } 150 | ``` 151 | 152 | ### Implementing a trait (inside *or* outside a defining scope) 153 | 154 | When the compiler tries to decide if an opaque type `Foo` implements a trait, it does so based on the declared bounds (the one exception is auto traits; see below). The hidden type is never used. This means that we sometimes get errors where the hidden type would have worked: 155 | 156 | ```rust 157 | type Foo = impl Debug; 158 | 159 | fn is_display() { } 160 | 161 | fn example() { 162 | let f: Foo = u32; 163 | is_display::(); // Error: Foo is not known to be display 164 | } 165 | ``` 166 | 167 | This can be surprising when using APIs like `Default` or `collect`: 168 | 169 | ```rust 170 | fn foo() { 171 | let x: Foo = 42_i32; 172 | let y: Foo = Default::default(); // Error Foo: Default not satisfied 173 | } 174 | ``` 175 | 176 | You can fix code like the above by specifying the type manually: 177 | 178 | 179 | ```rust= 180 | fn foo() { 181 | let y: Foo = ::default(); // OK 182 | 183 | let z: i32 = Default::default(); 184 | let z: Foo = z; // Also OK 185 | } 186 | ``` 187 | ### Auto-trait leakage from *inside the defining scope* 188 | 189 | When some code `f` inside the defining scope attempts to determine whether an opaque type like `Foo` implements an auto-trait, this is considered to be adding a "constraint" on the hidden type. In other words, to show that `Foo: Send`, `f` must constrain `Foo` to be some hidden type `H` which implements `Send`. 190 | 191 | Example: 192 | 193 | ```rust 194 | type Foo = impl Debug; 195 | 196 | fn is_send() { } 197 | 198 | fn not_good() { 199 | // Error: this function does not constrain `Foo` to any particular 200 | // hidden type, so it cannot rely on `Send` being true. 201 | is_send::(); 202 | } 203 | 204 | fn ok() { 205 | // Constrain `Foo = u32` 206 | let x: Foo = 22_u32; 207 | 208 | // No problem `Foo = u32` and `u32: Send` 209 | is_send::(); 210 | } 211 | ``` 212 | 213 | ### Auto-trait leakage 214 | 215 | When code outside the defining scope attempts to determine whether some opaque type `Foo` implements an auto-trait, the code can "reveal" the hidden type, as shown here: 216 | 217 | ```rust 218 | mod defining_scope { 219 | pub type Foo = impl Debug; 220 | pub fn ok() -> Foo { 22_u32 } 221 | } 222 | 223 | fn is_send() { } 224 | 225 | fn example() { 226 | // OK: Reveals the hidden type for the purposes of checking `Send` 227 | is_send::(); 228 | } 229 | ``` 230 | 231 | Revealing the hidden type forces all code in the defining scope to be type-checked; it is a fatal compilation error if this results in a cycle: 232 | 233 | ```rust 234 | // Results in a cycle error. 235 | 236 | fn is_send() { } 237 | 238 | mod defining_scope1 { 239 | pub type Foo = impl Debug; 240 | pub fn ok() -> Foo { 241 | is_send::(); 242 | 22_u32 243 | } 244 | } 245 | 246 | mod defining_scope2 { 247 | pub type Bar = impl Debug; 248 | pub fn ok() -> Foo { 249 | is_send::(); 250 | 22_u32 251 | } 252 | } 253 | ``` 254 | 255 | ## Desirable properties of this algorithm 256 | 257 | * Because each function must impose a complete constraint, and because auto-trait leakage within the defining scope, all functions within the defining scope are checkable independently. 258 | * This is good for the compiler, but it also means that users can remove a function and their code continues to compile, as long as it was not the *only* constraint. 259 | 260 | 261 | ## Differences from our current behavior 262 | 263 | ### Insta-stable: Accept recursive call sites 264 | 265 | Consider this example: 266 | 267 | ```rust 268 | fn bar(b: bool) -> impl std::fmt::Debug { 269 | if b { 270 | return 42 271 | } 272 | let x: u32 = bar(false); // this errors on stable 273 | 99 274 | } 275 | ``` 276 | 277 | On stable today, this function fails to compile: 278 | 279 | ``` 280 | error[E0308]: mismatched types 281 | --> src/lib.rs:5:18 282 | | 283 | 1 | fn bar(b: bool) -> impl std::fmt::Debug { 284 | | -------------------- the found opaque type 285 | ... 286 | 5 | let x: u32 = bar(false); // this errors on stable 287 | | --- ^^^^^^^^^^ expected `u32`, found opaque type 288 | | | 289 | | expected due to this 290 | | 291 | = note: expected type `u32` 292 | found opaque type `impl Debug` 293 | ``` 294 | 295 | On the new branch, that code would be accepted. The recursive call to `bar` returns the opaque type, which is then constrained to be equal to `u32`. This constraint is accepted because it occurs within the defining scope (`bar`). 296 | 297 | ## Differences between TAIT and RPIT with this algorithm 298 | 299 | In principle, these two definitions of `foo` should be equivalent, apart from defining the type `Foo`: 300 | 301 | ```rust 302 | mod tait { 303 | pub type Foo: Debug; 304 | pub fn foo() -> Foo { .. } 305 | } 306 | 307 | mod rpit { 308 | pub fn foo() -> impl Debug { .. } 309 | } 310 | ``` 311 | 312 | However, crater testing revealed some cases where stable code (i.e., code using RPIT) was behaving in ways that the TAIT algorithm did not accept. Therefore, we added some "special cases" for RPIT notation. We need to decide (in follow-up PRs) how to align the behavior of TAIT and RPIT in these cases. **The current choices were made to allow for maximum future flexibility.** 313 | 314 | ### Return statement 315 | 316 | `return` statements and the trailing return expression are special with RPIT (but not TAIT). So while this TAIT program fails to compile 317 | 318 | ```rust 319 | #![feature(type_alias_impl_trait)] 320 | type Foo = impl std::fmt::Debug; 321 | 322 | fn foo(b: bool) -> Foo { 323 | if b { 324 | return vec![42]; 325 | } 326 | std::iter::empty().collect() //~ ERROR `Foo` cannot be built from an iterator 327 | } 328 | 329 | ``` 330 | 331 | The equivalent RPIT code works just fine: 332 | 333 | ```rust 334 | fn bar(b: bool) -> impl std::fmt::Debug { 335 | if b { 336 | return vec![42] 337 | } 338 | std::iter::empty().collect() // Works, magic 339 | } 340 | ``` 341 | 342 | The RFCs do not mention such cases and there are no tests in the Rust test suite excercising this behavior. 343 | 344 | Note that in the new insta stable case mentioned earlier, when we are working with the return value of a recursive call, both RPIT and TAIT get errors (on this branch and later): 345 | 346 | ```rust 347 | type Foo = impl std::fmt::Debug; 348 | 349 | fn foo(b: bool) -> Foo { 350 | if b { 351 | return vec![]; 352 | } 353 | let mut x = foo(false); 354 | x = std::iter::empty().collect(); //~ ERROR `Foo` cannot be built from an iterator 355 | vec![] 356 | } 357 | 358 | fn bar(b: bool) -> impl std::fmt::Debug { 359 | if b { 360 | return vec![]; 361 | } 362 | let mut x = bar(false); 363 | x = std::iter::empty().collect(); //~ ERROR `impl Debug` cannot be built from an iterator 364 | vec![] 365 | } 366 | ``` 367 | 368 | ### Branches 369 | 370 | Similar from the user perspective but very different on the compiler side, TAITs do not allow type inference across branches of an `if` or `match`: 371 | 372 | ```rust 373 | type Foo = impl std::fmt::Debug; 374 | 375 | fn foo(b: bool) -> Foo { 376 | if b { 377 | vec![42_i32] 378 | } else { 379 | std::iter::empty().collect() 380 | //~^ ERROR `Foo` cannot be built from an iterator over elements of type `_` 381 | } 382 | } 383 | ``` 384 | 385 | The equivalent RPIT example works just fine. 386 | 387 | It is easy to support, but we should make an explicit decision to include the additional complexity in the implementation (it's not much, see a721052457cf513487fb4266e3ade65c29b272d2 which needs to be reverted to enable this). 388 | 389 | For closures the opposite is true: 390 | 391 | ```rust 392 | fn bar(b: bool) -> impl std::ops::FnOnce(String) -> usize { 393 | if b { 394 | |x| x.len() //~ ERROR type annotations needed 395 | } else { 396 | panic!() 397 | } 398 | } 399 | ``` 400 | 401 | does not work on stable, even though 402 | 403 | ```rust 404 | fn bar1(b: bool) -> impl std::ops::FnOnce(String) -> usize { 405 | |x| x.len() 406 | } 407 | ``` 408 | 409 | does work. 410 | 411 | The equivalent code with TAIT works just fine with lazy TAIT, because the opaque type stays opaque right until it is compared against the closure, thus giving the maximum amount of information to the closure. 412 | 413 | ```rust 414 | type Foo = impl std::ops::FnOnce(String) -> usize; 415 | 416 | fn foo(b: bool) -> Foo { 417 | if b { 418 | |x| x.len() 419 | } else { 420 | panic!() 421 | } 422 | } 423 | 424 | 425 | type Foo1 = impl std::ops::FnOnce(String) -> usize; 426 | fn foo1(b: bool) -> Foo1 { 427 | |x| x.len() 428 | } 429 | ``` -------------------------------------------------------------------------------- /minutes/2022-04-28-lazy-type-alias-impl-trait-user-facing.md: -------------------------------------------------------------------------------- 1 | # Lazy TAIT Inference Algorithm Implications 2 | 3 | This write-up documents the effects of the new "lazy TAIT" inference algorithm implemented in [PR #94081](https://github.com/rust-lang/rust/pull/94081). 4 | 5 | It begins with a write-up explaining the algorithm "from first principles" -- i.e., how a user should understand it. It then explains some of the implications, and cases where this differences from the current stabilized behavior. 6 | 7 | [Zulip discussion thread](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-04-28.20-.20lazy.20type.20alias.20impl.20trait) 8 | 9 | ## Algorithm from first principles 10 | 11 | When you define an impl trait in "existential" position: 12 | 13 | ```rust 14 | type Foo = impl Debug; 15 | fn foo() -> Foo { 22_u32 } 16 | 17 | // Or, (mostly) equivalently: 18 | fn foo() -> impl Debug { 22_u32 } 19 | ``` 20 | 21 | this corresponds to an "opaque type" `O`. For each opaque type, the compiler has the job of determining exactly what type `T_hidden` it represents (`u32`, in our example). This is called the *hidden type* of O. `T_hidden` is called the *hidden type* because, for the most part, other code cannot rely on it. Instead, that code treats `O` opaquely -- i.e., as "some type that implements `Debug`". This means that it can determine that `O: Debug`, but not that `O: Eq`, even though `u32: Eq` is true. The only exception is with autotraits: other code can figure out that `O: Send` because `u32: Send`. This is called "auto trait leakage", and it will be discussed later. 22 | 23 | ### How the compiler infers the hidden type 24 | 25 | The compiler infers the hidden type for an opaque type by looking at how that opaque type is used within its *defining scope*. The defining scope is defined as all code within whatever "container" declared the opaque type: 26 | 27 | 1. For type-alias-impl-trait (`type Foo = impl Debug`), the defining scope is the enclosing function, module, or impl. 28 | 2. For return-position-impl-trait (`fn foo() -> impl Debug`), the defining scope is the body of the function `foo`. 29 | 30 | For the remainder of this discussion, we'll work with the example of a type-alias-impl-trait like so: 31 | 32 | ```rust 33 | type Foo = impl Debug; 34 | ``` 35 | 36 | When type-checking code within the defining scope of `Foo`, we may encounter variables or values that are declared to be of type `Foo`, like the local variable `x` in this example: 37 | 38 | ```rust 39 | type Foo = impl Debug; 40 | 41 | fn example() { 42 | let x: Foo = 22_u32; 43 | ... 44 | } 45 | ``` 46 | 47 | To be well-typed, this code requires that `u32` be a subtype of `Foo`. **Outside of the defining scope**, that would be an error -- but **inside** the defining scope, it is instead adopted as a constraint on what type `Foo` can represent. Therefore, `example` constrains `Foo`'s hidden type to be `u32` in this case. 48 | 49 | The same applies to the more common case of a function whose return type is declared as an opaque type: 50 | 51 | ```rust 52 | type Foo = impl Debug; 53 | 54 | fn make_foo() -> Foo { 55 | 22_u32 56 | } 57 | ``` 58 | 59 | `make_foo` also constrains `Foo`'s hidden type to be `u32`. 60 | 61 | Another way to get a value of an opaque type is through a recursive call, or through a call to another function within the defining scope: 62 | 63 | ```rust 64 | type Foo = impl Debug; 65 | 66 | fn make_foo() -> Foo { 67 | let mut x: Foo = make_foo(); 68 | x = 22_u32; 69 | x 70 | } 71 | 72 | fn make_bar() -> Foo { 73 | let x: Foo = make_foo(); 74 | 22_u32 75 | } 76 | ``` 77 | 78 | These functions both constrain `Foo` to be equal to `u32`. 79 | 80 | ### Incomplete constraints 81 | 82 | When a function imposes a constraint, it must be a complete type: 83 | 84 | ```rust 85 | type Foo = impl Debug; 86 | 87 | fn insufficient() { 88 | // ERROR: Requires `Foo = Option`, but what is `T`? 89 | let x: Foo = None; 90 | } 91 | ``` 92 | 93 | Note though that the function can apply multiple constraints, which together suffice to fully specify the hidden type: 94 | 95 | ```rust 96 | type Foo = impl Debug; 97 | 98 | // Constrains `Foo = Result` 99 | fn sufficient() { 100 | let x: Foo = Ok(22_u32); // Requires `Result` 101 | let y: Foo = Err(22_i32); // Requires `Result<_, i32>` 102 | } 103 | ``` 104 | 105 | This does not work across functions. Every function must declare a full hidden type. The following example will thus not work: 106 | 107 | ```rust 108 | type Foo = impl Debug; 109 | 110 | fn foo() -> Foo { Ok(42) } 111 | fn bar() -> Foo { Err(69) } 112 | ``` 113 | 114 | ### Functions that impose no constraints 115 | 116 | Even within the defining scope, it is possible for a function to reference values of the type `Foo` without imposing any constraints on them: 117 | 118 | ```rust 119 | type Foo = impl Debug; 120 | fn take_foo(f: Foo) { 121 | // Requires that `Foo: Debug`, but that is given 122 | // from the declared constraints. 123 | println!("{f:?}"); 124 | } 125 | ``` 126 | 127 | ### Multiple functions that all impose constraints 128 | 129 | When an opaque type is defined at the module level, it is possible for there to be multiple functions which each constrain the same opaque type: 130 | 131 | ```rust 132 | type Foo = impl Debug; 133 | 134 | fn example() { let x: Foo = 22_u32; } // Adds constraint: `Foo = u32` 135 | fn make_foo() -> Foo { 22_u32 } // Adds constraint: `Foo = u32` 136 | fn take_foo(f: Foo) { println!("{f:?}"); } // No constraint. 137 | ``` 138 | 139 | This is allowed, so long as all of the following are true: 140 | 141 | * all functions impose the same constraint 142 | * each function imposes a complete constraint without type variables 143 | * there is at least one constraint 144 | 145 | Examples that do *not* meet those rules: 146 | 147 | ```rust 148 | type Foo = impl Debug; 149 | 150 | fn make_u32() -> Foo { 22_u32 } 151 | fn make_i32() -> Foo { 22_i32 } 152 | ``` 153 | 154 | ### Implementing a trait (inside *or* outside a defining scope) 155 | 156 | When the compiler tries to decide if an opaque type `Foo` implements a trait, it does so based on the declared bounds (the one exception is auto traits; see below). The hidden type is never used. This means that we sometimes get errors where the hidden type would have worked: 157 | 158 | ```rust 159 | type Foo = impl Debug; 160 | 161 | fn is_display() { } 162 | 163 | fn example() { 164 | let f: Foo = u32; 165 | is_display::(); // Error: Foo is not known to be display 166 | } 167 | ``` 168 | 169 | This can be surprising when using APIs like `Default` or `collect`: 170 | 171 | ```rust 172 | fn foo() { 173 | let x: Foo = 42_i32; 174 | let y: Foo = Default::default(); // Error Foo: Default not satisfied 175 | } 176 | ``` 177 | 178 | You can fix code like the above by specifying the type manually: 179 | 180 | 181 | ```rust= 182 | fn foo() { 183 | let y: Foo = ::default(); // OK 184 | 185 | let z: i32 = Default::default(); 186 | let z: Foo = z; // Also OK 187 | } 188 | ``` 189 | ### Auto-trait leakage from *inside the defining scope* 190 | 191 | When some code `f` inside the defining scope attempts to determine whether an opaque type like `Foo` implements an auto-trait, this is considered to be adding a "constraint" on the hidden type. In other words, to show that `Foo: Send`, `f` must constrain `Foo` to be some hidden type `H` which implements `Send`. 192 | 193 | Example: 194 | 195 | ```rust 196 | type Foo = impl Debug; 197 | 198 | fn is_send() { } 199 | 200 | fn not_good() { 201 | // Error: this function does not constrain `Foo` to any particular 202 | // hidden type, so it cannot rely on `Send` being true. 203 | is_send::(); 204 | } 205 | 206 | fn ok() { 207 | // Constrain `Foo = u32` 208 | let x: Foo = 22_u32; 209 | 210 | // No problem `Foo = u32` and `u32: Send` 211 | is_send::(); 212 | } 213 | ``` 214 | 215 | ### Auto-trait leakage 216 | 217 | When code outside the defining scope attempts to determine whether some opaque type `Foo` implements an auto-trait, the code can "reveal" the hidden type, as shown here: 218 | 219 | ```rust 220 | mod defining_scope { 221 | pub type Foo = impl Debug; 222 | pub fn ok() -> Foo { 22_u32 } 223 | } 224 | 225 | fn is_send() { } 226 | 227 | fn example() { 228 | // OK: Reveals the hidden type for the purposes of checking `Send` 229 | is_send::(); 230 | } 231 | ``` 232 | 233 | Revealing the hidden type forces all code in the defining scope to be type-checked; it is a fatal compilation error if this results in a cycle: 234 | 235 | ```rust 236 | // Results in a cycle error. 237 | 238 | fn is_send() { } 239 | 240 | mod defining_scope1 { 241 | pub type Foo = impl Debug; 242 | pub fn ok() -> Foo { 243 | is_send::(); 244 | 22_u32 245 | } 246 | } 247 | 248 | mod defining_scope2 { 249 | pub type Bar = impl Debug; 250 | pub fn ok() -> Foo { 251 | is_send::(); 252 | 22_u32 253 | } 254 | } 255 | ``` 256 | 257 | ## Desirable properties of this algorithm 258 | 259 | * Because each function must impose a complete constraint, and because auto-trait leakage within the defining scope, all functions within the defining scope are checkable independently. 260 | * This is good for the compiler, but it also means that users can remove a function and their code continues to compile, as long as it was not the *only* constraint. 261 | 262 | 263 | ## Differences from our current behavior 264 | 265 | ### Insta-stable: Accept recursive call sites 266 | 267 | Consider this example: 268 | 269 | ```rust 270 | fn bar(b: bool) -> impl std::fmt::Debug { 271 | if b { 272 | return 42 273 | } 274 | let x: u32 = bar(false); // this errors on stable 275 | 99 276 | } 277 | ``` 278 | 279 | On stable today, this function fails to compile: 280 | 281 | ``` 282 | error[E0308]: mismatched types 283 | --> src/lib.rs:5:18 284 | | 285 | 1 | fn bar(b: bool) -> impl std::fmt::Debug { 286 | | -------------------- the found opaque type 287 | ... 288 | 5 | let x: u32 = bar(false); // this errors on stable 289 | | --- ^^^^^^^^^^ expected `u32`, found opaque type 290 | | | 291 | | expected due to this 292 | | 293 | = note: expected type `u32` 294 | found opaque type `impl Debug` 295 | ``` 296 | 297 | On the new branch, that code would be accepted. The recursive call to `bar` returns the opaque type, which is then constrained to be equal to `u32`. This constraint is accepted because it occurs within the defining scope (`bar`). 298 | 299 | ## Differences between TAIT and RPIT with this algorithm 300 | 301 | In principle, these two definitions of `foo` should be equivalent, apart from defining the type `Foo`: 302 | 303 | ```rust 304 | mod tait { 305 | pub type Foo: Debug; 306 | pub fn foo() -> Foo { .. } 307 | } 308 | 309 | mod rpit { 310 | pub fn foo() -> impl Debug { .. } 311 | } 312 | ``` 313 | 314 | However, crater testing revealed some cases where stable code (i.e., code using RPIT) was behaving in ways that the TAIT algorithm did not accept. Therefore, we added some "special cases" for RPIT notation. We need to decide (in follow-up PRs) how to align the behavior of TAIT and RPIT in these cases. **The current choices were made to allow for maximum future flexibility.** 315 | 316 | ### Return statement 317 | 318 | `return` statements and the trailing return expression are special with RPIT (but not TAIT). So while this TAIT program fails to compile 319 | 320 | ```rust 321 | #![feature(type_alias_impl_trait)] 322 | type Foo = impl std::fmt::Debug; 323 | 324 | fn foo(b: bool) -> Foo { 325 | if b { 326 | return vec![42]; 327 | } 328 | std::iter::empty().collect() //~ ERROR `Foo` cannot be built from an iterator 329 | } 330 | 331 | ``` 332 | 333 | The equivalent RPIT code works just fine: 334 | 335 | ```rust 336 | fn bar(b: bool) -> impl std::fmt::Debug { 337 | if b { 338 | return vec![42] 339 | } 340 | std::iter::empty().collect() // Works, magic 341 | } 342 | ``` 343 | 344 | The RFCs do not mention such cases and there are no tests in the Rust test suite excercising this behavior. 345 | 346 | Note that in the new insta stable case mentioned earlier, when we are working with the return value of a recursive call, both RPIT and TAIT get errors (on this branch and later): 347 | 348 | ```rust 349 | type Foo = impl std::fmt::Debug; 350 | 351 | fn foo(b: bool) -> Foo { 352 | if b { 353 | return vec![]; 354 | } 355 | let mut x = foo(false); 356 | x = std::iter::empty().collect(); //~ ERROR `Foo` cannot be built from an iterator 357 | vec![] 358 | } 359 | 360 | fn bar(b: bool) -> impl std::fmt::Debug { 361 | if b { 362 | return vec![]; 363 | } 364 | let mut x = bar(false); 365 | x = std::iter::empty().collect(); //~ ERROR `impl Debug` cannot be built from an iterator 366 | vec![] 367 | } 368 | ``` 369 | 370 | ### Branches 371 | 372 | Similar from the user perspective but very different on the compiler side, TAITs do not allow type inference across branches of an `if` or `match`: 373 | 374 | ```rust 375 | type Foo = impl std::fmt::Debug; 376 | 377 | fn foo(b: bool) -> Foo { 378 | if b { 379 | vec![42_i32] 380 | } else { 381 | std::iter::empty().collect() 382 | //~^ ERROR `Foo` cannot be built from an iterator over elements of type `_` 383 | } 384 | } 385 | ``` 386 | 387 | The equivalent RPIT example works just fine. 388 | 389 | It is easy to support, but we should make an explicit decision to include the additional complexity in the implementation (it's not much, see a721052457cf513487fb4266e3ade65c29b272d2 which needs to be reverted to enable this). 390 | 391 | For closures the opposite is true: 392 | 393 | ```rust 394 | fn bar(b: bool) -> impl std::ops::FnOnce(String) -> usize { 395 | if b { 396 | |x| x.len() //~ ERROR type annotations needed 397 | } else { 398 | panic!() 399 | } 400 | } 401 | ``` 402 | 403 | does not work on stable, even though 404 | 405 | ```rust 406 | fn bar1(b: bool) -> impl std::ops::FnOnce(String) -> usize { 407 | |x| x.len() 408 | } 409 | ``` 410 | 411 | does work. 412 | 413 | The equivalent code with TAIT works just fine with lazy TAIT, because the opaque type stays opaque right until it is compared against the closure, thus giving the maximum amount of information to the closure. 414 | 415 | ```rust 416 | type Foo = impl std::ops::FnOnce(String) -> usize; 417 | 418 | fn foo(b: bool) -> Foo { 419 | if b { 420 | |x| x.len() 421 | } else { 422 | panic!() 423 | } 424 | } 425 | 426 | 427 | type Foo1 = impl std::ops::FnOnce(String) -> usize; 428 | fn foo1(b: bool) -> Foo1 { 429 | |x| x.len() 430 | } 431 | ``` 432 | -------------------------------------------------------------------------------- /minutes/2022-05-27-mir-formality-roadmap.md: -------------------------------------------------------------------------------- 1 | # Formality roadmap 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-05-27/near/284128865 4 | 5 | ## Goals 6 | 7 | * Complete model of safe Rust including all static checks + operational semantics 8 | * Able to run against portions of standard Rust test suite to compare behavior 9 | 10 | ## Current status of MIR formality 11 | 12 | * Subtyping algorithm modeled 13 | * Solver is "explore all routes", does not match recursive structure in chalk 14 | * Many gaps along the way: 15 | * ... (fill in) 16 | 17 | ## Big picture tasks and layers 18 | 19 | * *Checking a MIR program:* The **mir** layer drives the process of checking that a program meets all of Rust rules. This relies on... 20 | * *OK goals*: the **decl layer** creates an "ok goal" for the various Rust declarations 21 | * *Type checker*: The **mir** layer 22 | * *Solving goals*: The **logic layer** is tasked with taking a goal and returning a answer scheme. This relies on... 23 | * *Defining what is true:* The **decl layer** is tasked with converting Rust declarations into *clauses* 24 | * *Built-in Rust rules:* The **ty layer** implements various built-in relations like subtyping 25 | 26 | ## Spikes 27 | 28 | The plan is to drive this development through *spikes*, meaning example tests that we can use to work out what parts of the sytem need to be implemented. nikomatsakis intends to have enough implemented by next Wednesday's formality meeting that folks can start filling in. 29 | 30 | Spikes and why they were chosen: 31 | 32 | * Issue #25860: https://github.com/nikomatsakis/a-mir-formality/issues/22 33 | * validates our fix to a long-standing soundness problem 34 | * Lending iterator: https://github.com/nikomatsakis/a-mir-formality/issues/40 35 | * important to pending stabilization 36 | * TAIT: 37 | * pending stabilization, but also raises some interesting questions 38 | 39 | ## Test driver 40 | 41 | Filed under https://github.com/nikomatsakis/a-mir-formality/issues/42 42 | 43 | > We should create a test harness / rustc driver `formalityc` that works as follows: 44 | > 45 | > * It parses an input rust crate and compiles it to MIR 46 | > * It generates MIR formality files from the MIR and some portion of the interfaces of other crates 47 | > * It writes those files to a test file and then invokes `racket` to run MIR formality against them 48 | > * It reads some sort of special comments (e.g., `// compile-fail`) to determine what behavior is expected. 49 | > 50 | > This can be used to extend our test suite with Rust test files rather than hand-coding things in Racket. 51 | > 52 | > Eventually I expect the racket code to go away and be replaced with either Rust code or (my current preference) some Rust interpreter of our definition. 53 | 54 | 55 | ## Implementation in rustc 56 | 57 | Another angle is ongoing work to align the formality model with rustc implementations: 58 | 59 | * subtyping work 60 | 61 | ## Discussion: Implementation in chalk 62 | 63 | Another angle is ongoing work to align the formality model with chalk implementations: 64 | 65 | * Formality does not model the chalk recursive trait solver 66 | * Chalk needs to adopt Formality's overall goal structure 67 | * Chalk needs to adopt Formality's subtyping and type-relating goals 68 | * Chalk needs to adopt Formality's approach to associated types 69 | 70 | Conclusion from discussion: probably we just want to restart chalk from scratch. 71 | 72 | ## Discussion: Overview of rustc static checks 73 | 74 | Key: 75 | 76 | * :x: never expect to model this 77 | * :hourglass: would like to model this, but not right now 78 | * :heavy_minus_sign: not covered by the spikes above 79 | * :heavy_check_mark: this is part of our first goal 80 | 81 | | Phase | Modeled? | How? | 82 | | --- | --- | --- | 83 | | Parsing | :x: 84 | | Macro expansion | :hourglass: 85 | | Name resolution | :hourglass: 86 | | Lifetime elision rules | :hourglass: 87 | | Associated type trait selection | :hourglass: | e.g. `T::Item` becoming `::Item` 88 | | Variance inference | :hourglass: | we will take variance as "input" to the declarations | 89 | | Coherence overlap / orphan | :heavy_check_mark: | The decl layer's OK check | 90 | | HIR type checker's WF checks | :heavy_check_mark: | The decl layer's OK check | 91 | | Dyn safety rules | :heavy_minus_sign: | 92 | | Impl matches trait? | :heavy_check_mark: | Decl layer's OK check| 93 | | Const promotion | :hourglass: | decided by MIR building in rustc 94 | | HIR type checking of fn bodies | :hourglass: | we take MIR as input | 95 | | Method resolution | :hourglass: | decided by HIR type checker, embedded in MIR | 96 | | Closure capture inference | :hourglass: | decided by HIR type checker, embedded in MIR | 97 | | Closure mode (fn, fnmut) and signature inference | :hourglass: | decided by HIR type checker, embedded in MIR | 98 | | Coercion insertion | :hourglass: | decided by HIR type checker, embedded in MIR | 99 | | Drop/StorageDead placement | :hourglass: | decided by MIR building in rustc | 100 | | Patterns/exhaustiveness | :hourglass: | decided by MIR building in rustc | 101 | | Unsafe checking | :heavy_minus_sign: | Part of "type checking" on MIR | 102 | | MIR type check | :heavy_check_mark: | mir layer generates goals 103 | | Borrow checking | :heavy_check_mark: | mir layer polonius-style check | 104 | | Rust subtyping | :heavy_check_mark: | modeled by the ty layer and also decl | 105 | | Operational semantics | :hourglass: | basically what miri does | 106 | | Transmute rules | :hourglass: 107 | | Layout | :hourglass: | input to operational semantics for now | 108 | 109 | ## Discussion: Const generics 110 | 111 | Discussion around whether we want to model const generics and what would be required to do so. 112 | 113 | Conclusion was that we needed deeper discussion, but some felt modeling const generics could be useful for resolving some of the questions around newer features; this would broaden scope to include 114 | 115 | ## Questions for discussion 116 | 117 | * What about coherence rules? 118 | * What is needed to align chalk and formality? 119 | * Should we include operational semantics and -- if so -- how does that fit in? 120 | * conclusion from meeting *seemed* to be to keep it out of scope to start 121 | * ~~What are all the static checks rustc does, and which are covered by the spikes above?~~ 122 | * see table 123 | * Const generics? -------------------------------------------------------------------------------- /minutes/2022-06-03-planning-meeting.md: -------------------------------------------------------------------------------- 1 | # Planning meeting 2 | 3 | No doc, [zulip link](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022.E2.80.9006.E2.80.9003) 4 | -------------------------------------------------------------------------------- /minutes/2022-06-10-backlog-bonanza.md: -------------------------------------------------------------------------------- 1 | # Backlog bonanza 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-06-10/near/285671935 4 | 5 | Live hackmd link: https://hackmd.io/x3xTr5T7QKeS4tppEV0N-g 6 | -------------------------------------------------------------------------------- /minutes/2022-06-17-backlog-bonanza.md: -------------------------------------------------------------------------------- 1 | # Backlog bonanza 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-06-17/near/286485814 4 | 5 | Live hackmd link: https://hackmd.io/x3xTr5T7QKeS4tppEV0N-g 6 | -------------------------------------------------------------------------------- /minutes/2022-06-24-backlog-bonanza.md: -------------------------------------------------------------------------------- 1 | # Backlog bonanza 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-06-24/near/287311992 4 | 5 | Live hackmd link: https://hackmd.io/x3xTr5T7QKeS4tppEV0N-g 6 | -------------------------------------------------------------------------------- /minutes/2022-07-01-planning-meeting.md: -------------------------------------------------------------------------------- 1 | # 2022-07-01 Planning meeting 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-07-01/near/288033700 4 | 5 | ## Initiative updates 6 | 7 | ### NLL 8 | 9 | * Centralized on the NLL checker 10 | * Found several unsound situations in how NLL was handling higher-ranked projects, some fixed, some not yet: 11 | * #98095: Outlives requirements for projections, `for<'a> T: 'a` in where-clauses. Fixed by XXX. 12 | * #98693: Promoting requirements in higher universes. Fixed by #98713 (not yet landed). 13 | * #98589: Investigated -- not a *soundness* concern per se, but more of a "surprising behavior" concern, where the inferencer seems to be introducing inference that allows for named lifetimes in a closure to be approximated if it would be otherwise sound to do so. Should probably fix to prevent code from relying on it. 14 | 15 | **Question:** Should we beta revert? 16 | 17 | *Situation:* Stabilized NLL. Found 1 bug (#98095) 18 | 19 | *Premise:* if we do so, we'll give 6 more weeks to find bugs on nightly 20 | 21 | *But:* 22 | 23 | * Existing bugs are all concerning treatment of higher-ranked regions, which makes sense as that is where lexical check still differed from NLL 24 | * Most have been found by systematically comparing NLL code -- that process has completed, but we can do another check 25 | * Fixes for existing bugs have not had broad ecosystem impact (so unlikely to affect a lot of people) 26 | * Reverting on beta is a lot of work 27 | 28 | *Ways to reduce risk:* 29 | 30 | * We've not finished investigating #98589, so we can't say with certainty the impact of a fix there. We'll try to prioritize that. 31 | * Do a final review of the NLL code, given the existing pattern of bugs, to look for new instances 32 | 33 | ### GATs 34 | 35 | * Posted summary comments: 36 | * [Summarizing concerns](https://github.com/rust-lang/rust/pull/96709#issuecomment-1129311660) 37 | * [Deep-dive into some use patterns](https://github.com/rust-lang/rust/pull/96709#issuecomment-1167220240) 38 | * Other things: 39 | * Bevy report coming 40 | * Niko [synced with lang team to start FCP](https://github.com/rust-lang/lang-team/blob/master/minutes/2022-06-28.md#generic-associated-types) 41 | * Niko diving into WF stuff 42 | 43 | ### TAITs 44 | 45 | * [unsoundness due to lazy TAIT refactor](https://github.com/rust-lang/rust/issues/98608) 46 | * minimal paper-over PR available, but is perf regression 47 | * working on a real fix 48 | * [allow destructuring opaque types](https://github.com/rust-lang/rust/pull/98582) 49 | * `let (a, b) = some_tait;` registers a tuple as the hidden type instead of ICEing 50 | * [wf check generators](https://github.com/rust-lang/rust/pull/97183) 51 | * crater clean, needs review 52 | * [wf check opaque types](https://github.com/rust-lang/rust/pull/95474) 53 | * blocked on t-types checky boxes in https://github.com/rust-lang/rust/pull/97406 54 | 55 | ### RPIT refactor 56 | 57 | - We are lowering APITs and impl/traits blocks generics from AST, so no HIR copying. 58 | - Fixed some minor bugs related to the feature flag handling and some async fns issues 59 | - There are 3 issues that I've identified already: 60 | - in bound normalization tests where some lifetime bounds are not properly mapped to the RPIT, need to investigate this better 61 | - the RPIT doesn't have the Sized bound added implicitly, so if nothing in the function has that bound the RPIT is not Sized which is wrong 62 | - Some const fn issues in async functions, tries to subst &[] with index 0 63 | - Maybe @nikomatsakis/@oli can explain better than me the 'static problem 64 | 65 | ### Subtyping refactor 66 | 67 | * Remove universe logic from NLL 68 | - current step is: 69 | - simplify the "outlives requirement" (`T: 'a'`) clauses in the trait solver, not in the region check 70 | - https://github.com/rust-lang/rust/pull/97641/ 71 | - next step is: 72 | - make outlives environment available to trait solver, ideally refactor into parameter environment 73 | - we used to have to wait until type inference was done, but now (in NLL) we don't have to 74 | - blocked on: 75 | - https://github.com/rust-lang/rust/pull/98584 76 | - subsequent steps is: 77 | - handle type parametrs and regions in fulfill by searching parameter bounds etc 78 | - we can remove the "outlives" code entirely 79 | - and NLL no longer has to think about higher-ranked stuff 80 | - can remove universes from NLL* niko to think about how new subtyping algorithm coallesces of lifetime edges and model in a-mir-formality 81 | * no progress on splitting predicates into goals and clauses 82 | 83 | ### Trait object upcasting 84 | 85 | In a [recent Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/dyn-upcasting.20stabilization), there was a long conversation about stabilization, resulting in: 86 | 87 | * [Revised document](https://hackmd.io/@nikomatsakis/rJDzKH-Fq) outlining the various options. This resulted in a simpler set of choices: 88 | * "Fully valid vtable", which requires a fully valid vtable to create a `*const dyn`. We established that some of the more complex framings of this solution (e.g., "sufficiently valid vtables") weren't really necessary to buy forwards compatibility. This option is maximally conservative, but can be loosened in the future. 89 | * "Operations are UB", which permits creating `*const dyn` values with arbitrary vtables, but makes it UB to upcast or invoke methods on them, which effectively forbids them from escaping to safe code (since those operations are safe). This option is maximally permissive for users in terms of avoiding UB. 90 | 91 | The next step here is to check in briefly with unsafe code guidelines WG representatives and move to stabilization with one of the above variants. 92 | 93 | ### Negative impls 94 | 95 | Current state is that the code for this is largely implemented, modulo one outstanding issue ([#93875](https://github.com/rust-lang/rust/issues/93875)). 96 | 97 | We added a [rough model of coherence](https://github.com/nikomatsakis/a-mir-formality/pull/66) to a-mir-formality. 98 | 99 | No notable progress on the [RFC](https://hackmd.io/ZmpF0ITPRWKx6jYxgCWS7g?both). 100 | 101 | ### a MIR Formality 102 | 103 | ### Polonius 104 | 105 | * Developed a [roadmap and task listing](https://hackmd.io/@nikomatsakis/rJDoTg9Y5?type=view#task-listing) 106 | * upcoming tasks: 107 | * drafting canonical loan analysis, ideally in mir-formality 108 | 109 | ### chalk-ty 110 | 111 | * We are now unblocked to move 112 | * [Moved `RegionKind` to `rustc_type_ir`](https://github.com/rust-lang/rust/pull/98247) 113 | * @eggyal continues to make progress on aligning TypeFoldable/TypeVisitor 114 | * Needs review: 115 | * #98206 116 | * chalk#772 117 | 118 | ## Nominated issues 119 | 120 | ### #98117 Unsoundness due to where clauses not checked for well-formedness 121 | 122 | ### #98543 implied bounds from associated types may not actually get implied pt 2. 123 | 124 | ### #98693 NLL and closures: higher-ranked lifetime bounds are not enforced in type tests -------------------------------------------------------------------------------- /minutes/2022-07-08-implied-bounds-and-wf-checking.md: -------------------------------------------------------------------------------- 1 | # Implied bounds and well-formedness checking 2 | 3 | [Zulip topic for discussion](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-07-08) 4 | 5 | ## Goal 6 | 7 | To reconcile compiler's notion of implied bounds, in-scope types, and WF checking with something in a-mir-formality that can live with and that is simple and easy to understand. 8 | 9 | Also, to figure out how to integrate implied bounds into HRTB so as to address GAT usability concerns. 10 | 11 | ## Terminology 12 | 13 | In writing this document, I realized that I have interchangeably used the terms implied bounds for multiple things. I'm going to avoid the term implied bound and introduce some distinctions: 14 | 15 | * *Elaborated bounds* refers to cases where we figure out, based on one where clause, other things that must be true. For example, supertraits, where `T: Ord` implies that `T: Eq` also holds. I'll call that an elaborated bound. 16 | * *Default bounds* refers to cases where we add where-clauses of various kinds. We do this for two reasons: 17 | * *In-scope types* -- look at types that appear in a declaration and use that to imply some where-clauses that must hold. For example, `fn foo<'a, T>(x: &'a T)` considers `&'a T` to be an in-scope type, and hence can conclude that `T: 'a` must hold. 18 | * *Higher-ranked* -- to make higher-ranked bounds make sense. 19 | 20 | Implied bounds are then the union of elaboarted + defaulted. In both cases, they refer to facts that we are able to conclude that were not explicitly written by the user and which were not synthesized using impls. 21 | 22 | ## Integrating in-scope types into a-mir-formality and Rust 23 | 24 | The main goal for in-scope types has been to convert them into implicit where clauses that get added very early on in the process and which can be ignored from that point forward. I've been modeling this in a-mir-formality. 25 | 26 | To get a sense for what I mean, consider the following list of mir-formality layers and their rough rustc equivalents (note that this doesn't quite correspond to what's in the codebase; in the act of writing this doc I decided it made sense to split the existing "mir" layer into check/body): 27 | 28 | | Layer | rustc | Defines | Requires from upper layers via hook | 29 | | --- | --- | --- | --- | 30 | | rust | AST | user-facing syntax for decls/bodies, how that lowers into internal syntax | | 31 | | check | HIR | overall check of the Rust program | | 32 | | body | MIR type checker | grammar of fn bodies, type and borrow checker | | 33 | | decl | HIR-level queries, traits | grammar of Rust declarations, program clauses derived from Rust syntax like traits/impls | 34 | | ty | ty module, relate, infer | grammar of Rust types, definition of relations | generic types for a given ADT | 35 | | logic | traits | what is provable | set of program clauses, definition of relations, semantics of a predicate | 36 | 37 | In [my branch](https://github.com/nikomatsakis/a-mir-formality/tree/biformulas-everywhere), in-scope types are introduced as part of the **lowering in the rust layer** (the equivalent of AST->HIR lowering in rustc). 38 | 39 | As an example, consider a function like 40 | 41 | ```rust 42 | fn foo<'a, T>(x: &'a T) 43 | where 44 | T: Ord 45 | ``` 46 | 47 | Or, in the grammar of a-mir-formality's rust layer: 48 | 49 | ``` 50 | (fn foo[(lifetime a) (type T)]((& a T)) -> () 51 | where [(T : Ord[])] 52 | {trusted-fn-body}) 53 | ``` 54 | 55 | When this function gets lowered into the "decl layer", we wind up with the following where clauses: 56 | 57 | * `(is-implemented (Ord [T]))` -- derived from `(T : Ord[])` ([code](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/rust/lower-to-decl/fn-decl.rkt#L15)) 58 | * `(well-formed (type (& a T)))`[^user-ty] -- in-scope type, automatically inserted ([code](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/rust/lower-to-decl/fn-decl.rkt#L16-L17)) 59 | 60 | [^user-ty]: The type `(& a T)` here is not the actual a-mir-formality syntax. That's the "user type", and to be correct, we ought to write `(user-ty (& a T))`, which invokes a function to convert to the internal representation. The internal representation is `(rigid-ty (ref ()) [a T])`, but you can see why I didn't want to write that. 61 | 62 | Here, for example, is the current [code for lowering a function](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/rust/lower-to-decl/fn-decl.rkt#L10-L22). The `👈🥱` line marks the point where the user-given where-clauses are converted. The `👈🚨` lines mark the where clauses for in-scope types. 63 | 64 | ``` 65 | (define-metafunction formality-rust 66 | lower-to-decl/FnDecl : Rust/FnDecl -> FnDecl 67 | 68 | [(lower-to-decl/FnDecl (fn FnId KindedVarIds (Rust/Ty_arg ...) -> Rust/Ty_ret 69 | where [Rust/WhereClause ...] FnBody)) 70 | (fn FnId KindedVarIds ((user-ty Rust/Ty_arg) ...) -> (user-ty Rust/Ty_ret) 71 | where [(lower-to-decl/WhereClause Rust/WhereClause) ... ; 👈🥱 72 | (well-formed (type (user-ty Rust/Ty_arg))) ... ; 👈🚨 73 | (well-formed (type (user-ty Rust/Ty_ret))) ; 👈🚨 74 | ] 75 | FnBody) 76 | ] 77 | ) 78 | ``` 79 | 80 | ## Elaborating in-scope types 81 | 82 | In the previous section, we talked about how an in-scope type resulted in a where-clause `(well-formed (type (& a T))` being added to the function. But the *effect* of this is that the fn is supposed to be able to conclude that `T: 'a` (or, in mir-formality terms, `T -outlives- a`)...how does that work? 83 | 84 | This is where **elaboration** comes in. We have a concept of elaboration which takes the set of hypotheses (where-clauses assumed to be true) and converts them into a richer set. This is done based on *invariants*, and one such invariant is 85 | 86 | * `(well-formed (type (& a T)))` implies `(T -outlives- a)` 87 | 88 | In other words: if you know that `&'a T` is well-formed, you can assume that `T: 'a` must also be true. We introduce other invariants based on struct declarations and where clauses. So for example `struct Foo<'a, 'b, T> where T: 'a + 'b` introduces two invariants 89 | 90 | * `(well-formed (type (Foo < a b T >)))` implies `(T -outlives- a)` 91 | * `(well-formed (type (Foo < a b T >)))` implies `(T -outlives- b)` 92 | 93 | ### Other kinds of elaboration 94 | 95 | We haven't fully implemented the elaboration of outlives types in a-mir-formality yet, that is [a-mir-formality/#63](https://github.com/nikomatsakis/a-mir-formality/issues/63). In rustc, if you know that `Vec: 'a`, we conclude that `T: 'a`. This is based on the (hard-coded) outlives rules for when `Vec: 'a` (iff `?T: 'a`). This kind of reasoning is very important in traits and impls. Consider this case: 96 | 97 | ```rust 98 | trait Get { 99 | type T; 100 | fn get(&'g self) -> &'g Self::T; 101 | } 102 | 103 | impl<'a, T> Get for &'a T { 104 | type T = T; 105 | 106 | fn get<'g>(&'g self) -> &'g T { 107 | &*self 108 | } 109 | } 110 | ``` 111 | 112 | This impl looks reasonable, right? But if you look closely at the definition of `get`, you'll see there's something subtle going on: 113 | 114 | * `&*self` yields a value of type `&'a T` 115 | * but the return type is `&'g T` 116 | 117 | How do we know that `'a: 'g`, and hence it is legal to upcast? For that matter, how do we know that `T: 'g`? 118 | 119 | If you consider the trait/impl pair with in-scope types written in full, it becomes more clear: 120 | 121 | ```rust 122 | trait Get { 123 | type T; 124 | fn get(&'g self) -> &'g Self::T 125 | where 126 | well_formed(&'g Self); 127 | } 128 | 129 | impl<'a, T> Get for &'a T { 130 | type T = T; 131 | 132 | fn get<'g>(&'g self) -> &'g T 133 | where 134 | well_formed(&'g &'a T) 135 | { 136 | &*self 137 | } 138 | } 139 | ``` 140 | 141 | The impl's where-clause follows from the trait where-clause, and because `&'g &'a T` is well-formed, we can conclude that `T: 'a: 'g`. But deriving all those facts relies on a combination of elaboration and invariants. 142 | 143 | ## How does this notion of in-scope types compare with rustc's behavior? 144 | 145 | When it comes to in-scope types on functions and impls, the mir-formality version roughly matches rustc's behavior, except that it closes soundness holes like [#25860](https://github.com/rust-lang/rust/issues/25860). 146 | 147 | Part of why those soundness holes arise is because rustc integrates in-scope types in a kind of ad-hoc, complex way around the codebase. We have things that the callee is assuming to be true (`T: 'a`) but they are not listed explicitly as facts the caller must prove and -- indeed -- the caller does not always wind up proving them. 148 | 149 | ### Can we just do this in rustc then and fix the bug? 150 | 151 | Not now, but eventually yes! The reason that rustc is setup the way it is is to deal with the early- vs late-bound distinction. Consider this function: 152 | 153 | ```rust 154 | fn foo(x: &T) { 155 | } 156 | ``` 157 | 158 | The type of `foo` is `for<'a> fn(&'a ?T)` -- i.e., `T` is converted into an inference variable when you reference it, but `'a` remains *late-bound*. If we were to add a where-clause during AST->HIR conversion, however... 159 | 160 | 161 | ```rust 162 | fn foo<'a, T>(x: &'a T) 163 | where 164 | T: 'a // or `well_formed(&'a T)`, if we had that, etc 165 | { 166 | } 167 | ``` 168 | 169 | ...then `'a` would become *early-bound*, meaning that the type of `foo` would be `fn(&'?a ?T)`, where both `'a` and `T` become inference variables. This is required because we have to register the where-clause `?T: '?a` to be proven at some point. 170 | 171 | If we had richer types, though, the type of `foo` could be 172 | 173 | ``` 174 | for<'a, T> where (T: 'a) fn(&'a T) 175 | ``` 176 | 177 | ...and this is precisely what a-mir-formality supports. 178 | 179 | *That said*, we might be able to do *something* in this direction, because of the fndecl vs fnpointer distinction (which I was ignoring here). Worth thinking about, perhaps. 180 | 181 | ## Well-formedness checking 182 | 183 | OK, so we have a notion of in-scope types -- how does that fit with **well-formedness checking**? This term is again a kind of "catch-all" that we use for various things in rustc. I'm going to be more specific: 184 | 185 | * A type is *well-formed* if it (a) all of its constituent types are well-formed and (b) it meets all of the where clauses declared on the relevant type (or built-in, in the case of things like `&T`). 186 | * So `Vec` is well-formed if (a) `T` is well-formed and (b) `T: Sized` is true (since `Vec` has `where T: Sized` and nothing else). 187 | * A where-clause is *well-formed* if (a) all of its constituent terms (types or where-clauses) are well-formed and (b) it meets all of the where clauses declared on the relevant trait (if any). 188 | * So `T: Ord` is well-formed if (a) `T` is well-formed and (b) `T: Eq` is true, since `trait Ord` has `where Self: Eq` (i.e., a supertrait). 189 | * Similarly `Foo: 'a` is well-formed if (a) `Foo` is well-formed and `'a` is well-formed (there are no where-clauses to consider, so (b) doesn't apply). 190 | * A **declaration** is well-formed if (a) all of its constituent terms are well-formed. There are no where-clauses to meet[^check-vs-wf]. 191 | * So `impl Ord for Vec where T: Ord` is legal if... 192 | * the type `Vec` is WF 193 | * the where clause `T: Ord` is WF 194 | * the where clause `Vec: Ord` is WF (it's a bit of a stretch, but we'll say the trait-ref being implemented is a constituent term) 195 | 196 | [^check-vs-wf]: You could say that the "where clauses declared elsewhere that must be met" for a declaration are things like: an impl must ensure that it meets the signatures declared on the trait, etc. Or similarly, that a struct's fields must be well-formed. That's what rustc does, I think, when we do these checks in wf checking. I've changed it because (as I discuss below) I want to maintain the invariant in mir-formality that WF checking is NOT required for soundness; the rules exist to meet user expectations and because of semver considerations. At present, this split is not as clear as I would like in mir-formality, I'm trying to establish it. 197 | 198 | ### Elaboration and WF checking 199 | 200 | When we check well-formedness for a declaration, we do so in an environment that assumes that all the where-clauses on the declaration hold (and their elaborations). Consider the rule that says, for `T: Ord` to be WF, `T: Eq` must hold -- we don't require explicitly writing `T: Eq`, why is that? It's because it follows from `T: Ord` by elaboration. However, because our elaboration only elaborates supertrait where-clauses, some where-clauses declared on the trait *do not follow* implicitly and must be declared explicitly: 201 | 202 | ```rust 203 | trait BothOrd: Ord {} 204 | 205 | fn foo() 206 | where 207 | A: BothOrd 208 | {} 209 | ``` 210 | 211 | This function is [not well-formed](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7a37c6f128fdc7b3b1077a815419ae6f) because it lacks `B: Ord`. This is because `A: BothOrd` is well-formed if `A: Ord` and `B: Ord`. The first follows by elaboration from `A: BothOrd`, but the second does not. 212 | 213 | ### In mir-formality, WF checking is a "nice to have" 214 | 215 | The way that mir-formality is setup, WF checking is NOT required for soundness. Loosely speaking, the idea is this: declarations are allowed to assume that their constituent terms are well-formed. The caller is responsible for proving it. 216 | 217 | One of the ways this plays out is: to prove `(is-implemented (SomeTrait [SomeType]))`, in mir-formality, we must prove both that 218 | 219 | * `(has-impl (SomeTrait [SomeType]))` -- i.e., there is an impl somewhere 220 | * and that the `(SomeTrait [SomeType])` is well-formed, meaning that (a) `SomeType` is WF and (b) the where-clauses on `SomeTrait` hold. 221 | 222 | In rusc, this works differently. We only prove the first part, and we assume (thanks to WF checking etc) that the secondary stuff holds. But this doesn't work when you extend to coinduction. In that case, it's possible to have self-supporting impls (at least unless we impose some conditions on the kinds of where-clauses you can have in impls, and I've not found a formulation of those conditions that accepts the kind of code we currently accept). 223 | 224 | So, if WF checking is not required, why do we do it? To be honest, I'm not totally sure we should! I think it might be better to make WF checking a kind of lint (i.e., detecting cases where the caller couldn't possibly prove things are WF and warning about it, but otherwise accepting what was written). But I'm trying to model rustc roughly as it is so that we can then describe proposed changes in terms of the model. 225 | 226 | ### Defining well-formedness 227 | 228 | So, in (my branch of) mir-formality, I've defined some functions that create the `Goal` required to prove a given term (type, where-clause) is well-formed: 229 | 230 | * [`well-formed-goal-for-ty`](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/decl/well-formed/parameter.rkt#L17) takes a type and gives back the goal to prove it well-formed 231 | * [`well-formed-goal-for-lt`](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/decl/well-formed/parameter.rkt#L31) does the same for lifetimes (not much to do there...) 232 | * [`well-formed-goal-for-biformula`](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/decl/well-formed/biformula.rkt#L18)[^biformula] does the same for where-clauses 233 | 234 | [^biformula]: Biformula? WTF is that? This "mir-formality" for a lowered "where-clause", kind of a `ty::Predicate` in rustc. The name biformula is meant to suggest it is a logical formula that can serve *either* as a goal (something you have to prove) or a clause/hypothesis (something you can assume is true). An earlier name was `Goal∧Clause` but that got annoying to read and pluralize. :) 235 | 236 | There is also a predicate `(well-formed (type Ty))`. Proving that predicate requires proving `(well-formed-goal-for-ty Ty)`. This predicate is in fact "built-in" by the decl layer, meaning that we define it with some custom code; this is needed (a) to account for the infinite variety of types (e.g., tuples of arbitrary arity) in ways that we don't currently permit users to quantify (i.e., you can't write an impl that covers tuples of arbitrary arity), but also (b) to gently guide the trait solver away from some hopeless corners (i.e., proving that `(well-formed (type ?T))` is true by enumerating the (infinite) set of well-formed types `?T`). 237 | 238 | ## Extending in-scope types to higher-ranked things 239 | 240 | So far, everything we said matches rustc's behavior (more or less). Now let's talk about higher-ranked types and trait bounds. Rustc's behavior around these is kind of inconsistent and not very useful. I spent a while trying to [rationialize and model it](https://hackmd.io/0tbjoWROTGC3uqGFF_iVHw), with some success, but ultimately let's talk about how to make it useful. 241 | 242 | I'm going to start by focusing on *higher-ranked trait bounds* and come back to higher-ranked types. 243 | 244 | ### Problem: `for<'a>` shouldn't really mean for **ALL** `'a` 245 | 246 | Right now, when you write `for<'a> Predicate`, it means that `Predicate` 247 | is true **for all** `'a`. That turns out to not be an especially useful definition. Almost always what we want is more like **for any suitable `'a`**. Here is a rather artificial example to show you what I mean. Consider a trait `IntoData`, that lets you convert some type into a slice with lifetime `'d`, so long as `'d` is "suitably short"[^assoc]: 248 | 249 | [^assoc]: Side note that this is probably not the way to model this problem, you'd probably prefer an associated type for the slice, or perhaps an associated lifetime, if we had those. But never mind. 250 | 251 | ```rust 252 | trait IntoData<'d> 253 | where 254 | Self: 'd, 255 | { 256 | fn into_data(self) -> &'d [u32]; 257 | } 258 | 259 | impl<'d> IntoData<'d> for &'d [u32] { // example impl 260 | fn into_data(self) -> &'d [u32] { 261 | self 262 | } 263 | } 264 | ``` 265 | 266 | Now we might like to define a function that takes some `T` that implements `MakeRef`: 267 | 268 | ```rust 269 | fn foo(t: T) 270 | where 271 | T: for<'short> IntoData<'short> 272 | { 273 | let data: &[u32] = t.into_data(); 274 | process(data); 275 | } 276 | ``` 277 | 278 | But what happens when I call foo? ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8f0ed5d96f022fba2e0c367edf119a45)) 279 | 280 | ``` 281 | error: implementation of `IntoData` is not general enough 282 | --> src/main.rs:27:5 283 | | 284 | 27 | foo(s); 285 | | ^^^ implementation of `IntoData` is not general enough 286 | | 287 | = note: `IntoData<'0>` would have to be implemented for the type `&[u32]`, for any lifetime `'0`... 288 | = note: ...but `IntoData<'1>` is actually implemented for the type `&'1 [u32]`, for some specific lifetime `'1` 289 | ``` 290 | 291 | Huh, well *that's* annoying. The error makes sense though -- we can't really say that `T: IntoData<'short>` for **any** lifetime `'short`, only for lifetimes that are 'suitably short' (in particular, those where `T: 'short`). 292 | 293 | Of course, this example is kind of artificial and silly. Part of the reason for that is that in-scope types on impls often allow us to circumvent these problems. For example, I could write `IntoData` somewhat differently: 294 | 295 | ```rust 296 | trait GetData { 297 | fn data(&self) -> &[u32] 298 | } 299 | ``` 300 | 301 | ...and it would work for that particular example. Of course, the reason it works is because of in-scope types, as we saw earlier. And, of course, this is not the same interface: I can't use this interface to convert a `T` into a `&[u32]` that I can return from the function. 302 | 303 | This problem arises a lot with GATs. Consider this: 304 | 305 | ```rust 306 | trait LendingIterator { 307 | type Item<'a> where Self: 'a; 308 | } 309 | 310 | fn foo() 311 | for<'a> T: LendingIterator = &'a u32> 312 | { 313 | 314 | } 315 | ``` 316 | 317 | Now imagine calling `foo` for some specific type `MyLendingIter<'b>`. To prove that `MyLendingIter<'b>: LendingIterator = &'a u32>`, we have to show that the where-clause `Self: 'a` holds, which means `MyLendingIter<'b>: 'a` -- and we have to show that **for any** `'a`. But of course that's not true, so we will get a similar error. 318 | 319 | ### Solution: add defaulted bounds 320 | 321 | How can we solve the above? We need some default bounds. Roughly speaking, my idea is to say that, when we convert `for

WhereClause` to a biformula, instead of doing [this](https://github.com/nikomatsakis/a-mir-formality/blob/8a83f2c55425d220d89d78b6e1039dfdcfed6bed/src/rust/lower-to-decl/where-clause.rkt#L12-L13): 322 | 323 | ``` 324 | [(lower-to-decl/WhereClause (for KindedVarIds Rust/WhereClause)) 325 | (∀ KindedVarIds (lower-to-decl/WhereClause Rust/WhereClause))] 326 | ``` 327 | 328 | ...we will do something like this[^gerk]... 329 | 330 | [^gerk]: For various annoying "needs refactoring"-type reasons, you couldn't copy and paste this into mir-formality as is. We have to ensure that the `well-formed-goal-for-biformula` returns a biformula, and not an arbitrary goal, for example (I think it does), and that we don't include `&&` connectives (not sure about that), or else that we normalize them, and a few other annoying things. 331 | 332 | ``` 333 | [(lower-to-decl/WhereClause (for KindedVarIds Rust/WhereClause)) 334 | (∀ KindedVarIds 335 | (implies [Biformula_wf] Biformula)) 336 | ) 337 | (where/error Biformula (lower-to-decl/WhereClause Rust/WhereClause))] 338 | (where/error Biformula_wf (well-formed-goal-for-biformula Biformula)) 339 | ``` 340 | 341 | In other words, `for<'a> WC` where `WC` is some where clause is "short for" `for<'a> if (WC is well-formed) WC`. In other words, there are enough defaulted where-clauses to ensure that the where clause `WC` is well-fromed. 342 | 343 | * `for

WhereClause` 344 | 345 | ### What happens if we do this? 346 | 347 | Let's go back to our example of a caller function that didn't compile ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8f0ed5d96f022fba2e0c367edf119a45)): 348 | 349 | ```rust 350 | fn main() { 351 | let x = vec![1, 2, 3]; 352 | let s: & /*'a*/ u32 = &x[..]; // call the lifetime here 'a 353 | foo(s); // ERROR 354 | } 355 | 356 | fn foo(t: T) 357 | where 358 | T: for<'short> IntoData<'short> 359 | { 360 | let data: &[u32] = t.into_data(); 361 | process(data); 362 | } 363 | ``` 364 | 365 | The problem here was that `main` had to prove that `&'a [u32]: 'short` for all `'short`, and that just wasn't true. But with these new implications, `main` has to prove something else: 366 | 367 | ``` 368 | forall<'short> { 369 | if (&'a [u32]: 'short) { // where clause from `IntoData` 370 | &'a [u32]: 'short // OK, that seems true :) 371 | } 372 | } 373 | ``` 374 | 375 | ### Status of implementation 376 | 377 | I haven't *QUITE* gotten this part modeled in mir-formality yet, there's some refactoring and tweaks needed. But actually writing out this doc helped me to see that my in-progress edits were wrong-headed anyway so that's good. 378 | 379 | ## What about WF for higher-ranked TYPES? 380 | 381 | OK, it's 8:54am and I'm frantically typing to finish this by 9am, but the short version is that for `for

T` we'll add in defaulted conditions in the same way, something like `for

if (T is well-formed) T`. Since mir-formality supports implication types, this should be possible. 382 | 383 | ## Questions from meeting 384 | 385 | Feel free to add questions here, use `###` as the header. 386 | 387 | ### Question format 388 | 389 | nikomatsakis: Wait, how do I format the questions, can you show me an example? 390 | 391 | Yep, just like this! 392 | 393 | ### Comparing these defaults to rustc 394 | 395 | nikomatsakis: Wait! I have a question! How do these defaults for higher-ranked trait bounds compare to what rustc does? 396 | 397 | Answer: This is more accepting than rustc. We can tweak the definition slightly if we care to get closer. Example: 398 | 399 | ```rust 400 | trait Foo<'a, T: Ord> () {} 401 | 402 | fn test() 403 | where 404 | for<'z> A: Foo<'z, B> 405 | { 406 | } 407 | ``` 408 | 409 | In rustc, this errors because `B: Ord` is required. Under the definition I gave, `B: Ord` would be part of the default bounds. We can tweak this by not including *all* the WF conditions as default bounds, but only those that involve the `'z` variable. In that case, `B: Ord` would not be defaulted, and the WF checking would report an error on this example, just as rustc does. 410 | 411 | ### Who can add questions 412 | 413 | nikomatsakis: As the author of this doc, am I allowed to add questions? 414 | 415 | Answer: Yes, damn it. WE MAKE THE RULES. 416 | 417 | ### Should we have a `(in-scope)` predicate in mir-formality? 418 | 419 | nikomatsakis: So long as we have a more limited notion like rustc does of what we expan, I am not sure if adding default `(well-formed)` predicates is the right thing or not. I was coming up with some torturous examples where it might not behave as expected. Let me see if I can do craft one. 420 | 421 | The idea is that you are allowed to assume that a given type is fully well-formed, even though you can't prove that yourself. (I guess the WF checking ensures that you have enough where-clauses to prove it yourself, so that's kind of its role.) 422 | 423 | ```rust 424 | 425 | ``` 426 | 427 | ### in-scope and #25860 428 | 429 | > don't we have the issue that the implied bounds are on types which are fully inferred, so any fix during rust -> hir lowering won't be enough? (though this will get fixed by implication types later on, so it doesn#t matter ^^) 430 | 431 | You mean for closures, for example? 432 | 433 | I think this is ok because: the thing that gets added into the environment is 434 | 435 | ``` 436 | (well-formed (type ?T)) 437 | ``` 438 | 439 | where `?T` is the yet-to-be-inferred argument type. The way that elaboration works in mir-formality (bottom-up, not top-down), we won't be able to do much with that *until* we learn things about what `?T` winds up being inferred to be. At that point we would be able to. 440 | 441 | [Zulip discussion.](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-07-08/near/288941603) 442 | 443 | ### what's a biformula? 444 | 445 | Answer: see the footnote [^biformula]. 446 | 447 | > :heart: 448 | 449 | ### https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6e27f3dbe6bb4127f615df03fe60755f shouldn't compile at all, even with `for<'short>` meaning the right thing 450 | 451 | > we have `impl<'d> IntoData<'d> for &'d [u32]` and trait matching is invariant, isn't it? so `&'d [u32]: IntoData<'c>` doesn't hold, even if `'c: 'd` holds? we would need `impl<'c, 'd: 'c> IntoData<'c> for &'d [u32]` at which point we don't have latebound lifetimes anymore 452 | 453 | nikomatsakis: Hmm, that depends on what the type `T`.. maybe. I was trying to come up with a good example and I wans't very happy with that one. That said, why are the lifetimes not late-bound? Which lifetimes do you even mean? 454 | 455 | lcnr: because we need an explicit `'d: 'c` bound 456 | 457 | nikomatskais: There are no late-bound lifetimes on impls. I think if you change the impl, the example works as is. 458 | 459 | let's mvoe this to zulip lol 460 | -------------------------------------------------------------------------------- /minutes/2022-07-15-backlog-bonanza.md: -------------------------------------------------------------------------------- 1 | # Backlog bonanza 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-07-15/near/289610912 4 | 5 | Live hackmd link: https://hackmd.io/x3xTr5T7QKeS4tppEV0N-g 6 | -------------------------------------------------------------------------------- /minutes/2022-07-29-nominated-triage.md: -------------------------------------------------------------------------------- 1 | # Nominated triage 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-07-29/near/291315895 4 | 5 | -------------------------------------------------------------------------------- /minutes/2022-09-02-planning-meeting.md: -------------------------------------------------------------------------------- 1 | # 2022-09-02 planning meeting 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/meeting.202022-09-02.20planning/near/296814921 4 | 5 | ## Proposed meetings 6 | 7 | ### The meeting proposals 8 | 9 | * [discuss projection equality](https://github.com/rust-lang/types-team/issues/51) 10 | * [discuss the trait_alias feature](https://github.com/rust-lang/types-team/issues/49) 11 | * [Variance and Rust](https://github.com/rust-lang/types-team/issues/45) 12 | * [Polonius status update](https://github.com/rust-lang/types-team/issues/43) 13 | * [Finalize recommendations for TAITs](https://github.com/rust-lang/types-team/issues/40) 14 | * [Types team roadmap](https://github.com/rust-lang/types-team/issues/53) 15 | * [Chalk integration plan](https://github.com/rust-lang/types-team/issues/54) 16 | * [RPIT refactor review](https://github.com/rust-lang/types-team/issues/55) 17 | 18 | Proposed meetings: 19 | * Sep 9 -- projection equality (types-team#51)-- @**Boxy [she/her]** 20 | * Sep 16 -- finalize recommendations for TAITs (types-team#40) -- @**oli** 21 | * Sep 23 -- RPIT refactor review (types-team#55) -- @**Santiago Pastorino** 22 | * Sep 30 -- chalk integration plan (types-team#54) -- @**nikomatsakis** / @**Jack Huey** 23 | 24 | ## Status updates 25 | 26 | ### RPIT refactor 27 | 28 | We've fixed yesterday the last issue and we will probably be able to open a PR today with 2 diagnostics regressions, which I think we can open issues about and land this as is. 29 | 30 | :tada: --nikomatsakis --oli 31 | 32 | ### TAITs 33 | 34 | * https://github.com/rust-lang/rust/pull/95474 (don't imply `impl Trait<'a>: 'a`) 35 | * real world breakage on crater found (3 crates) 36 | * proactively provided PRs to the broken projects 37 | * will fix one significant diagnostic regression before merging 38 | * re-FCP with T-types? 39 | * https://github.com/rust-lang/rust/pull/99806 (allow `let (x, y) = some_opaque_value` to be a defining use) 40 | * perf hit, still analyzing the cause 41 | * https://github.com/rust-lang/rust/pull/98933 42 | * just needs a rebase and some cleanup work 43 | 44 | leftover issues before merging: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AF-type_alias_impl_trait+assignee%3Aoli-obk 45 | 46 | ### GATs 47 | 48 | Is in FCP as of Wednesday. 8 days left. Should make it into 1.65. Notes from lang meeting: https://github.com/rust-lang/lang-team/blob/master/design-meeting-minutes/2022-08-31-gat-stabilization.md 49 | 50 | GATs GATs GATs woooo --oli 51 | 52 | ### a-mir-formality 53 | 54 | * merged voidc's rustc front end, so that we can generate tests from rust source code 55 | * implemented the start of borrow checker -- in particular, liveness and initialization checks 56 | * spastorino landed some improvements to coherence checker and is investigating modeling negative impls 57 | 58 | ### NLL 59 | 60 | Done? Should WG get closed? 61 | 62 | ### Subtyping refactor 63 | 64 | Goal is to have the traits/subtyping code manage HRTB. As part of that, lcnr has been working on moving implied bounds into the parameter environment: 65 | 66 | > Moving implied bounds into the `ParamEnv` required a general refactoring to how implied bounds are implemented. The first step for this was https://github.com/rust-lang/rust/pull/100676 which changes rustc to eagerly compute implied bounds. This PR accidentally exacerbated an existing soundness bug https://github.com/rust-lang/rust/issues/100051, causing me to revert that accidental behavior change in https://github.com/rust-lang/rust/pull/100989. 67 | > 68 | > I am now close to finishing the move of implied bounds into the `ParamEnv`. This cleanup also makes it a lot easier to fix https://github.com/rust-lang/rust/issues/100051 and will allow us to consider more types for implied-bounds. 69 | 70 | ### Trait object upcasting 71 | 72 | * we had some discussion in [dyn-upcasting stabilization](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/dyn-upcasting.20stabilization). Key conclusions: 73 | * No-op trait upcasts don't count, we are only interested in upcasts that change the "principal trait(s)" (i.e., affect the methods that can be invoked, and hence alter the vtable). This was formalized in https://github.com/rust-lang/rust/pull/100208. 74 | * We prefer the "operations are UB" variant as [described in this document](https://hackmd.io/z9GaT_vdRtazrmcF6pStvQ) as it sems maximally consistent. 75 | * One minor open question is whether vtables ought to be defined as aligned pointers to create a niche for "raw wide pointers", e.g., `*const dyn Foo`. There is a niche today (but not for `*const T` where `T: Sized`). 76 | * Observation: backwards compatible to remove the niche. 77 | 78 | ### Negative impls 79 | 80 | * spastorino landed https://github.com/rust-lang/rust/pull/100888, closing the last known issue in the implementation 81 | * rfc draft has not made any progress 82 | 83 | ### Polonius 84 | 85 | * discussed roadmap with Amanda Stjerna and Giacomo Pasini [on zulip](https://rust-lang.zulipchat.com/#narrow/stream/186049-t-compiler.2Fwg-polonius/topic/2022-08) 86 | * Giacomo is going to investigate a proposed change to MIR with the goal of eliminating duplicate logic between borrow checker and drop elaboration, and giving a single unified version of MIR for all static analyses. nikomatsakis needs to write up that proposal as an MCP and discuss with oli and MIR optimization team. 87 | 88 | ### chalk-ty 89 | 90 | No progress. Well, small PR: https://github.com/rust-lang/rust/pull/100095 91 | 92 | -------------------------------------------------------------------------------- /minutes/2022-09-09-projection-equality.md: -------------------------------------------------------------------------------- 1 | # deep dive 9/9/22 2 | 3 | [zulip meeting](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-09-09.20projection.20equality) 4 | 5 | Note: this doc often refers to a `ProjectionEq` obligation, this is actually called `ProjectionPredicate` in rustc apparently which seems like kind of a silly name to me. Apologies for constantly messing up the name in this doc and likely anywhere I talk about this lol 6 | 7 | # projection equality status quo 8 | 9 | currently relating projections happens "eagerly", for example `<_ as Trait>::Assoc eq u32` fails because we can't wait around to see if the projection normalizes to `u32`. 10 | 11 | ## Other type is not a projection 12 | 13 | If we relate `<_ as Trait>::Assoc eq SomeOtherType<...>` it will currently fail which is incorrect as it may later end up with an inferred self type which allows for normalization, i.e. `::Assoc`. 14 | 15 | This currently is mitigated by sometimes normalizing `<_1 as Trait>::Assoc` to some new inference var `_2` and emitting a `ProjectionEq` obligation. However this falls short for higher ranked stuff which can be gotten from where clauses i.e. `where for<'a> >::Assoc: Other`, causing issues [#96230](https://github.com/rust-lang/rust/issues/96230) and [#89196](https://github.com/rust-lang/rust/issues/89196). 16 | 17 | ## Other projection is a different `DefId` 18 | 19 | If we relate: 20 | `<_1 as Trait>::Assoc eq <_2 as Trait>::Assoc2` 21 | currently it would fail because the projections are for different defids. This is overly restrictive as `_2` might end up getting resolved to some concrete type `T` allowing the projection to be normalized to: 22 | `::Assoc` 23 | which would then be able to succeed in being equated with: 24 | `<_1 as Trait>::Assoc` 25 | 26 | ## Relating substs 27 | 28 | If we relate `>::Assoc eq >::Assoc` currently it would fail because `u32 eq u64` does not hold. This is overly restrictive is the impl `u32: Trait<_1>` and `u64: Trait<_1>` may have the same value for the `type Assoc`. 29 | 30 | Similarly if we relate `<_1 as Trait>::Assoc eq <_2 as Trait>::Assoc` we would constrain `_1 eq _2` which may not necessarily be required and later cause type inference to error because `_2` turned out to be a `u32` and `_1` turned out to be a u64. 31 | 32 | # deferred projection equality 33 | 34 | PR [#96912](https://github.com/rust-lang/rust/pull/96912) changes the logic of relating projections to (if the projection has infer vars) succeed and emit a `ProjectionEq` obligation. This seems to fix all of the above issues (surprisingly as I was only aiming to fix the first issue). 35 | 36 | As of writing this the PR updates `ProjectionEq` obligation handling to only relate the substs and defid of a `ProjectionTy` if it is "as normalized as it will ever get". I am not sure what precise terminology for this is but the idea is that `::Assoc` is never going to be able to normalized more, but a `<_ as Trait>::Assoc` might. 37 | 38 | Fixing "relating substs" is not entirely backwards compatible as now relating `<_ as Trait>::Assoc eq ::Assoc` will leave the inference var unconstrained, it would be simple to "unfix" this in the PR. 39 | 40 | Note: the exact code changes in [#96912](https://github.com/rust-lang/rust/pull/96912) are a bit :grimacing: right now. specifically `project.rs` and winnowing, they certainly will be changed before seriously attempting to land the PR. (More about the winnowing changes below.) 41 | 42 | # #96912 issues 43 | 44 | ## typenum regression 45 | 46 | below is a minimal repro of the code that fails in typenum with the lazy projection equality PR, annotated with the candidates/obligations that are being evaluated during winnowing: 47 | 48 | ```rust 49 | #![recursion_limit = "4"] 50 | #![allow(unused_must_use)] 51 | 52 | use std::ops::Shl; 53 | 54 | pub struct Foo(U); 55 | 56 | pub trait NotSub: Sized { 57 | type Output; 58 | fn make_output(&self) -> Self::Output; 59 | } 60 | 61 | impl Shl> for Foo 62 | where 63 | Foo: NotSub, 64 | Foo>: Shl< as NotSub>::Output>, 65 | { 66 | type Output = (); 67 | fn shl(self, rhs: Foo) { 68 | let lhs: Foo> = Foo(self); 69 | let rhs: as NotSub>::Output = as NotSub>::make_output(&rhs); 70 | // < 71 | // Foo> 72 | // as 73 | // Shl< 74 | // as NotSub>::Output 75 | // > 76 | // >::shl(lhs, rhs) 77 | <_ as Shl<_>>::shl(lhs, rhs); 78 | // obligation: Foo> as Shl<_#0t> 79 | // candidates: 80 | // - param `Foo> as Shl< as NotSub>::Output>` 81 | // - ??? 82 | // - ??? 83 | // - impl `for Foo as Shl>` 84 | // - requires _#0t == Foo<_#1t> 85 | // - substs: [Foo, _#1t] 86 | // - nested: 87 | // - Foo<_#1t>: NotSub 88 | // - requires _#1t == B 89 | // - Foo>>: Shl< as NotSub>::Output > 90 | // candidates: 91 | // - impl `for Foo as Shl>` 92 | // - substs: [Foo>, _#2t] 93 | // - nested: 94 | // - ProjectionEq( as NotSub>::Output == Foo<_#2t>) 95 | // - Foo<_#2t>: NotSub 96 | // - requires _#2t == B 97 | // - Foo>>>: Shl< Foo< _#2t > as NotSub >::Output > 98 | // - same as previous `Foo>>` obligation but with an extra `Foo` this recurses infinitely 99 | } 100 | } 101 | ``` 102 | 103 | The comments in the code shows all the candidates for each obligation being solved and the nested obligations from each candidate. When evaluating the `impl` candidate we end up evaluting infinitely recursing `Foo<..<....>..>: Shl< as NotSub>::Output >` obligations. 104 | 105 | In order to make the code compile we need rustc to understand that the `impl` candidate doesn't apply and the `param` candidate does. The impl candidate can `EvaluateToErr` if the obligations are evaluated in a specific order: 106 | - `Foo<_#1t>: NotSub` this unifies `_1 eq B` 107 | - `Foo>>: Shl< as NotSub>::Output >` 108 | - `ProjectionEq( as NotSub>::Output == Foo<_2>)` note that this is actually `Foo<_1> as NotSub` but we have unified `_1 eq B` which allows us to know that this `ProjectionEq` obligation does not hold. 109 | 110 | Currently we do not even evaluate the `ProjectionEq` obligation, we evalaute `Foo>>>: Shl< Foo<_2> as NotSub >::Output` first and then `Foo>>>>: Shl<...>` etc etc. This causes us to get a recursion limit error which ends compilation rather than an `EvaluatedToErr` which would let us reject the impl candidate and move on to successfully evaluating the `param` candidate. 111 | 112 | We could do a lot better at avoiding these recursion errors by removing `evaluate_predicate_recursively` and using `ObligationCtx` (honestly I don't know what type to use but lcnr mentioned using `ObligationCtx` so...) to evaluate candidates. This would ensure that evenf if `ProjectionEq` was evaluated and then `Foo<_1>: NotSub` was evaluated it would be alright since the `ProjectionEq` obligation could stall on `_1`. Using an `ObligationCtx` also removes the possibility of us recursing forever without evaluating some obligations (This is more of an assumption, I don't actually know enough to know if this is completely true...). 113 | 114 | An alternative way to make this specific code compile would be to take advantage of the fact that impl candidates get discarded in favor of param candidates. We could potentailly evaluate all param candidates first and if any are `EvaluatedToOk`, discard all the impl candidates without evaluating them. There is a perf run for this solution at [#97380](https://github.com/rust-lang/rust/pull/97380). 115 | 116 | The PR currently implements the latter solution (evaluate param candidates first). It would not be backwards compatible to remove this and replace it with only fulfill like evaluation as `ObligationCtx` does not prevent us from ever getting a recursion limit error. Using `ObligationCtx` seems like a nicer solution and something that would be good to do anyway so that we don't have to maintain two separate ways of evaluating obligations. 117 | 118 | ## projection eq variance 119 | 120 | if we have a `<_ as Trait>::Assoc sub Foo<'a>'` and later `_` gets inferred to `Foo<'b>` which allows us to normalize the projection to `Foo<'b>` then we would end up doing `Foo<'b> eq Foo<'a>` not `Foo<'b> sub Foo<'a>`. 121 | 122 | # Questions 123 | 124 | ## How do I ask a question 125 | 126 | Like this. 127 | 128 | ## @lcnr: nested fulfillment during evaluation 129 | 130 | `evaluate_predicate_recursively` sucks, using a new fulfillment context there instead should work but allows some code to compile which may break again when going "full chalk". How does it work in chalk rn? 131 | 132 | nikomatsakis (spying in, not 100% here) -- I think that in chalk-style solver we would evaluate both paths but discard the impl path (eventually) as ambiguous -- but probably not until types got too large or something, I have to look more closely at that. 133 | 134 | ## implications merging 97380 135 | 136 | > what are the implications of just merging this on its own? It looks like a perf improvement even with the further-improvable implementation. 137 | - oli 138 | 139 | codes kinda janky and would not be entirely safe to remove later -------------------------------------------------------------------------------- /minutes/2022-09-23-RPITIT-support.md: -------------------------------------------------------------------------------- 1 | # 2022-09-23 deep dive 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-09-23.20RPITIT.20Support.2C.20Refactoring/near/300356358 4 | 5 | ## RPIT refactor 6 | 7 | given this... 8 | 9 | ```rust 10 | fn bar<'a>(&'a self) -> impl Debug + 'a 11 | ``` 12 | 13 | we desugar this to 14 | 15 | ```rust 16 | fn foo<'a>(&'a self) -> Foo<'static, 'a> { 17 | type Foo<..., 'a1>: Debug + 'a1; 18 | ``` 19 | 20 | because it inherits the parameters, we have to add `'static` values 21 | 22 | Q: I guess one of the questions could have been ... why this is not just `Foo<'a1>` and you forget about what is not being captured? 23 | 24 | A: the short version: that's what we were trying to do :) 25 | 26 | Example: 27 | 28 | ```rust 29 | fn foo<'a, T>(a: T) -> impl Debug 30 | where 31 | T: SomeTrait<'a> + Debug 32 | { 33 | a 34 | } 35 | ``` 36 | 37 | `'a` not captured, but appears in where clauses; `T` captured -------------------------------------------------------------------------------- /minutes/2022-09-30-chalk-integration.md: -------------------------------------------------------------------------------- 1 | # Chalk integration proposal (2022-09-30) 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-09-30.20chalk.20integration/near/301641085 4 | 5 | ## Meta comment and plan 6 | 7 | We've had trouble "getting going" on chalk integration and there are various ongoing efforts. Niko's meta proposal for how to proceed is as follows: 8 | 9 | * We create a living design repository that will describe the design we are working towards 10 | * either as part of a-mir-formality, as a fork of rustc-dev-guide, or as its own thing 11 | * we review updates to this design repository on a regular basis 12 | * this hackmd is meant as the start of that material 13 | * We prototype the final design in a-mir-formality 14 | * e.g. this is a good forum to explore some of the questions around lifetime inference 15 | * this hackmd links 16 | * We refactor rustc to bring it closer to the overall design, oncovering constraints as we go 17 | * this is also ongoing, and is the third part of this document (very sketchy) 18 | 19 | ## "The chalk vision" 20 | 21 | Chalk is a kind of shorthand for a style of solver that can be both efficient, correct, and shared across multiple codebases. This will likely build on some parts of today's chalk repo, but also integrate lessons from a-mir-formality and other work that has happened in the meantime. 22 | 23 | This section aims to explain the proposed high-level architecture. The a-mir-formality repository models this architecture quite closely, and so we have links in the doc to that repository as well. 24 | 25 | ### Various "actors" 26 | 27 | 28 | 29 | ### Core interface to the database 30 | 31 | Logic solver and type relations code can execute various callbacks: 32 | 33 | * `fn generics_of(&self, def_id: DefId) -> Vec` 34 | * `fn predicates_of(&self, def_id: DefId) -> Vec` 35 | * `fn clauses_for_goal(&self, goal: &Goal) -> Vec` 36 | * convert from Rust syntax into logical clauses 37 | * e.g., `impl Foo for Vec where T: Debug` might get translated to `has_impl(Vec: Foo) :- is_implemented(T: Debug)` 38 | 39 | In a-mir-formality, these are the ["hook" methods implemented by the decl layer](https://github.com/nikomatsakis/a-mir-formality/blob/038b0e1ccfb2a3f591688d5855a42c129d577e85/racket-src/decl/env.rkt#L65-L85). 40 | 41 | ### Core interface to/from the type relation code 42 | 43 | ```rust 44 | fn relate( 45 | db: &Db, 46 | env: &mut Env, 47 | relation: Relation, 48 | ) -> Result, Error>; 49 | // Yields Ok(goals) with subgoals to prove, 50 | // or Err(_) if this is not provable at all. 51 | 52 | enum Relation { 53 | t1: ty::Generic, 54 | op: RelationOp, 55 | t2: ty::Generic, 56 | } 57 | 58 | enum RelationOp { 59 | SubtypeOf, 60 | Outlives, 61 | } 62 | ``` 63 | 64 | In a-mir-formality, this is the "ty" layer, and `relate` is [`ty:relate-parameters`](https://github.com/nikomatsakis/a-mir-formality/blob/038b0e1ccfb2a3f591688d5855a42c129d577e85/racket-src/decl/env.rkt#L74). 65 | 66 | ### Core interface to/from the solver 67 | 68 | ```rust 69 | fn perform_query(db: &Db, canonical_query: CanonicalGoal) -> Response 70 | 71 | enum Response { 72 | // Known to be true. The substitution 73 | // constraints the input variables. 74 | True(Substitution, VarsAndRelations), 75 | Maybe(Substitution), 76 | False, 77 | } 78 | 79 | struct VarsAndRelations { 80 | /// new inference variables 81 | inference_vars: Vec<(Universe, Name)>, 82 | 83 | // new relations: these are low-level 84 | // relations, primarily `'a: 'b` 85 | relations: Vec, 86 | } 87 | ``` 88 | 89 | Where a `CanonicalGoal` is 90 | 91 | * Bound variables (inference, universal placeholders) 92 | * Parameter environment 93 | * Goal expressed as a logical predicate: 94 | * `is_implemented` 95 | * `normalizes_to` etc 96 | 97 | and a `Response` includes 98 | 99 | * the core result (yes/no/maybe) 100 | * a substitution of things that are known to be true 101 | * even with a maybe result, we may learn something about the inference variables 102 | * relations that have to be checked later by the region code 103 | * you can think of this as a list of outlives obligations on region variables 104 | * e.g. `T: Foo<'a>` might be true "if `'a: 'static`" 105 | * in a-mir-formality, subtyping and other relations can be returned as well, but we have already checked for overall consistency; this has more to do with the simple-sub inference algorithm, which is really a separate consideration worthy of more discussion. 106 | 107 | This is the "logic" layer of a-mir-formality, and especially [the `logic:solve-query` function](https://github.com/nikomatsakis/a-mir-formality/blob/main/racket-src/logic/solve-query.rkt#L15-L17). 108 | 109 | #### The recursive solver 110 | 111 | Chalk includes multiple solvers that can fulfill the above interface. The choice of solver does affect what kinds of programs compile and so it is part of the specification, though we have room to improve it over time. For various reasons, nikomatsakis thinks that the recursive solver is the best choice at the moment. It effectively works like this: 112 | 113 | ```rust 114 | fn solve(canonical_goal: CanonicalGoal) -> Result<()> { 115 | // get the goal to prove, e.g., `is_implemented(Vec: Debug)` or 116 | // `projected_to( = find_subgoals(goal); 121 | while !subgoals.is_empty() { 122 | let subgoal = subgoals.pop(); 123 | let canonical_subgoal = inference_context.canonicalize(subgoal); 124 | match solve(canonical_subgoal) { 125 | True(solution) => inference_context.include(solution), 126 | False => return Err, 127 | Maybe(solution) => { 128 | inference_context.include(solution); 129 | subgoals.push(subgoal); 130 | } 131 | } 132 | } 133 | True(inference_context.make_solution()) 134 | } 135 | ``` 136 | 137 | 138 | ### Managing diagnostics 139 | 140 | This part is less well-developed. The basic idea is to offer a second interface to the solver: 141 | 142 | ```rust 143 | fn perform_query_tree(db: &Db, canonical_query: CanonicalGoal) -> ResponseTree 144 | ``` 145 | 146 | that solves the query but constructs and returns the resulting tree, showing what things it tried to prove and why they failed. This could be implemented separately or with one codebase that is generic over which mode it is. 147 | 148 | ### How this is expected to be integrated into rustc 149 | 150 | #### Unifying fulfill, evaluation, selection, and projection into one mechanism 151 | 152 | Currently we have four bits of code: 153 | 154 | * fulfillment context -- tracks what has to be proven 155 | * selection -- selects what impl to use 156 | * evaluation -- determines if a query might be true 157 | * projection -- normalizes associated variables 158 | 159 | In the proposed approach, all of these are unified into performing queries (with possible exception of the first). 160 | 161 | #### Caching, cycles, and incremental compilation 162 | 163 | The chalk "recursive solver" can be integrated quite cleanly with the rust query system, if we extend it to support "fixed point" queries. The idea is that each of the methods identified above can be considered a query. Using the recursive solver style from chalk, the solver creates new subqueries for each subgoal. Each subquery returns a solution that summarizes all possible solutions to the subgoal. 164 | 165 | Effectively the recursive solver works like this: 166 | 167 | ```rust 168 | fn solve(canonical_goal: CanonicalGoal) -> Result<()> { 169 | let (inference_context, goal) = InferenceContext::new(canonical_goal); 170 | let mut subgoals: Vec<_> = find_subgoals(goal); 171 | while !subgoals.is_empty() { 172 | let subgoal = subgoals.pop(); 173 | let canonical_subgoal = inference_context.canonicalize(subgoal); 174 | match solve(canonical_subgoal) { 175 | True(solution) => inference_context.include(solution), 176 | False => return Err, 177 | Maybe(solution) => { 178 | inference_context.include(solution); 179 | subgoals.push(subgoal); 180 | } 181 | } 182 | } 183 | True(inference_context.make_solution()) 184 | } 185 | ``` 186 | 187 | 188 | #### HIR type checking 189 | 190 | HIR type checker would make use of a pared down, simplified fulfillment context that just tracks the top-level obligations that are not yet solved: 191 | 192 | ```rust 193 | struct FulfillmentCx { 194 | goals: Vec 195 | } 196 | ``` 197 | 198 | the equivalent of `select_where_possible` etc would be to: 199 | 200 | * iterate the list and perform queries 201 | * queries returns suggested unifications, incorporate those 202 | * if this yields back true, remove it from the list 203 | 204 | Note that the same top-level goal may correspond to different queries each time, as it may reference inference variables that have since been constrained. 205 | 206 | When an error occurs -- either an obligation that cannot be proven or goals that remain ambiguous once all type checking is complete -- we would rerun those obligations in diagnostic mode, yielding a detailed trace, and then figure out how to report that to user. 207 | 208 | The HIR type checker, when run with `-Zchalk`, already does something kind of like this (but without the smart handling for diagnostics). 209 | 210 | #### Lazy normalization 211 | 212 | Lazy normalization means that associated types are not normalized until they are required to be. This would help avoid quite a number of cycles in 213 | 214 | #### MIR type checking, borrow checker 215 | 216 | The MIR type checker already uses a query system, but it doesn't require the full generality of the above because (at least for now...) it doesn't expect type inference variables. 217 | 218 | One key difference in the chalk model that is not obvious from the interfaces sketched above is the way that it handles higher-ranked outlives obligations like `for<'a> (T: 'a)`. In rustc today, the obligations that result from a trait operation can include higher-ranked obligations like this, and they are ultimately resolved by the borrow checker. 219 | 220 | In MIR formality, higher-ranked obliations are handled by the type checker, and the borrow checker only gets simple constraints between variables in the "root universe". This is a much better fit for a system like polonius, which is ill-equipped to deal with higher-ranked reasoning. 221 | 222 | #### Codegen 223 | 224 | Codegen uses the trait solver in a few particular ways. The primary one is to figure out which version of a trait method is being called. In some cases, 225 | 226 | ## How to get there? 227 | 228 | Here are some ideas for initial projects. 229 | 230 | ### chalk-ir crate 231 | 232 | Part of the plan is to have chalk be extracted from rustc 233 | 234 | ### "Shallow subtyping" 235 | 236 | The current subtyping code produces higher-ranked obligations like `for<'a> '0: 'a`. The goal here is to process those at the trait solving layer (after all, all the bounds of `'a` are known up-front), thus freeing the borrow checker from the need to think about regions. This is a blocker for polonius integration as well. 237 | 238 | ### Diagnostics query (proposed by lcnr) 239 | 240 | Begin by modifying the type checker to integrate 241 | 242 | ### Richer existential types in rustc 243 | 244 | 245 | 246 | ### Implication predicates 247 | 248 | ### Coherence 249 | 250 | Implement the new solver and integrate it into coherence. The modeling of coherence in a-mir-formality is complete apart from specialization and negative impls. 251 | 252 | Coherence is interesting because it is only using an "evaluation" style testing. 253 | 254 | ## Some question marks for further exploration 255 | 256 | There are some things that need more exploration in a-mir-formality. 257 | 258 | ### Lifetime erasure 259 | 260 | We have to think about which lifetimes we erase from queries precisely and how we can guarantee lifetime erasure going forward. 261 | 262 | ### Existential predicates 263 | 264 | To properly model TAITs, we need 265 | 266 | # Questions 267 | 268 | ## Coordinating overal effort and tracking the overall design 269 | 270 | nikomatsakis: My sense is that there is a need to get consensus on the overall design we are working for. I am proposing the drafting of a design doc and continued prototyping work on a-mir-formality as a way to drive that design. I feel like trying to do all our discussion and experimentation by live editing rustc code is going to slow us down, and that we need to be simultaneously doing that *and* working "up ahead". I also feel like my own personal time is probably best spent "up ahead", which is why i've been focused on hacking on a-mir-formality. But I'd like to hear what others think on this point and how to get that communication going in both directions. Should we have a dedicated "chalkification" meeting time? Smaller efforts that coordinate? 271 | 272 | ## Missing pieces that show up in rustc etc 273 | 274 | nikomatsakis: I'm wondering what are some of the missing pieces that cause big interactions in rustc but are lacking in the models and design docs. Const generics comes to mind, are there others? 275 | 276 | lcnr: there's codegen/ctfe which uses erased lifetimes and should still result in the same evaluation result as mentioned above. idk, do we have a doc which states all of the requirements we have on our trait system somewhere? 277 | 278 | ## Design doc points that came up 279 | 280 | * Where does the code that converts from HIR definitions into logical predicates live ("decl" layer of a-mir-formality). 281 | * What is the interface that it uses to talk to rustc/rust-analyzer? 282 | 283 | ## What do we want to do with Chalk? 284 | 285 | * There is some amount of code that might be reusable in a new trait solver implementation (in Rust) - type folding, interner interface, maybe most of chalk-ir. 286 | * Rust-analyzer currently uses it heavily - we should consider the medium-term, where we heavily work on a-mir-formality, but rust-analyzer wants something more "stable". Are we open to making Chalk more "experimental" for things like const-eval or lifetime constraint generation under the *current* type model? 287 | 288 | ## When is a-mir-formality "ready" to move to rust-lang 289 | 290 | We should announce that along with types team and types team efforts in a blog post :) 291 | -------------------------------------------------------------------------------- /minutes/2022-10-07-planning-meeting.md: -------------------------------------------------------------------------------- 1 | # 2022-10-07 planning meeting 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-10-07.20Planning.20meeting/near/302846151 4 | Previous planning meeting: https://hackmd.io/BN-RofYeTZKKc_5Iu3sPFg 5 | 6 | ## Proposed meetings 7 | 8 | ## Status updates 9 | 10 | ### RPIT refactor 11 | 12 | * PR got closed :( 13 | * Changing to RPIT/RPITIT cleanup 14 | 15 | ### TAITs 16 | 17 | * landed https://github.com/rust-lang/rust/pull/95474 18 | * opened https://github.com/rust-lang/rust/pull/102417 19 | * opened https://github.com/rust-lang/rust/pull/102700 20 | * Status tracked here: https://github.com/orgs/rust-lang/projects/22/views/1 21 | 22 | ### GATs 23 | 24 | * Stable now ~~?~~ ! 25 | * TODO: blog post for 1.65 release 26 | * Issues tracked here: https://github.com/orgs/rust-lang/projects/17 27 | * Some, at least 28 | * Adding `PredicateTy` to rustc: https://github.com/jackh726/rust/tree/a-whole-new-world 29 | 30 | ### a-mir-formality 31 | 32 | voidc landed some improvements to the type checker. 33 | 34 | Currently working on adding a version of the borrow checker (modeling NLL, to start). This has led me to realize that we *may* be able to make a lightweight change to rustc that would help us with "problem case #3": 35 | 36 | ```rust 37 | if let Some(v) = self.map.get() { 38 | return v; 39 | } 40 | self.map.insert(); 41 | ``` 42 | 43 | Currently investigating if this is true. :) 44 | 45 | Going to be giving a talk on mir-formality next week at HILT '22. Will share slides when they're worth looking at. 46 | 47 | ### Subtyping refactor 48 | 49 | mostly distracted by opaque types in ctfe. annoying :angry: 50 | 51 | ### Trait object upcasting 52 | 53 | Blocked on the need to author an RFC. Should do that. 54 | 55 | ### Negative impls 56 | 57 | Did preliminary integration into a-mir-formality and uncovered a problem, filed at [#102678], concerning cyclic reasoning. The basic idea is that, before we rely on `(T: !Foo) => (T: Foo)`, we need to establish that. The planned fix is to refactor coherence and leverage query system to avoid cycles. 58 | 59 | [#102678]: https://github.com/rust-lang/rust/issues/102678 60 | 61 | ### Polonius 62 | 63 | We are planning a series of hackathons to get oriented, starting Oct 26. We will be adding these to the compiler team calendar. 64 | 65 | ### chalk-ty 66 | 67 | * No `TypeFoldable` for `EarlyBinder`: https://github.com/rust-lang/rust/pull/101901 68 | -------------------------------------------------------------------------------- /minutes/2022-10-21-issue-triage.md: -------------------------------------------------------------------------------- 1 | # Issue triage 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-10-21.20issue.20triage/near/305348200 -------------------------------------------------------------------------------- /minutes/2022-10-28-roadmap.md: -------------------------------------------------------------------------------- 1 | # Roadmap planning 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-10-28.20roadmap/near/306650004 4 | 5 | # Big pieces 6 | 7 | * formality (i.e., model) 8 | * shared library for trait solver between rust/r-a, with intermediate steps of 9 | * improved diagnostics for trait system 10 | * refactored rustc implementation 11 | * Chalk? 12 | * rustc-type-ir/chalk-ty 13 | * feature work (intersects both the above), such as... 14 | * improvements on generic associated types 15 | * improvements on impl Trait (e.g., TAITs, RPITIT) 16 | * soundness fixes, especially for higher-ranked stuff 17 | 18 | ### Formality 19 | 20 | Key questions: 21 | - When to move to rust-lang org? 22 | 23 | Goals for next year: 24 | 25 | * testing against rustc (and chalk) 26 | * modeling borrow check, trait solving, type checking from MIR backwards, with some elements of lowering into MIR as needed 27 | * integrated into our language design processes (new features modeled) 28 | 29 | Specific questions to probe: 30 | 31 | * [erased lifetimes](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-10-28.20roadmap/near/306657313) 32 | * 33 | 34 | ### Shared library 35 | 36 | - Initiative? Not all of this? 37 | 38 | ### Feature work and related 39 | 40 | What features are relevant? 41 | 42 | - async? (how much) 43 | - https://github.com/rust-lang/rust/issues/60658 44 | - RPITIT 45 | - lead: Niko/tmandry 46 | - other: Michael 47 | - AFIT 48 | - lead: Niko/tmandry 49 | - other: Michael 50 | - TAITs 51 | - lead: oli 52 | - existential lifetime parameters for cleaner TAIT impl? 53 | - lead: nobody 54 | - - GATs 55 | - lead: Jack 56 | - Subgoals: 57 | - Implied 'static 58 | - Object safety 59 | - `for<'a> <_ as Trait>::Assoc<'a>: OtherTrait` goals 60 | - polonius 61 | - lead: Niko 62 | - others: lqd 63 | - keyword generics 64 | - const traits 65 | - negative trait impls 66 | - lead: Niko 67 | - others: santiago 68 | - const eval 69 | - `impl Trait` interaction? 70 | - implication types 71 | - lead: Jack? 72 | 73 | ### GATs 74 | 75 | 76 | 77 | ## Timelines and meetings 78 | 79 | ## Questions 80 | 81 | ### Is layout under our purview? 82 | 83 | Seemingly no? Probably more of an opsem team thing. 84 | 85 | ### Active initiatives and planned work that goes beyond that 86 | 87 | Can we chart it out 88 | 89 | ```mermaid 90 | flowchart LR 91 | a-mir-formality 92 | class a-mir-formality active_development; 93 | 94 | rustc-trait-solver-rewrite 95 | class rustc-trait-solver-rewrite active_development; 96 | 97 | shared-trait-solver-library 98 | class shared-trait-solver-library blocked; 99 | 100 | rustc-trait-solver-rewrite --> shared-trait-solver-library 101 | 102 | polonius 103 | class polonius active_development; 104 | 105 | classDef active_development fill:#B10DC9,color:white 106 | classDef blocked fill:#0074D9,color:lightgrey 107 | classDef stalled fill:#0074D9,color:white 108 | ``` -------------------------------------------------------------------------------- /minutes/2022-11-04-planning-meeting.md: -------------------------------------------------------------------------------- 1 | # 2022-11-04 planning meeting 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-11-04.20planning/near/307951923 4 | Previous planning meeting: https://hackmd.io/VV4OlAgKQXKKxqI8dbWMvA 5 | 6 | ## Meeting agenda 7 | 8 | * Fill in status updates 9 | * Review and schedule proposed meetings 10 | * Topics for extended discussion 11 | * Proposed workflow: 12 | * create tracking issues for each item and give them a tag (e.g., `I-types-team-initiative`). 13 | * bot to scrape repos for issues with that agenda and include recent updates 14 | * ability to ping bot and have it ping people assigned to those issues 15 | 16 | ## Proposed meetings 17 | 18 | * Variance and Rust #45 19 | * discuss the trait_alias feature #49 20 | * Types team roadmap #53 21 | * Done? In progress? 22 | 23 | ## Status updates 24 | 25 | ### RPITIT refactoring 26 | 27 | It's almost done. 28 | 29 | * We are already lowering the RPIT as an associated type in both the trait and the corresponding impl. 30 | * I've gone over the involved queries adjusting them and making them do the right thing. 31 | * There are currently 15 failing test cases, from the ones I remember ... 32 | * trait with default bodies 33 | * async fns 34 | * I'm currently going over project, candidate assembly, confirm and friends in order to better understand how they work. 35 | 36 | ### AFIT/RPITIT stabilization 37 | 38 | They work surprisingly well, the only existing issues are due to `'static` in the impl-trait desugaring causing some outlives issues when comparing methods' compatibility with their traits. 39 | A few folks are already using AFIT experimentally: 40 | * Embedded HAL: https://github.com/rust-embedded/embedded-hal/pull/407 41 | * Yosh's async_iterator crate: https://docs.rs/async-iterator/2.0.0/async_iterator/trait.Iterator.html 42 | 43 | Existing blockers due to `'static` substitution in lifetimes causing strange lifetime equality bugs, e.g.: https://github.com/rust-lang/rust/issues/102681 44 | cjgillot's PR https://github.com/rust-lang/rust/pull/103491 attempts to fix this, otherwise associated types are quite limited in AFIT. 45 | * this PR could use a deep-dive, since cjgillot told me that they're uncertain if it's sound. 46 | 47 | Open issue for auto trait bounds issue: https://github.com/rust-lang/rust/issues/103854 48 | Though definitely requires some lang design work that doesn't necessarily block static AFITs landing, since all changes would be forward-compatible. 49 | * compiler-errors might put up a PR for `T: Trait` type bounds, since they're not that hard to hack into the compiler. 50 | 51 | ### TAITs 52 | 53 | TAIT is just one merge away from being ready for stabilization. I will write a doc now explaining what TAIT does and what it doesn't. 54 | 55 | ### GATs 56 | 57 | Stable! (Onwards and upwards to the next thing (working on implied static)) 58 | 59 | ### a-mir-formality 60 | 61 | Working on rust-rewrite in the riir branch. Things are progressing well. Hoping to open it up for others to contribute to soon. Current status is that end-to-end tests kind of work, but there are still a few basic pieces in the trait solver (e.g., outlives relationships) to finish modeling before it's really ready to be scaled out. Using Rust is nice. 62 | 63 | ### Subtyping refactor 64 | 65 | No progress on this directly. 66 | 67 | nikomatsakis: I believe we can meet the major goal of unblocking polonius in a simpler way. Essentially moving the higher-ranked code that we use *today* in NLL into a pre-pass on the constraints coming out from the trait solver. This item could perhaps be removed from the list. 68 | 69 | ### Implied bounds 70 | 71 | WIP PR ready except for inductive trait solver cycles due to the additional WF bounds. Avoiding them in a non hack-ish way will probably require us to change the solver to be coinductive for all traits. 72 | 73 | ### Non-fatal trait solver overflow 74 | 75 | Requires changes to the while API of the trait solver, so it's a good work to start the rustc trait solver rewrite initiative with :sparkles: the current API surface is pretty massive and they tend to need slightly different approaches. Making progress on this though and am not stuck on anything yet. 76 | 77 | ### Trait object upcasting 78 | 79 | [RFC #3324](https://github.com/rust-lang/rfcs/pull/3324) is in FCP, finishes in a day or two, and then we should be ready to stabilize. :tada: 80 | 81 | ### Negative impls 82 | 83 | Tracking issue: https://github.com/rust-lang/rust/issues/68318 84 | 85 | No major progress here, though nikomatsakis has been thinking about the issue of cycles (https://github.com/rust-lang/rust/issues/102678) and plans to model a fix in a-mir-formality. Good first goal for the riir branch, actually. Santiago and he should touch base on the idea, which could also be implemented in rustc. 86 | 87 | Other blockers: 88 | 89 | * https://github.com/rust-lang/rust/issues/79098 90 | * 91 | 92 | ### Polonius 93 | 94 | Had a hackathon meeting yesterday with a number of people. Went back over the rules and identified two main next steps: 95 | 96 | * Implementation: plan is to explore an implementation in rustc that builds on NLL infrastructure. lqd is leading this, with theo plus some others interested. lqd + nikomatsakis plan to meet once more to do high-level design. 97 | * Rule design: we've got several variants of the rules by now and need to get to one set. nikomatsakis was drafted rules in a-mir-formality but paused that work for the riir branch. Domenic Quirl is going to be doing some detective work on the various alternatives. Another meeting needs to be scheduled here too to go over the results. 98 | 99 | ### chalk-ty 100 | -------------------------------------------------------------------------------- /minutes/2022-11-11-RPIT-self-PR.md: -------------------------------------------------------------------------------- 1 | # Behaviour of inherited lifetime parameters for opaque types 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022.E2.80.9011-11.20PR.20review/near/309197876 4 | PR link: https://github.com/rust-lang/rust/pull/103491 5 | 6 | The current implementation of async and RPIT replace all lifetimes from the parent item's generics by `'static`. 7 | The point of this scheme is to ensure that only the lifetimes that explicitly appear in the bounds for the opaque: 8 | - are allowed to occur inside the opaque (while borrow-checking the defining function); 9 | - are considered to occur inside the opaque (while borrow-checking the user functions). 10 | 11 | However, using `'static` creates unwanted behaviour when `Self` and associated type projections appear in bounds. 12 | In pseudo syntax, the desugaring looks like this: 13 | ```rust 14 | trait Trait<'x> { 15 | type Assoc; 16 | } 17 | 18 | impl<'a> Foo<'a> { 19 | fn foo<'b, 'c, 'd, T: Trait<'b>>() -> impl Into + From + 'c { ... } 20 | } 21 | 22 | opaque type Foo::<'_a>::foo::<'_b, '_c, '_d, T>::opaque<'c>: 23 | Into> // `Self` is implicitly desugared to mention `'_a` 24 | + From<>::Assoc> // `T::Assoc` is implicitly desugared to mention `'_b` 25 | + 'c; // `'_d` stays unused, as expected 26 | 27 | impl<'a> Foo<'a> { 28 | fn foo<'b, 'c, T: Trait<'b>>() -> Foo::<'static>::foo::<'static, 'static, 'static, T>::opaque::<'b> { ... } 29 | } 30 | ``` 31 | 32 | This implies that the bounds are: 33 | ```rust 34 | opaque type Foo::<'static>::foo::<'static, 'static, 'static, T>::opaque<'c>: 35 | Into> // `Self` gets the wrong lifetime 36 | + From<>::Assoc> // The trait bound is wrong too 37 | + 'c; 38 | ``` 39 | 40 | In order to avoid accepting wrong code and silently transmuting a `Foo<'a>` to a `Foo<'static>`, 41 | `Self` and projections were banned from impl-trait. 42 | 43 | # Proposed resolution 44 | 45 | The point of the original device was to ensure that `'_a`, `'_b`, `'_c` and `'_d` did not appear in borrowck, 46 | but just the duplicated `'c` version. A more "proper" desugaring would look like: 47 | 48 | ```rust 49 | impl<'a> Foo<'a> { 50 | fn foo<'b, 'c, 'd, T: Trait<'b>>() -> Foo::<'a>::foo::<'b, 'c, 'd, T>::opaque::<'c> { ... } 51 | } 52 | ``` 53 | 54 | The issue becomes: how to tell borrow-checking that the opaque only actually depends on `'_a`, `'_b` and `'c` but not `'_d`. 55 | 56 | We want to: 57 | - only relate substs that correspond to captured lifetimes during TypeRelation; 58 | - only list captured lifetimes in "occurs check". 59 | 60 | We propose to encode usage/non-usage using `variances_of` query: 61 | `Bivariant` vs `Invariant` for unused vs captured lifetimes. 62 | 63 | Impl-trait that do not reference `Self` or projections will have their variances as: 64 | - `o` (invariant) for each type or const generic param; 65 | - `*` (bivariant) for each lifetime param from parent --> will not participate in borrowck; 66 | - `o` (invariant) for each own lifetime param. 67 | 68 | Impl-trait that do reference `Self` and/or projections will have some parent lifetimes marked as `o` as they appear in the bounds, and participate in type relation and borrowck. 69 | 70 | In the example above, `'_a` and `'_b` appear in bounds, so: `variances_of(opaque) = ['_a: o, '_b: o, _c: *, '_d: *, T: o, 'c: o]`. 71 | 72 | # Unresolved questions 73 | 74 | Is this even sound? 75 | 76 | Is there a lighter way to do that, instead of changing `TypeRelation`? 77 | 78 | Should we insert a `'_c == 'c` bound somewhere? --> yes 79 | 80 | Variance computation for opaques is not integrated into the crate-global variance computation: 81 | 1. it makes conservative assumptions about mutually recursive TAITs; 82 | 2. bivariance does not leak into ADTs. 83 | 84 | # Comments 85 | 86 | oli: 87 | Why do we need the additional lifetimes on the opaque type? Can't we just mark the right ones as invariant/bivariant? 88 | 89 | cjgillot: to support late-bound lifetimes in functions `fn foo(&self) -> impl Debug + '_` 90 | 91 | Less of a question: I'd like to land this first for TAIT and add tests that ensure that TAIT works exactly like RPIT. Then we can migrate RPIT without any language concerns. 92 | 93 | ## AFIT interaction 94 | 95 | nikomatsakis: This problem is related to AFIT somehow, right? Can we say a bit more about the connection? 96 | 97 | compiler-errors: https://github.com/rust-lang/rust/issues/102681, basically `Self` type ends up being substituted with `'static` types, which causes the method signature comparison is `compare_predicate_entailment` to unnecessarily relate a bunch of non-`'static` lifetimes with `'static` 98 | 99 | ## wellformedness interactions 100 | 101 | nikomatsakis: I am not sure if this proposal is addressing the interesting problem. In the past when we talked about it, we had settled on the need for some kind of existential lifetime support. The reason was because of cases like this, which is currently accepted: 102 | 103 | ```rust 104 | trait Foo<'a>: Bar { } 105 | 106 | trait Bar { } 107 | 108 | fn foo<'a, T>(x: T) -> impl Debug 109 | where 110 | T: Foo<'a>, 111 | { 112 | MyStruct { x } 113 | } 114 | 115 | struct MyStruct { x: T } 116 | 117 | impl Debug for MyStruct 118 | where 119 | T: Bar, 120 | { 121 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 122 | panic!() 123 | } 124 | } 125 | ``` 126 | 127 | Note that `'a` is not captured, but for the `MyStruct` to be WF, we must know that `T: Bar`, and we know that because we know that `T: Foo<'a>` for *some* `'a`. This works today but because of some rather hacky things. 128 | 129 | There are also other examples, I'm trying to find the hackmd where we went through the various cases -- there doesn't have to be a supertrait relationship. 130 | 131 | ## variance 132 | 133 | nikomatsakis: I don't love using variance to encode this, though it also doesn't seem entirely wrong. 134 | 135 | ## oli alternative 136 | 137 | nikomatsakis: Didn't oli have some other approach to this problem? I don't know what it was, though. 138 | -------------------------------------------------------------------------------- /minutes/2022-11-16-closure-return-type-outlives.md: -------------------------------------------------------------------------------- 1 | # Closure return type outlives 2 | 3 | Zulip discussion link: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-11-16.20close.20return.20type.20outlives.20types-team.2357/near/310426588 4 | PR link: https://github.com/rust-lang/rust/pull/84385 5 | -------------------------------------------------------------------------------- /minutes/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the minutes from our various meetings. These 2 | meetings are held on Zulip and you can find the time and other 3 | information in [the compiler-team calendar][c]. 4 | 5 | [c]: https://github.com/rust-lang/compiler-team#meeting-calendar 6 | 7 | ## Design meetings 8 | 9 | * [2019.10.16](design-2019-10-16.md): How to handle normalization in 10 | chalk and ideas about what a generic library to represent types 11 | might look like. 12 | -------------------------------------------------------------------------------- /minutes/design-2019-10-16.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.10.16 2 | 3 | ## topic 4 | 5 | How to handle normalization in chalk and ideas about what a generic 6 | library to represent types might look like. 7 | 8 | ## summary 9 | 10 | Key points in the discussion: 11 | 12 | * [how does normalization work in chalk today](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-16/near/178314511) 13 | * [would like to remove unnormalized projections and move that logic to clause lowering](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-16/near/178315108) 14 | * [but this makes lowering more complex](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-16/near/178315630) 15 | * [can use generics to keep things straight](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-16/near/178315802) 16 | * [and in particular a typefamily trait](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-16/near/178316023) 17 | * [this typefamily trait can be the foundation for a generic type library](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-16/near/178316849) 18 | -------------------------------------------------------------------------------- /minutes/design-2019-10-21.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.10-21 2 | 3 | ## topic 4 | 5 | `dyn Trait` in Chalk. 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-21/near/178672663) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [how is `dyn Trait` defined in Chalk](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-21/near/178681888) 13 | * [where clauses](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/meeting.202019-10-21/near/178684670) 14 | -------------------------------------------------------------------------------- /minutes/design-2019-10-28.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.10-28 2 | 3 | ## topic 4 | 5 | Rustc and trait upcasting. 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E10.2E28/near/179258087) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [codegen changes](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E10.2E28/near/179259139) 13 | * [changes to enable this](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E10.2E28/near/179259720) 14 | * [diamond inheritance](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E10.2E28/near/179260637) 15 | -------------------------------------------------------------------------------- /minutes/design-2019-11-04.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.11.04 2 | 3 | ## topic 4 | 5 | Regions and universes. 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E04/near/179863691) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [what is normalization](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E04/near/179864314) 13 | * [normalization under binders](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E04/near/179865279) 14 | * [leak check](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E04/near/179867205) 15 | * [Niko's leak check PR](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E04/near/179868825) 16 | * [PR](https://github.com/rust-lang/rust/pull/65232) 17 | -------------------------------------------------------------------------------- /minutes/design-2019-11-11.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.11.11 2 | 3 | ## topic 4 | 5 | Coinduction in chalk (and the current [unsoundness](https://github.com/rust-lang/chalk/issues/248)) 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E11/near/180448354) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [what is coinduction and what's the problem](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E11/near/180450250) 13 | * [brief explanation of how chalk works irt. coinduction](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E11/near/180451093) 14 | * [general idea for how to fix the issue](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E11/near/180451374) 15 | * [can we see negative coinductive cycles?](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E11/near/180452900) 16 | * [a walk-through of how the new implementation would work for a test case](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E11.2E11/near/180454384) 17 | -------------------------------------------------------------------------------- /minutes/design-2019-11-18.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.11.18 2 | 3 | ## topic 4 | 5 | How to improve rustc-chalk integration. 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/rustc-chalk.20integration.2C.20take.202/near/181043120) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [we should have rustc use `chalk-solve` instead of `chalk-engine`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/rustc-chalk.20integration.2C.20take.202/near/181043229) 13 | * [refactoring in rustc to make things easier](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/rustc-chalk.20integration.2C.20take.202/near/181046650) 14 | * [`QuantifiedTy`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/rustc-chalk.20integration.2C.20take.202/near/181047974) 15 | -------------------------------------------------------------------------------- /minutes/design-2019-12-02.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.12.02 2 | 3 | ## topic 4 | 5 | Small updates from the last week 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E02/near/182377699) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [refining an answer in Chalk can cause a panic (currently)](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E02/near/182380076) 13 | - This was spotted in [a pull request](https://github.com/rust-lang/chalk/pull/281#discussion_r344847832), but no follow-up has been done yet. Issue [filed](https://github.com/rust-lang/chalk/issues/302). 14 | * [some thoughts of associated type projections](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E02/near/182380309) 15 | * [chalk needs more/better tests](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E02/near/182380251) 16 | * [debug output with `CHALK_DEBUG` and possibly switching to `tracing`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E02/near/182385372) 17 | -------------------------------------------------------------------------------- /minutes/design-2019-12-09.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.12.09 2 | 3 | ## topic 4 | 5 | rust-analyzer infinite loop, associated type normalization 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E09/near/182987877) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [separating *unification* from *type relation*](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E09/near/182988478) 13 | - [where does this come up](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E09/near/182988918) 14 | * [how does the infinite loop happen](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E09/near/182990322) 15 | * [existing PR: don't truncate environment](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E09/near/182990731) 16 | * [associated type normalization](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E09/near/182991633) 17 | 18 | -------------------------------------------------------------------------------- /minutes/design-2019-12-16.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.12.16 2 | 3 | ## topic 4 | 5 | Associated types and normalization 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183576530) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [chalk book and what it should cover](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183579289) 13 | * [why are there both `Normalize` and `ProjectionEq`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183580571) 14 | * [A potential solution to generating the "extra" fallback type](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183581540) 15 | * [What is wrong with the current design](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183582215) 16 | * [design question: should Chalk "guess" about the associated type if there are inference variables](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183582802) 17 | * [Niko has been trying to remove unnormalized types](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183583970) 18 | * [Directions to explore](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E16/near/183584430) 19 | 20 | -------------------------------------------------------------------------------- /minutes/design-2019-12-30.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2019.12.30 2 | 3 | ## topic 4 | 5 | Overall strategy and steps to take first 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E30/near/184493020) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [whether `GeneratorWitness` is too specific](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E30/near/184493361) 13 | * [renaming `chalk-ir` to `chalk-ty`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E30/near/184493914) 14 | * [where to start with integrating chalk into rustc](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E30/near/184494158) 15 | * [logging test cases, dumping a `.chalk` file, to debug perf issues](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E30/near/184494621) 16 | * [using the `wg-traits` repo as a coordination point for tracking plans](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202019.2E12.2E30/near/184495709) 17 | -------------------------------------------------------------------------------- /minutes/design-2020-01-06.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.01.06 2 | 3 | ## topic 4 | 5 | Plans are slowly taking shape 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184934566) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [general roadmap: integrate chalk into rustc step by step](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184935652) 13 | * [getting `chalk-ir` ready for rustc integration](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184936420) 14 | * [balancing rust-analyzer and optimization work](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184937063) 15 | * [incremental goal solving](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184937837) 16 | * [sync-up: book PR, writing out steps, other PRs](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184938309) 17 | * [adding tracing to the solver](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184939093) 18 | * [action points](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E06/near/184940534): 19 | - We do want to try to extend both rustc and chalk. 20 | - Need to come up with a plan for chalk integration into rustc (Niko) 21 | - Need to come up with goals for chalk (Jack) 22 | - Need to put together what needs to be done for chalk-ir changes (Niko) 23 | - One way to maybe help performance would be to cache program clause creation 24 | - Should think about potential other solvers 25 | - Going to add tracing into chalk (David and Jack) 26 | - Going to create projects on wg-traits to get organized 27 | -------------------------------------------------------------------------------- /minutes/design-2020-01-13.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.01.13 2 | 3 | ## topic 4 | 5 | Alias types, bringing rustc and chalk closer together, and truncation 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185524101) 8 | 9 | [A hackMD with some chalk goals](https://hackmd.io/VeMmXIYBRu2KdYbJDIpcFA?both) 10 | 11 | ## summary 12 | 13 | Key points in the discussion: 14 | * [setting up a "chalk development" project](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185524694) 15 | * [re-implementing `impl Trait` as an alias](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185525598) 16 | * [move rustc and chalk closer together by refactoring them both](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185527268) 17 | * [type representation, `Ty` vs `TyData`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185527502) 18 | * [`Alias` enum representation](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185528001) 19 | * [rust-analyzer bug around truncation](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185529345) 20 | * [meeting summary](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E01.2E13/near/185531717): 21 | - `Alias` might make sense as one enum variant, or maybe three 22 | - We want to bring rustc and Chalk's types closer together/merge 23 | - @**detrumi** is going to try to reimplement `impl Trait` 24 | - We should try to just remove truncation and instead just `Flounder` (Jack will try) 25 | - performance/cancellation is the next big thing if we remove truncation & related errors 26 | -------------------------------------------------------------------------------- /minutes/design-2020-02-11.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.02.11 2 | 3 | ## topic 4 | 5 | Unofficial start of a "trial" wg-traits sprint 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187949855) 8 | 9 | [Sprint planning doc](https://paper.dropbox.com/doc/wg-traits-2020-sprint-planning--AvNwMlSOogLX0k73AfezNY4zAg-SSt74TfcovdnKKhZNyzeW) 10 | 11 | ## summary 12 | 13 | Key points in the discussion: 14 | * [Trying out sprints for the Traits working group again](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187954919) 15 | * [Blockers for integrating chalk and rustc](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187955733) 16 | * [Creating a `rustc_ty` crate to share between chalk and rustc](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187956058) 17 | * [More discussion on blockers](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187956348), and specifically [debruijn indices](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187956700) 18 | * [Bringing rustc closer to chalk, for example by refactoring `ty::Predicate`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187957236) 19 | * [Planning the sprint by tagging issues (and niko working on his skill-tree)](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187957931) 20 | * [Things in rustc that are missing from chalk](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187958602) 21 | * [issue triage: `RustIrDatabase` interface](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187959368) 22 | * [defining long-term plans and getting organized](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meetting.202020.2E02.2E11/near/187959947) 23 | -------------------------------------------------------------------------------- /minutes/design-2020-02-25.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.02.25 2 | 3 | ## topic 4 | 5 | Discussions on chalk refactorings 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189060154) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [head count for who's working on the sprint](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189061051) 13 | * [`impl Trait`, opaque types](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189061403) 14 | * [differences between type projections and impl trait](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189062739) 15 | * [adding the interner to chalk code](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189063630) 16 | * [sized and auto-traits](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189064002) 17 | * [rustc refactorings on `Predicate` not being picked up](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E02.2E25/near/189065423) 18 | -------------------------------------------------------------------------------- /minutes/design-2020-03-03.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.03.03 2 | 3 | ## topic 4 | 5 | Half-way point to the first sprint 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189633304) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [upcoming design meeting on library-ifying chalk-ty/rustc-ty](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189633985) 13 | * [planning and the skill tree](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189635407) 14 | * [next steps for integrating `impl Trait` in RA](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189636191) 15 | * [mapping types between rustc and chalk](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189636724) 16 | - [types mapping table](https://rust-lang.github.io/chalk/book/types/rust_types.html#mapping-to-rustc-types) 17 | - [types in RA](https://github.com/rust-analyzer/rust-analyzer/blob/5abc45982b5558d4c5f8753cb531a4a0858faa0f/crates/ra_hir_ty/src/lib.rs#L71-L145) 18 | * [ambiguous associated types, which are problematic for rust-analyzer](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189637861) 19 | * [things "left" this sprint](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E03/near/189639234): 20 | 1. impl Trait 21 | 2. tracing 22 | 3. Finishing `Interner` refactoring 23 | -------------------------------------------------------------------------------- /minutes/design-2020-03-10.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.03.10 2 | 3 | ## topic 4 | 5 | Discussion on impl Trait (mostly) 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E10/near/190216727) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [updates on Interner](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E10/near/190219031) 13 | * [impl Trait](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E10/near/190219649) 14 | -------------------------------------------------------------------------------- /minutes/design-2020-03-17.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.03.17 2 | 3 | ## topic 4 | 5 | Sprint discussion, builtin traits and types 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E17/near/190902377) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [`TyData::Fn`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E17/near/190904085) 13 | * [sprint discussion](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E17/near/190905134) 14 | * [builtin traits](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E17/near/190907418) 15 | * [recursive solver vs SLG](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E17/near/190909029) 16 | -------------------------------------------------------------------------------- /minutes/design-2020-03-24.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.03.24 2 | 3 | ## topic 4 | 5 | Sprint recap, next sprint goals 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E24/near/191663614) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Things accomplished](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E24/near/191664933) 13 | * [Tracing](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E24/near/191665617) 14 | * [Next sprint discussion](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E24/near/191665917) 15 | -------------------------------------------------------------------------------- /minutes/design-2020-03-31.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.03.31 2 | 3 | ## topic 4 | 5 | New sprint, who dis 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E31/near/192441350) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [How to organize the sprint](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E31/near/192443140) 13 | * [Chalk releases](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E31/near/192444969) 14 | * [What is needed in the book?](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E31/near/192446459) 15 | * [Implied bounds](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E31/near/192447465) 16 | * [Planning design meetings](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E03.2E31/near/192448605) 17 | -------------------------------------------------------------------------------- /minutes/design-2020-04-07.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.04.07 2 | 3 | ## topic 4 | 5 | const in Chalk 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193239347) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Recent activity](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193240567) 13 | * [what is a const](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193241542) 14 | * [design considerations for chalk consts](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193242623) 15 | * [Mututal recursion of consts](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193243417) 16 | * [When do we want to implement](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193246061) 17 | * [`Fold` and `Visit` naming](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E07/near/193246520) 18 | -------------------------------------------------------------------------------- /minutes/design-2020-04-14.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.04.14 2 | 3 | ## topic 4 | 5 | Sprint progress review 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E14/near/193948519) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Recent activity](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E14/near/193949754) 13 | * [Sprint progress review](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E14/near/193950312) 14 | * [Chalk book](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E14/near/193951120) 15 | * [Chalk releases](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E14/near/193953084) 16 | -------------------------------------------------------------------------------- /minutes/design-2020-04-21.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.04.21 2 | 3 | ## topic 4 | 5 | Implied bounds 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E21/near/194853430) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Recent activity](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E21/near/194853602) 13 | * [What are implied bounds](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E21/near/194854642) 14 | * [Reasoning of `FromEnv`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E21/near/194856679) 15 | * [WellFormed goals](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E21/near/194858563) 16 | -------------------------------------------------------------------------------- /minutes/design-2020-04-28.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.04.28 2 | 3 | ## topic 4 | 5 | Builtin types/traits, link check, opaque types, const types 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E28/near/195618205) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Recent activity](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E28/near/195618377) 13 | * [Builtin types/traits](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E28/near/195619901) 14 | * [Link check](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E28/near/195622231) 15 | * [Opaque types](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E28/near/195624119) 16 | * [const types](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E04.2E28/near/195625661) 17 | -------------------------------------------------------------------------------- /minutes/design-2020-05-05.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.05.05 2 | 3 | ## topic 4 | 5 | leak check, `ObjectSafe` and `Outlives` goals, const PR discussion 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E05/near/196359047) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Recent activity](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E05/near/196359487) 13 | * [Universe transition in rustc](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E05/near/196360573) 14 | * [Leak cheak](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E05/near/196361190) 15 | * [`ObjectSafe` and `Outlives`](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E05/near/196363704) 16 | * [const PR discussion](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E05/near/196365991) 17 | -------------------------------------------------------------------------------- /minutes/design-2020-05-12.md: -------------------------------------------------------------------------------- 1 | # traits design meeting 2020.05.12 2 | 3 | ## topic 4 | 5 | Sprint recap 6 | 7 | [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E12/near/197329732) 8 | 9 | ## summary 10 | 11 | Key points in the discussion: 12 | * [Recent activity](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E12/near/197329871) 13 | * [How do we want to keep minutes](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E12/near/197330803) 14 | * [Sprint recap](https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/design.20meeting.202020.2E05.2E12/near/197332669) 15 | -------------------------------------------------------------------------------- /minutes/triage-2019-02-24.md: -------------------------------------------------------------------------------- 1 | # Triage meeting on 2019-02-24 2 | 3 | ## Info 4 | 5 | [Zulip thread.](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-02-25) 6 | 7 | ## Summary 8 | 9 | The goal of the meeting was to try and figure out, in somewhat more 10 | detail, how we want to organize the traits working group itself. We've 11 | been doing [work on enumerating and triaging the set of things we hope 12 | to do][roadmap], but in this meeting we were basically trying to come 13 | up with some concrete next steps. 14 | 15 | [roadmap]: https://paper.dropbox.com/doc/Traits-Roadmap-sketch--AYTQPvAVQ~p4lyElpr24zoAQAg-m6hucUslp7GihsY3SjNN2 16 | 17 | Ultimately we identified the following next steps: 18 | 19 | - Schedule a meeting to dig into some of the **lifetime problems around 20 | async-await**. This is kind of an "intersecting" issue between async await 21 | and the traigs WG, but seems high priority. (nikomatsakis) 22 | - **Explore the use cases for lazy normalization**, trying to create a summary 23 | of exactly which test cases are causing problems and why, and what it might 24 | take to fix them (can it be done without a full chalk transition?). (nikomatsakis) 25 | - **Explore the use cases for GATs**, trying to find a set of specific examples 26 | from async-await and other contexts. It seems likely that we could do an initial 27 | impl of GATs in rustc without chalk, but would it be enough? (aturon, centril) 28 | - Schedule a meeting to **dig into the chalk transition** -- what is 29 | current status and what are the possible future routes, what should 30 | we be exploring? (nikomatsakis, scalexm) 31 | - Get tests plus FCP around `type Foo = impl Bar` (centril) 32 | 33 | In general, we're trying to get a sense for what the [initial set of 34 | active 'subprojects' will 35 | be](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-02-25/near/159365173) 36 | (basically, the things that the WG is focusing on). Ideally, each of 37 | them will have a distinct "lead" (or, better, leads!) who is driving 38 | the effort (in collaboration with the rest of us). 39 | 40 | A **likely** set of initial subprojects will contain: 41 | 42 | - some amount of hacking on rustc (GATs, lazy norm) in an effort to "relieve the pressure" 43 | - some amount of hacking on chalk itself and on chalk integration 44 | - some amount of work on defining the semantics of other features like 45 | specialization by lowering them to chalk predicates 46 | 47 | but that is not certain. A key drive is both the set of people we have 48 | involved and also what seems to be highest priority in terms of 49 | unblocking other things within Rust. 50 | -------------------------------------------------------------------------------- /minutes/triage-2019-03-04.md: -------------------------------------------------------------------------------- 1 | # Triage meeting on 2019-03-04 2 | 3 | ## Info 4 | 5 | [Zulip thread.](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04) 6 | 7 | ## Summary 8 | 9 | We followed up on the goals from last time. 10 | 11 | ### Lifetime problems around async-await 12 | 13 | We 14 | [discussed](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159939976) 15 | how we found a way to resolve the `async fn` complications by changing 16 | the async fn desugaring, and hence don't need any deep trait 17 | action. We are [still 18 | interested](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940028) 19 | in trying to find a way to solve the "captures problem" for impl 20 | Trait, however, and alexreg and nikomatsakis may do some follow-up 21 | there. 22 | 23 | ### Explore use cases for lazy normalization 24 | 25 | Some investigation occurred. [Current plan](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940188) 26 | to continue documenting the way that the current normalization code 27 | plays out and to hold some sort of meeting to document that and walk 28 | through it. That meeting will hopefully happen this week and will be 29 | recorded. 30 | 31 | ### Explorse use cases for GATs 32 | 33 | [Not a lot of progress here.](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940294) (Yet!) 34 | 35 | Once we **do** make progress, though, the [logical next 36 | step](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940943) 37 | is probably to try and model those use cases some in Chalk, as well as 38 | to investigate more deeply how rustc could be extended to handle the 39 | cases natively (without blocking on full chalk integration). 40 | 41 | ### Dig into the chalk transition 42 | 43 | We [have a meeting scheduled for tomorrow](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940496) with the RLS 2.0 folks, planning to talk about how the type checker is working in that context. 44 | 45 | [**We are thinking that integrating Chalk first into the RLS 2.0 46 | project may be a better idea than starting with 47 | rustc**](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940552), 48 | particularly as it can help get RLS 2.0 to a "working product" faster, 49 | but also because we may be able to use that to pursue the idea of 50 | sharing more code between chalk + compiler than we could readily do 51 | with rustc. Specifically, we should be able to have: 52 | 53 | - a library to share the definition of types between chalk + RLS 2.0 54 | - shared code for lowering traits + impls into logical rules 55 | 56 | We also talked about other possible work on chalk, in particular the 57 | idea of chalk-specific refactorings but also building a [benchmarking 58 | harness](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159940894) 59 | for the `chalk-engine` crate. 60 | 61 | ## Miscellaneous discussion 62 | 63 | There are a few other things we talked about this week: 64 | 65 | - [the idea of a research intern working on chalk and what they might 66 | do](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159941464) 67 | - [how we might support `async fn` in traits without full GAT support](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weekly.20meeting.202019-03-04/near/159942222) 68 | 69 | ## Plans for the coming week 70 | 71 | We settled on the following plans for the coming week: 72 | 73 | So plans for this week are: 74 | 75 | - Describe how normalization works today and hold a (recorded) call to 76 | try and explain it to others. Trace through some of the examples 77 | where lazy norm would be helpful. (nikomatsakis) 78 | - Explore the use cases for GATs (aturon, centril) 79 | - Discuss RLS 2.0 type checker and contemplate how to integrate chalk 80 | into it (nikomatsakis, scalexm) 81 | - Maybe discuss other chalk improvements? (e.g., benchmarking harness) (nikomatsakis) 82 | - Maybe discuss the "lifetime capture" problem in impl Trait? (nikomatsakis, alexreg) 83 | 84 | -------------------------------------------------------------------------------- /minutes/triage-2019-03-11.md: -------------------------------------------------------------------------------- 1 | # Triage meeting on 2019-03-11 2 | 3 | ## Info 4 | 5 | [Zulip thread][] 6 | 7 | [Zulip thread]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weeky.20meeting.202019-03-11 8 | 9 | ## Help wanted! 10 | 11 | - nikomatsakis is looking for someone to help with investigating lazy 12 | normatlization. The task would be to experimentally modify rustc and 13 | is best suited to someone already vaguely familiar with the Rust query 14 | system etc. See below. 15 | 16 | ## Summary 17 | 18 | We followed up on the goals from last time. 19 | 20 | ### Lazy normalization and const generics 21 | 22 | [Link](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weeky.20meeting.202019-03-11/near/160502973) 23 | 24 | Last week, nikomatsakis did more investigation, taking notes in [this 25 | dropbox paper document][lnpaper]. In general, it's still not entirely 26 | clear if the "cycle" that gives rise to the need for lazy 27 | normalization is something we can easily circumvent. One thing is that 28 | the `generics_of` and other queries for "anonymous constants" 29 | currently use the incorrect parent def-id precisely to avoid a cycle, 30 | so it's hard to see how the cycle would manifest. 31 | 32 | [lnpaper]: https://paper.dropbox.com/doc/Lazy-normalization-Ryv4YfpIcGAl6R3ZtWrWs 33 | 34 | **Next step:** re-establish the cycle in those queries so it can be observed. 35 | 36 | ### GATs 37 | 38 | [Link](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weeky.20meeting.202019-03-11/near/160503327) 39 | 40 | centril + aturon drew up a [paper document containing GAT use 41 | casts][gat] and there are some notes from the conversation in [this 42 | Zulip thread][gatthread]. 43 | 44 | **Next step:** unclear, but probably to investigate the use cases and 45 | make some comments. 46 | 47 | [gat]: https://paper.dropbox.com/doc/GAT-use-case-analysis--AY1Ck74Fgk1Ztq1kHrethI8BAg-xFJQMxHXTOUekCyweukU1 48 | [gatthread]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/GAT.20use-case.20analysis 49 | 50 | ### Integrating into RLS 2.0 51 | 52 | [Link](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/weeky.20meeting.202019-03-11/near/160503711) 53 | 54 | We had a chat ([with 55 | video](https://www.youtube.com/watch?v=Lmp3P9WNL8o)) about how the RLS 56 | 2.0 type checker works. We decided we'd rather try to do the chalk 57 | integration into RLS 2.0 "correct", meaning that we can share a lot 58 | more code with chalk. 59 | 60 | **Next step:** nikomatsakis to schedule some time to sketch out what chalk integration would look like. 61 | 62 | ### Other chalk improvements 63 | 64 | > Maybe discuss other chalk improvements? (e.g., benchmarking harness) (nikomatsakis) 65 | 66 | This didn't happen and we'll probably shelve it for now in favor of the previous point. 67 | 68 | ### "lifetime capture" 69 | 70 | > Maybe discuss the "lifetime capture" problem in impl Trait? 71 | 72 | This didn't happen and we'll probably shelve it for now in favor of the next point. 73 | 74 | ### Draft RFCs 75 | 76 | centril plans to (at minimum) upload some draft RFCs to a new wg-traits repository. 77 | 78 | ### Associated type bounds 79 | 80 | alexreg has been working on associated type bounds in [this Zulip 81 | thread][atb] and will likely continue to do so. 82 | 83 | [atb]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-compiler.2Fwg-traits/topic/associate.20type.20bounds 84 | 85 | 86 | ## Plans for the coming week 87 | 88 | - Try to correct the `generics_of` query etc for constants so we can 89 | observe what results. 90 | - **Help wanted!** nikomatsakis is looking for someone to help 91 | with investigating lazy normatlization. The task would be to 92 | experimentally modify rustc and is best suited to someone 93 | already vaguely familiar with the Rust query system etc. 94 | - Read-over GAT use cases and try to theorize about what it would take to 95 | support them in rustc etc (nikomatsakis) 96 | - Schedule a call to talk over what chalk integration into RLS 2.0 might look like (nikomatsakis) 97 | - Create a wg-traits repository to house draft RFCs and the like. (nikomatsakis) 98 | - Upload drafts of various traits-related RFCs to wg-traits (centril) 99 | - Continue work on associated type bounds (alexreg) 100 | -------------------------------------------------------------------------------- /roadmap.toml: -------------------------------------------------------------------------------- 1 | [[group]] 2 | name = "rustc-universe-transition" 3 | label = "rustc universe transition" 4 | href = "https://github.com/rust-lang/rust/issues/56105" 5 | items = [ 6 | { label = "introduce universe system into rustc", status="Complete", href="https://github.com/rust-lang/rust/pull/65232" }, 7 | { label = "extend NLL solver with new universes", status="Complete", href="https://github.com/rust-lang/rust/pull/70950" }, 8 | { label = "resolve wasm-bindgen interaction", status="Assigned" }, 9 | ] 10 | 11 | [[group]] 12 | name = "align-rustc-predicate" 13 | label = "Align rustc predicates with chalk predicates" 14 | requires = ["rustc-universe-transition"] 15 | href = "https://github.com/rust-lang/compiler-team/issues/285" 16 | items = [ 17 | { label = "isolate Binder into a Forall goal" }, 18 | { label = "introduce Implication" }, 19 | { label = "introduce Forall goals with types" }, 20 | ] 21 | 22 | [[group]] 23 | name = "recursive-solver" 24 | label = "Experiment with a recursive chalk solver" 25 | items = [ 26 | { label = "Write-up the idea that Niko had", status="Complete", href="https://gist.github.com/nikomatsakis/bfbdbe588d6fc61ecb09e3b51847fb7c" }, 27 | { label = "Build prototype", status="Complete", href="https://github.com/rust-lang/chalk/issues/351" }, 28 | { label = "Resolve coinductive semantics", status="Assigned", href="https://github.com/rust-lang/chalk/issues/399" }, 29 | ] 30 | 31 | [[group]] 32 | name = "impl-trait" 33 | label = "Model `impl Trait`" 34 | items = [ 35 | { label = "Preliminary model for opaque types where hidden types are known", status="Assigned", ref = "https://github.com/rust-lang/chalk/issues/335" }, 36 | ] 37 | 38 | [[group]] 39 | name = "chalk-outlives" 40 | label = "Extend chalk with outlives goals" 41 | href = "https://github.com/rust-lang/chalk/issues/435" 42 | items = [ 43 | { label = "add region outlives goals", status = "Complete" }, 44 | { label = "add type outlives goals", status = "Complete" }, 45 | { label = "add type outlives constraints", status = "Complete" }, 46 | ] 47 | 48 | [[group]] 49 | name = "rust-analyzer-integration" 50 | label = "Integrate with rust-analyzer" 51 | requires = ["impl-trait"] 52 | items = [ 53 | { label = "Ensure that we never need to ask for impls of unknown types", port = "askfor", requires = ["syntactic-semantic-equality"] }, 54 | { label = "Deal with performance problems", status = "Blocked" }, 55 | { label = "Deal with memory usage", status = "Blocked" }, 56 | ] 57 | 58 | [[group]] 59 | name = "syntactic-semantic-equality" 60 | label = "Separate syntactic equality from semantic equality" 61 | href = "https://github.com/rust-lang/chalk/issues/364" 62 | requires = [ 63 | "map-chalk-types-to-rustc-types:debruijn", 64 | "map-chalk-types-to-rustc-types:visit" 65 | ] 66 | status = "Assigned" 67 | items = [ 68 | { label = "Implementation" } 69 | ] 70 | 71 | [[group]] 72 | name = "map-chalk-types-to-rustc-types" 73 | label = "Map chalk types to rustc types" 74 | href = "https://github.com/rust-lang/types-team/issues/16" 75 | items = [ 76 | { label = "Rename Projection to Alias", status="Complete" }, 77 | { label = "Make ty intern method take &self", href="https://github.com/rust-lang-nursery/chalk/issues/328", status="Complete" }, 78 | { label = "Make ty data methods take &self", href="https://github.com/rust-lang/chalk/issues/339", status="Complete" }, 79 | { label = "Make other intern method take &self", href="https://github.com/rust-lang-nursery/chalk/issues/340", status="Complete" }, 80 | { label = "Make other data methods take &self", href="https://github.com/rust-lang/chalk/issues/341", status="Complete" }, 81 | { label = "Align placeholders and ty::Param", status="Blocked" }, 82 | { label = "Move Identifier to TypeFamily", status="Complete" }, 83 | { label = "Adapt rustc's debruijn index model", port="debruijn", status="Complete", href="https://github.com/rust-lang/chalk/issues/334" }, 84 | { label = "Adapt rustc's representation of late-bound items", status="Blocked" }, 85 | { label = "Remove all vectors, boxes", href="https://github.com/rust-lang/chalk/issues/369", status="Complete" }, 86 | { label = "Introduce a `Visit` trait", href="https://github.com/rust-lang/chalk/issues/333", status="Complete", port="visit" }, 87 | { label = "Add and integrate flags into types and elsewhere" }, 88 | ] 89 | 90 | [[group]] 91 | name = "chalk-builtin" 92 | label = "Extend chalk-solve with knowledge of builtin traits and types" 93 | href = "https://github.com/rust-lang/chalk/issues/363" 94 | items = [ 95 | { label="create concept of well-known traits", status="Complete", href="https://github.com/rust-lang/chalk/issues/356" }, 96 | { label="support the `Sized` trait", status="Complete", href="https://github.com/rust-lang/chalk/issues/261" }, 97 | { label="support the `Clone` trait", status="Complete", href="https://github.com/rust-lang/chalk/issues/363" }, 98 | { label="support the `Copy` trait", status="Complete", href="https://github.com/rust-lang/chalk/issues/363" }, 99 | { label="model `ObjectSafe` goals", status="Complete", href="https://github.com/rust-lang/chalk/pull/434" }, 100 | { label="support the `Unsized` trait", status="Complete", href="https://github.com/rust-lang/chalk/pull/427" }, 101 | { label="extend `TypeName` with builtin types", href="https://github.com/rust-lang/chalk/issues/368" }, 102 | { label="support the `Fn` traits", status="Complete" }, 103 | ] 104 | 105 | [[group]] 106 | name = "chalk-const" 107 | label = "Extend chalk to support constants" 108 | items = [ 109 | { label="introduce constant 'kind', alongside types and lifetimes", status="Complete", href="https://github.com/rust-lang/chalk/pull/393" }, 110 | ] 111 | 112 | [[group]] 113 | name = "rustc-integration-mvp" 114 | label = "Integrate chalk-solve into rustc" 115 | href = "https://github.com/rust-lang/types-team/issues/18" 116 | requires = [ "map-chalk-types-to-rustc-types", "chalk-const", "chalk-builtin", "chalk-outlives" ] 117 | items = [ 118 | { label="remove old chalk support", status="Complete", href="https://github.com/rust-lang/rust/pull/69247" }, 119 | { label="exploratory integration to better uncover requirements", href="https://github.com/rust-lang/rust/pull/69406", status="Complete" }, 120 | { label="map rustc types to chalk types", status="Complete" }, 121 | { label="map rustc predicates to chalk goals, clauses", status="Complete" }, 122 | { label="implement RustIrDatabase in trait", status="Complete" }, 123 | ] 124 | 125 | [[group]] 126 | name = "features" 127 | label = "Explore proposed language features" 128 | requires = [ "rustc-integration-mvp", "rust-analyzer-integration" ] 129 | status = "Blocked" 130 | items = [ 131 | { label="Implied bounds" }, 132 | { label="Specialization", href="https://github.com/rust-lang/chalk/issues/9" }, 133 | ] 134 | 135 | [[group]] 136 | name = "chalk-debugging" 137 | label = "Improve ability to debug chalk from within rustc or rust-analyzer" 138 | requires = [ ] 139 | items = [ 140 | { label="Integrate tracing library", href="https://github.com/rust-lang/chalk/issues/337", status="Complete" }, 141 | { label="Extract standalone examples automatically", href="https://github.com/rust-lang/chalk/issues/365", status="Assigned" }, 142 | ] 143 | 144 | [[goal]] 145 | name = "library" 146 | label = "Chalk usable as a standalone library for traits solving" 147 | requires = [ "rustc-integration-mvp", "rust-analyzer-integration", "chalk-debugging" ] 148 | 149 | [[goal]] 150 | name = "gats" 151 | label = "Deploy GATs in Rust nightly" 152 | requires = [ "align-rustc-predicate" ] 153 | -------------------------------------------------------------------------------- /sprints/2020-1.md: -------------------------------------------------------------------------------- 1 | FIXME: add an overview of work done in 2020 sprint 1 2 | 3 | Link to summary blog post: 4 | https://blog.rust-lang.org/inside-rust/2020/03/28/traits-sprint-1.html 5 | -------------------------------------------------------------------------------- /sprints/2020-2.md: -------------------------------------------------------------------------------- 1 | # wg-traits sprint 2020-03-31 .. 2 | 3 | **Pulled from https://hackmd.io/kYWsWI9IS0213x0qX_1RDw on 2020/5/14** 4 | 5 | * Goal: Rustc integration MVP ([tracking issue](https://github.com/rust-lang/wg-traits/issues/18)) 6 | * Initial integration work landed 7 | * Made a lot of progress towards extending chalk to support builtin types and traits 8 | * Currently using some hacks in rustc for some of them 9 | * Next steps: 10 | * Extend chalk to be able to represent all of the Rust types [chalk#368](https://github.com/rust-lang/chalk/issues/368) 11 | * Connect rustc types to the builtin chalk types 12 | * Auto trait handling for builtin chalk types 13 | * Handling int and float literal inference variables 14 | * Region / outlives integration 15 | * Bound inference variables, perhaps? 16 | * Goal: Plan for what const integration looks like ([tracking issue](https://github.com/rust-lang/wg-traits/issues/15)) 17 | * Held [initial meeting](https://zulip-archive.rust-lang.org/144729wgtraits/23279designmeeting20200407.html) and designed a minimal subset 18 | * Implementing a [pending PR](https://github.com/rust-lang/chalk/pull/393) which uncovered some interesting questions about how to represent constants 19 | * Next steps: 20 | * [Resolve `GenericArg` handling](https://github.com/rust-lang/chalk/issues/452) 21 | * Land [chalk#393](https://github.com/rust-lang/chalk/pull/393) which will offer basic constant support 22 | * it has been reviewed and we are working out the [list of test cases](https://hackmd.io/Ah_J6nFQSbuUiVOsH5acLg) 23 | * next steps: 24 | * incorporate some mention into the chalk book 25 | * Goal: Move towards alignment of rustc and chalk types, and towards extracting a shared library ([tracking issue](https://github.com/rust-lang/wg-traits/issues/16)) 26 | * [Doc from meeting](https://hackmd.io/roRq0qHMQ6CyRJxj_FsPSQ) 27 | * Extended chalk types to support builtin rust types and traits 28 | * Refactoring of predicates on rustc side to be interned and match chalk conventions [rust-lang/rust#72055](https://github.com/rust-lang/rust/pull/72055) 29 | * Next steps: 30 | * Finalize naming conventions and rename as necessary 31 | * Create issues around rustc side 32 | * Goal: basic support for impl Trait ([tracking issue](https://github.com/rust-lang/chalk/issues/335)) 33 | * basic support has landed: [PR #324](https://github.com/rust-lang/chalk/pull/324), :tada: 34 | * working now on adding better generics support 35 | * [Next steps](https://github.com/rust-lang/chalk/issues/335#issuecomment-615254659) 36 | * Goal: progress towards removing leak check in rustc ([tracking issue](https://github.com/rust-lang/rust/issues/59490)) 37 | * Landed [#70950](https://github.com/rust-lang/rust/pull/70950) which aligns NLL with lexical checker 38 | * but to truly remove leak check we have to resolve some back-compat interactions 39 | * Next steps: 40 | * rustc refactoring to move leak check to occur later, which unblocks lazy norm and a few other changes 41 | * explore a smarter variant of leak check that takes into account implied bounds and is able to continue accepting wasm-bindgen 42 | * Goal: exploration and research 43 | * exploring recursive solver (flodiebold) 44 | * initial version has landed and been integrated into rust-analyzer 45 | * Follow-up items: 46 | * fix coinduction [chalk#399](https://github.com/rust-lang/chalk/issues/399) 47 | * revisiting the chalk-solve crate structure 48 | * documenting how it works in chalk-book 49 | * comparison between it and SLG checker 50 | * explore converting semantic-to-syntactic equality 51 | * [draft PR opened](https://github.com/rust-lang/chalk/pull/401) 52 | * create a chalk file from any given program 53 | * [draft PR opened](https://github.com/rust-lang/chalk/pull/430) and it's starting to work 54 | * Goal: increase Chalk performance (very open-ended) 55 | * Create a set of benchmarks 56 | * no progress 57 | * Add tracing support 58 | * opened a [draft PR](https://github.com/rust-lang/chalk/pull/409) 59 | * Track memory usage and try to decrease as necessary 60 | * no progress 61 | * Goal: add more to Chalk book 62 | * Added [chalk big picture](http://rust-lang.github.io/chalk/book/#high-level-view-of-how-chalk-works) material 63 | * Moved content from [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/traits/chalk-overview.html) 64 | * Added [table tracking the well-known traits](http://rust-lang.github.io/chalk/book/clauses/well_known_traits.html#current-state) 65 | * Next steps: 66 | * glossary and notation for common terms 67 | * the `?0` notation 68 | * the `^0` notation 69 | * the `!0` notation 70 | * what is a "bound variable", an "inference variable", and a "placeholder variable", and what do they *mean* semantically 71 | -------------------------------------------------------------------------------- /src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Welcome](./welcome.md) 4 | - [Development roadmap](./roadmap.md) 5 | - [Minutes and design notes](./minutes.md) 6 | -------------------------------------------------------------------------------- /src/minutes.md: -------------------------------------------------------------------------------- 1 | Minutes from various meetings are located in [the `minutes` directory 2 | on the github repository][minutes]. 3 | 4 | [minutes]: https://github.com/rust-lang/types-team/tree/master/minutes 5 | -------------------------------------------------------------------------------- /src/roadmap.md: -------------------------------------------------------------------------------- 1 | # Development roadmap 2 | 3 | We maintain a [development roadmap][dr] that shows both our current 4 | efforts, future work we have in mind, and the overall goals we are 5 | working towards. Many of the items on that map have links that lead to 6 | corresponding issues on the appropriate tracker. Alternatively, if 7 | you're just looking for issues to pick up, you can take a look at 8 | these issue lists on Github: 9 | 10 | * [current-sprint issues on chalk](https://github.com/rust-lang/chalk/labels/current-sprint) 11 | 12 | We are working from a 6-week "sprint cycle". We're still working out 13 | the details of how we organize our sprints. For now, if you'd like to 14 | claim one of the above issues or get involved, though, drop by on [the 15 | rust-lang Zulip] in the [`#t-types`] stream and say hello! 16 | 17 | [the rust-lang Zulip]: https://rust-lang.zulipchat.com/ 18 | [`#t-types`]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types 19 | [dr]: roadmap/skill-tree.html 20 | -------------------------------------------------------------------------------- /src/welcome.md: -------------------------------------------------------------------------------- 1 | # Welcome to the types team 2 | 3 | ## Scope and purpose 4 | 5 | The **types** team is dedicated to improving the trait 6 | system implementation in rustc. This team is a collaboration 7 | between the [lang team] and the compiler team. We have a number of inter-related 8 | goals: 9 | 10 | - designing new trait-related language features; 11 | - documenting and specifying the semantics of traits in Rust today; and, 12 | - improving the trait solver implementation in rustc. 13 | 14 | [lang team]: https://github.com/rust-lang/lang-team/ 15 | 16 | A big part of this work is transitioning the compiler to use a 17 | [Chalk-style] solver, but along the way we hope to make targeted fixes 18 | to the existing solver where needed. 19 | 20 | [Chalk-style]: https://github.com/rust-lang-nursery/chalk 21 | 22 | ## Design meetings 23 | 24 | We hold weekly design meetings where we talk in depth about various 25 | topics ([calendar event][ce-design]). These meetings take place on Zulip (see below). The goal is 26 | not just to figure out what we want to do, it's also a way to spread 27 | knowledge. Feel free to come and lurk! 28 | 29 | [ce-design]: https://calendar.google.com/event?action=TEMPLATE&tmeid=MnFmbmdkaGV0aXE3Zjc4cjlpNWVjNDRoZXMgNnU1cnJ0Y2U2bHJ0djA3cGZpM2RhbWdqdXNAZw&tmsrc=6u5rrtce6lrtv07pfi3damgjus%40group.calendar.google.com 30 | 31 | You'll find minutes from past meetings in [the minutes 32 | directory](minutes). We also keep have a 33 | [hackmd](https://hackmd.io/nrhN5A8sR2eY9UdfJTKcJg?edit) where we keep 34 | a log of what's been happening and track possible agendas for upcoming 35 | meetings. 36 | 37 | ## Chat forum 38 | 39 | On [the rust-lang Zulip][z], in [the `#t-types` stream][s]. 40 | 41 | [z]: https://rust-lang.zulipchat.com/ 42 | [s]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types 43 | 44 | ## Dedicated repository 45 | 46 | Documents related to the types team are stored on a 47 | dedicated repository, [rust-lang/types-team]. This repository contains 48 | meeting minutes, past sprints, as well as draft RFCs and other 49 | documents. 50 | 51 | [rust-lang/types-team]: https://github.com/rust-lang/types-team 52 | -------------------------------------------------------------------------------- /triagebot.toml: -------------------------------------------------------------------------------- 1 | [major-change] 2 | second_label = "final-comment-period" 3 | meeting_label = "to-announce" 4 | open_extra_text = "cc @rust-lang/types" 5 | zulip_stream = 326866 # #T-types/nominated 6 | zulip_ping = "T-types" 7 | 8 | [assign] 9 | --------------------------------------------------------------------------------