├── .gitignore ├── .gitattributes ├── text ├── 2071-impl-trait-type-alias.md ├── 0060-rename-strbuf.md ├── 0534-deriving2derive.md ├── 0112-remove-cross-borrowing.md ├── 0139-remove-cross-borrowing-entirely.md ├── 0342-keywords.md ├── 0050-assert.md ├── 0123-share-to-threadsafe.md ├── 0111-index-traits.md ├── 1119-result-expect.md ├── 0341-remove-virtual-structs.md ├── 0164-feature-gate-slice-pats.md ├── 0168-mod.md ├── 0087-trait-bounds-with-plus.md ├── 1467-volatile.md ├── 1260-main-reexport.md ├── 0909-move-thread-local-to-std-thread.md ├── 0469-feature-gate-box-patterns.md ├── 0593-forbid-Self-definitions.md ├── 0522-self-impl.md ├── 0202-subslice-syntax-change.md ├── 0601-replace-be-with-become.md ├── 1590-macro-lifetimes.md ├── 1030-prelude-additions.md ├── 1219-use-group-as.md ├── 0151-capture-by-value.md ├── 1535-stable-overflow-checks.md ├── 0771-std-iter-once.md ├── 0532-self-in-use.md ├── 1660-try-borrow.md ├── 0531-define-rfc-scope.md ├── 0450-un-feature-gate-some-more-gates.md ├── 1419-slice-copy.md ├── 1653-assert_ne.md ├── 0066-better-temporary-lifetimes.md ├── 1548-global-asm.md ├── 0234-variants-namespace.md ├── 0968-closure-return-type-syntax.md ├── 1135-raw-pointer-comparisons.md ├── 1300-intrinsic-semantics.md ├── 1725-unaligned-access.md ├── 1695-add-error-macro.md ├── 2296-option-replace.md ├── 0026-remove-priv.md ├── 0059-remove-tilde.md ├── 0702-rangefull-expression.md ├── 0085-pattern-macros.md ├── 1096-remove-static-assert.md ├── 2471-lint-test-inner-function.md ├── 2341-const-locals.md ├── 1174-into-raw-fd-socket-handle-traits.md ├── 1651-movecell.md ├── 2836-project-asm.md ├── 1307-osstring-methods.md ├── 3392-leadership-council │ └── non-goals.md ├── 0049-match-arm-attributes.md ├── 1152-slice-string-symmetry.md ├── 1498-ipv6addr-octets.md ├── 2420-unreserve-proc.md ├── 0115-rm-integer-fallback.md ├── 0184-tuple-accessors.md ├── 0356-no-module-prefixes.md ├── 0221-panic.md ├── 2509-byte-concat.md ├── 1647-allow-self-in-where-clauses.md ├── 0459-disallow-shadowing.md ├── 1014-stdout-existential-crisis.md ├── 0063-module-file-system-hierarchy.md ├── 2230-bury-description.md ├── 1434-contains-method-for-ranges.md ├── 1521-copy-clone-semantics.md ├── 1983-nursery-deprecation.md ├── 0179-and-mut-patterns.md ├── 0572-rustc-attribute.md ├── 1131-likely-intrinsic.md ├── 0378-expr-macros.md ├── 1054-str-words.md ├── 0446-es6-unicode-escapes.md ├── 0558-require-parentheses-for-chained-comparisons.md ├── 0574-drain-range.md ├── 0563-remove-ndebug.md ├── 1640-duration-checked-sub.md ├── 2832-core-net-types.md ├── 0735-allow-inherent-impls-anywhere.md ├── 0888-compiler-fence-intrinsics.md ├── 0438-precedence-of-plus.md ├── 0214-while-let.md └── 1552-contains-method-for-various-collections.md ├── .github ├── renovate.json5 ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── deploy.yml ├── book.toml ├── LICENSE-MIT ├── triagebot.toml ├── lang_changes.md ├── compiler_changes.md └── generate-book.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | book/ 3 | src/ 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.md linguist-detectable 2 | -------------------------------------------------------------------------------- /text/2071-impl-trait-type-alias.md: -------------------------------------------------------------------------------- 1 | Moved to [2071-impl-trait-existential-types.md](2071-impl-trait-existential-types.md). 2 | -------------------------------------------------------------------------------- /.github/renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | extends: [ 3 | 'config:best-practices', 4 | ':pinAllExceptPeerDependencies', 5 | ':maintainLockFilesWeekly', 6 | ':semanticCommitsDisabled', 7 | ':label(not-rfc)', 8 | 'customManagers:githubActionsVersions', 9 | 'schedule:monthly', 10 | ], 11 | } 12 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | title = "The Rust RFC Book" 3 | 4 | [output.html] 5 | smart-punctuation = true 6 | no-section-label = true 7 | git-repository-url = "https://github.com/rust-lang/rfcs" 8 | site-url = "/rfcs/" 9 | 10 | [output.html.search] 11 | heading-split-level = 0 12 | 13 | [output.html.playground] 14 | runnable = false 15 | 16 | [build] 17 | extra-watch-dirs = ["text"] 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | > [!IMPORTANT] 5 | > When responding to RFCs, try to use inline review comments (it is possible to leave an inline review comment for the entire file at the top) instead of direct comments for normal comments and keep normal comments for procedural matters like starting FCPs. 6 | > 7 | > This keeps the discussion more organized. 8 | -------------------------------------------------------------------------------- /text/0060-rename-strbuf.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-04-30 2 | - RFC PR: [rust-lang/rfcs#60](https://github.com/rust-lang/rfcs/pull/60) 3 | - Rust Issue: [rust-lang/rust#14312](https://github.com/rust-lang/rust/issues/14312) 4 | 5 | ## Summary 6 | 7 | `StrBuf` should be renamed to `String`. 8 | 9 | ## Motivation 10 | 11 | Since `StrBuf` is so common, it would benefit from a more traditional name. 12 | 13 | ## Drawbacks 14 | 15 | It may be that `StrBuf` is a better name because it mirrors Java `StringBuilder` or C# `StringBuffer`. It may also be that `String` is confusing because of its similarity to `&str`. 16 | 17 | ## Detailed design 18 | 19 | Rename `StrBuf` to `String`. 20 | 21 | ## Alternatives 22 | 23 | The impact of not doing this would be that `StrBuf` would remain `StrBuf`. 24 | 25 | ## Unresolved questions 26 | 27 | None. 28 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /text/0534-deriving2derive.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-19-19 2 | - RFC PR: [534](https://github.com/rust-lang/rfcs/pull/534) 3 | - Rust Issue: [20362](https://github.com/rust-lang/rust/issues/20362) 4 | 5 | ## Summary 6 | 7 | Rename the `#[deriving(Foo)]` syntax extension to `#[derive(Foo)]`. 8 | 9 | ## Motivation 10 | 11 | Unlike our other verb-based attribute names, "deriving" stands alone as a 12 | present participle. By convention our attributes prefer "warn" rather than 13 | "warning", "inline" rather than "inlining", "test" rather than "testing", and so 14 | on. We also have a trend against present participles in general, such as with 15 | `Encoding` being changed to `Encode`. 16 | 17 | It's also shorter to type, which is very important in a world without implicit 18 | Copy implementations. 19 | 20 | Finally, if I may be subjective, `derive(Thing1, Thing2)` simply reads better 21 | than `deriving(Thing1, Thing2)`. 22 | 23 | ## Detailed design 24 | 25 | Rename the `deriving` attribute to `derive`. This should be a very simple find- 26 | and-replace. 27 | 28 | ## Drawbacks 29 | 30 | Participles the world over will lament the loss of their only foothold in this 31 | promising young language. 32 | -------------------------------------------------------------------------------- /text/0112-remove-cross-borrowing.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-06-09 2 | - RFC PR: [rust-lang/rfcs#112](https://github.com/rust-lang/rfcs/pull/112) 3 | - Rust Issue: [rust-lang/rust#10504](https://github.com/rust-lang/rust/issues/10504) 4 | 5 | ## Summary 6 | 7 | Remove the coercion from `Box` to `&mut T` from the language. 8 | 9 | ## Motivation 10 | 11 | Currently, the coercion between `Box` to `&mut T` can be a hazard because it can lead to surprising mutation where it was not expected. 12 | 13 | ## Detailed design 14 | 15 | The coercion between `Box` and `&mut T` should be removed. 16 | 17 | Note that methods that take `&mut self` can still be called on values of type `Box` without any special referencing or dereferencing. That is because the semantics of auto-deref and auto-ref conspire to make it work: the types unify after one autoderef followed by one autoref. 18 | 19 | ## Drawbacks 20 | 21 | Borrowing from `Box` to `&mut T` may be convenient. 22 | 23 | ## Alternatives 24 | 25 | An alternative is to remove `&T` coercions as well, but this was decided against as they are convenient. 26 | 27 | The impact of not doing this is that the coercion will remain. 28 | 29 | ## Unresolved questions 30 | 31 | None. 32 | -------------------------------------------------------------------------------- /text/0139-remove-cross-borrowing-entirely.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-06-25 2 | - RFC PR: [rust-lang/rfcs#139](https://github.com/rust-lang/rfcs/pull/139) 3 | - Rust Issue: [rust-lang/rust#10504](https://github.com/rust-lang/rust/issues/10504) 4 | 5 | ## Summary 6 | 7 | Remove the coercion from `Box` to `&T` from the language. 8 | 9 | ## Motivation 10 | 11 | The coercion between `Box` to `&T` is not replicable by user-defined smart pointers and has been found to be rarely used [1]. We already removed the coercion between `Box` and `&mut T` in RFC 33. 12 | 13 | ## Detailed design 14 | 15 | The coercion between `Box` and `&T` should be removed. 16 | 17 | Note that methods that take `&self` can still be called on values of type `Box` without any special referencing or dereferencing. That is because the semantics of auto-deref and auto-ref conspire to make it work: the types unify after one autoderef followed by one autoref. 18 | 19 | ## Drawbacks 20 | 21 | Borrowing from `Box` to `&T` may be convenient. 22 | 23 | ## Alternatives 24 | 25 | The impact of not doing this is that the coercion will remain. 26 | 27 | ## Unresolved questions 28 | 29 | None. 30 | 31 | [1]: https://github.com/rust-lang/rust/pull/15171 32 | -------------------------------------------------------------------------------- /text/0342-keywords.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-10-07 2 | - RFC PR: [rust-lang/rfcs#342](https://github.com/rust-lang/rfcs/pull/342) 3 | - Rust Issue: [rust-lang/rust#17862](https://github.com/rust-lang/rust/issues/17862) 4 | 5 | ## Summary 6 | 7 | Reserve `abstract`, `final`, and `override` as possible keywords. 8 | 9 | ## Motivation 10 | 11 | We intend to add some mechanism to Rust to support more efficient inheritance 12 | (see, e.g., RFC PRs #245 and #250, and this 13 | [thread](http://discuss.rust-lang.org/t/summary-of-efficient-inheritance-rfcs/494/43) 14 | on discuss). Although we have not decided how to do this, we do know that we 15 | will. Any implementation is likely to make use of keywords `virtual` (already 16 | used, to remain reserved), `abstract`, `final`, and `override`, so it makes 17 | sense to reserve these now to make the eventual implementation as backwards 18 | compatible as possible. 19 | 20 | ## Detailed design 21 | 22 | Make `abstract`, `final`, and `override` reserved keywords. 23 | 24 | ## Drawbacks 25 | 26 | Takes a few more words out of the possible vocabulary of Rust programmers. 27 | 28 | ## Alternatives 29 | 30 | Don't do this and deal with it when we have an implementation. This would mean 31 | bumping the language version, probably. 32 | 33 | ## Unresolved questions 34 | 35 | N/A 36 | -------------------------------------------------------------------------------- /text/0050-assert.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-04-18 2 | - RFC PR: [rust-lang/rfcs#50](https://github.com/rust-lang/rfcs/pull/50) 3 | - Rust Issue: [rust-lang/rust#13789](https://github.com/rust-lang/rust/issues/13789) 4 | 5 | ## Summary 6 | 7 | Asserts are too expensive for release builds and mess up inlining. There must be a way to turn them off. I propose macros `debug_assert!` and `assert!`. For test cases, `assert!` should be used. 8 | 9 | ## Motivation 10 | 11 | Asserts are too expensive in release builds. 12 | 13 | ## Detailed design 14 | 15 | There should be two macros, `debug_assert!(EXPR)` and `assert!(EXPR)`. In debug builds (without `--cfg ndebug`), `debug_assert!()` is the same as `assert!()`. In release builds (with `--cfg ndebug`), `debug_assert!()` compiles away to nothing. The definition of `assert!()` is `if (!EXPR) { fail!("assertion failed ({}, {}): {}", file!(), line!(), stringify!(expr) }` 16 | 17 | ## Alternatives 18 | 19 | Other designs that have been considered are using `debug_assert!` in test cases and not providing `assert!`, but this doesn't work with separate compilation. 20 | 21 | The impact of not doing this is that `assert!` will be expensive, prompting people will write their own local `debug_assert!` macros, duplicating functionality that should have been in the standard library. 22 | 23 | ## Unresolved questions 24 | 25 | None. 26 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | env: 8 | # renovate: datasource=crate depName=mdbook versioning=semver 9 | MDBOOK_VERSION: 0.5.1 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 16 | with: 17 | fetch-depth: 0 18 | - name: Install mdbook 19 | run: | 20 | mkdir mdbook 21 | curl -Lf https://github.com/rust-lang/mdBook/releases/download/v${{ env.MDBOOK_VERSION }}/mdbook-v${{ env.MDBOOK_VERSION }}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook 22 | echo `pwd`/mdbook >> $GITHUB_PATH 23 | - name: Generate Book 24 | run: | 25 | ./generate-book.py 26 | - name: Upload Artifact 27 | uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 28 | with: 29 | path: ./book 30 | 31 | deploy: 32 | needs: build 33 | 34 | permissions: 35 | pages: write 36 | id-token: write 37 | 38 | environment: 39 | name: github-pages 40 | url: ${{ steps.deployment.outputs.page_url }} 41 | 42 | runs-on: ubuntu-latest 43 | steps: 44 | - id: deployment 45 | uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 46 | -------------------------------------------------------------------------------- /text/0123-share-to-threadsafe.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-06-15 2 | - RFC PR #: [rust-lang/rfcs#123](https://github.com/rust-lang/rfcs/pull/123) 3 | - Rust Issue #: [rust-lang/rust#16281](https://github.com/rust-lang/rust/issues/16281) 4 | 5 | ## Summary 6 | 7 | Rename the `Share` trait to `Sync` 8 | 9 | ## Motivation 10 | 11 | With interior mutability, the name "immutable pointer" for a value of type `&T` 12 | is not quite accurate. Instead, the term "shared reference" is becoming popular 13 | to reference values of type `&T`. The usage of the term "shared" is in conflict 14 | with the `Share` trait, which is intended for types which can be safely shared 15 | concurrently with a shared reference. 16 | 17 | ## Detailed design 18 | 19 | Rename the `Share` trait in `std::kinds` to `Sync`. Documentation would 20 | refer to `&T` as a shared reference and the notion of "shared" would simply mean 21 | "many references" while `Sync` implies that it is safe to share among many 22 | threads. 23 | 24 | ## Drawbacks 25 | 26 | The name `Sync` may invoke conceptions of "synchronized" from languages such as 27 | Java where locks are used, rather than meaning "safe to access in a shared 28 | fashion across tasks". 29 | 30 | ## Alternatives 31 | 32 | As any bikeshed, there are a number of other names which could be possible for 33 | this trait: 34 | 35 | * `Concurrent` 36 | * `Synchronized` 37 | * `Threadsafe` 38 | * `Parallel` 39 | * `Threaded` 40 | * `Atomic` 41 | * `DataRaceFree` 42 | * `ConcurrentlySharable` 43 | 44 | ## Unresolved questions 45 | 46 | None. 47 | -------------------------------------------------------------------------------- /text/0111-index-traits.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-06-09 2 | - RFC PR: [rust-lang/rfcs#111](https://github.com/rust-lang/rfcs/pull/111) 3 | - Rust Issue: [rust-lang/rust#6515](https://github.com/rust-lang/rust/issues/6515) 4 | 5 | ## Summary 6 | 7 | `Index` should be split into `Index` and `IndexMut`. 8 | 9 | ## Motivation 10 | 11 | Currently, the `Index` trait is not suitable for most array indexing tasks. The slice functionality cannot be replicated using it, and as a result the new `Vec` has to use `.get()` and `.get_mut()` methods. 12 | 13 | Additionally, this simply follows the `Deref`/`DerefMut` split that has been implemented for a while. 14 | 15 | ## Detailed design 16 | 17 | We split `Index` into two traits (borrowed from @nikomatsakis): 18 | 19 | // self[element] -- if used as rvalue, implicitly a deref of the result 20 | trait Index { 21 | fn index<'a>(&'a self, element: &E) -> &'a R; 22 | } 23 | 24 | // &mut self[element] -- when used as a mutable lvalue 25 | trait IndexMut { 26 | fn index_mut<'a>(&'a mut self, element: &E) -> &'a mut R; 27 | } 28 | 29 | ## Drawbacks 30 | 31 | * The number of lang. items increases. 32 | 33 | * This design doesn't support moving out of a vector-like object. This can be added backwards compatibly. 34 | 35 | * This design doesn't support hash tables because there is no assignment operator. This can be added backwards compatibly. 36 | 37 | ## Alternatives 38 | 39 | The impact of not doing this is that the `[]` notation will not be available to `Vec`. 40 | 41 | ## Unresolved questions 42 | 43 | None that I'm aware of. 44 | -------------------------------------------------------------------------------- /text/1119-result-expect.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `result_expect` 2 | - Start Date: 2015-05-13 3 | - RFC PR: [rust-lang/rfcs#1119](https://github.com/rust-lang/rfcs/pull/1119) 4 | - Rust Issue: [rust-lang/rust#25359](https://github.com/rust-lang/rust/pull/25359) 5 | 6 | ## Summary 7 | 8 | Add an `expect` method to the Result type, bounded to `E: Debug` 9 | 10 | ## Motivation 11 | 12 | While `Result::unwrap` exists, it does not allow annotating the panic message with the operation 13 | attempted (e.g. what file was being opened). This is at odds to 'Option' which includes both 14 | `unwrap` and `expect` (with the latter taking an arbitrary failure message). 15 | 16 | ## Detailed design 17 | 18 | Add a new method to the same `impl` block as `Result::unwrap` that takes a `&str` message and 19 | returns `T` if the `Result` was `Ok`. If the `Result` was `Err`, it panics with both the provided 20 | message and the error value. 21 | 22 | The format of the error message is left undefined in the documentation, but will most likely be 23 | the following 24 | 25 | ``` 26 | panic!("{}: {:?}", msg, e) 27 | ``` 28 | 29 | ## Drawbacks 30 | 31 | - It involves adding a new method to a core rust type. 32 | - The panic message format is less obvious than it is with `Option::expect` (where the panic message is the message passed) 33 | 34 | ## Alternatives 35 | 36 | - We are perfectly free to not do this. 37 | - A macro could be introduced to fill the same role (which would allow arbitrary formatting of the panic message). 38 | 39 | ## Unresolved questions 40 | 41 | Are there any issues with the proposed format of the panic string? 42 | -------------------------------------------------------------------------------- /text/0341-remove-virtual-structs.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-09-30 2 | - RFC PR: [rust-lang/rfcs#341](https://github.com/rust-lang/rfcs/pull/341) 3 | - Rust Issue: [rust-lang/rust#17861](https://github.com/rust-lang/rust/issues/17861) 4 | 5 | ## Summary 6 | 7 | Removes the "virtual struct" (aka struct inheritance) feature, which 8 | is currently feature gated. 9 | 10 | ## Motivation 11 | 12 | Virtual structs were added experimentally prior to the RFC process as 13 | a way of inheriting fields from one struct when defining a new struct. 14 | 15 | The feature was introduced and remains behind a feature gate. 16 | 17 | The motivations for removing this feature altogether are: 18 | 19 | 1. The feature is likely to be replaced by a more general mechanism, 20 | as part of the need to address hierarchies such as the DOM, ASTs, 21 | and so on. See 22 | [this post](http://discuss.rust-lang.org/t/summary-of-efficient-inheritance-rfcs/494/43) 23 | for some recent discussion. 24 | 25 | 2. The implementation is somewhat buggy and incomplete, and the 26 | feature is not well-documented. 27 | 28 | 3. Although it's behind a feature gate, keeping the feature around is 29 | still a maintenance burden. 30 | 31 | ## Detailed design 32 | 33 | Remove the implementation and feature gate for virtual structs. 34 | 35 | Retain the `virtual` keyword as reserved for possible future use. 36 | 37 | ## Drawbacks 38 | 39 | The language will no longer offer any built-in mechanism for avoiding 40 | repetition of struct fields. Macros offer a reasonable workaround 41 | until a more general mechanism is added. 42 | 43 | ## Unresolved questions 44 | 45 | None known. 46 | -------------------------------------------------------------------------------- /text/0164-feature-gate-slice-pats.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-07-14 2 | - RFC PR #: [rust-lang/rfcs#164](https://github.com/rust-lang/rfcs/pull/164) 3 | - Rust Issue #: [rust-lang/rust#16951](https://github.com/rust-lang/rust/issues/16951) 4 | 5 | ## Summary 6 | 7 | Rust's support for pattern matching on slices has grown steadily and incrementally without a lot of oversight. 8 | We have concern that Rust is doing too much here, and that the complexity is not worth it. This RFC proposes 9 | to feature gate multiple-element slice matches in the head and middle positions (`[xs.., 0, 0]` and `[0, xs.., 0]`). 10 | 11 | ## Motivation 12 | 13 | Some general reasons and one specific: first, the implementation of Rust's match machinery is notoriously complex, and not well-loved. Removing features is seen as a valid way to reduce complexity. Second, slice matching in particular, is difficult to implement, while also being of only moderate utility (there are many types of collections - slices just happen to be built into the language). Finally, the exhaustiveness check is not correct for slice patterns because of their complexity; it's not known if it 14 | can be done correctly, nor whether it is worth the effort to do so. 15 | 16 | ## Detailed design 17 | 18 | The `advanced_slice_patterns` feature gate will be added. When the compiler encounters slice pattern matches in head or middle position it will emit a warning or error according to the current settings. 19 | 20 | ## Drawbacks 21 | 22 | It removes two features that some people like. 23 | 24 | ## Alternatives 25 | 26 | Fixing the exhaustiveness check would allow the feature to remain. 27 | 28 | ## Unresolved questions 29 | 30 | N/A 31 | -------------------------------------------------------------------------------- /text/0168-mod.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-06-06 2 | - RFC PR: [rust-lang/rfcs#168](https://github.com/rust-lang/rfcs/pull/168) 3 | - Rust Issue: [rust-lang/rust#15722](https://github.com/rust-lang/rust/issues/15722) 4 | - Author: Tommit (edited by nrc) 5 | 6 | 7 | ## Summary 8 | 9 | Add syntax sugar for importing a module and items in that module in a single 10 | view item. 11 | 12 | 13 | ## Motivation 14 | 15 | Make use clauses more concise. 16 | 17 | 18 | ## Detailed design 19 | 20 | The `mod` keyword may be used in a braced list of modules in a `use` item to 21 | mean the prefix module for that list. For example, writing `prefix::{mod, 22 | foo};` is equivalent to writing 23 | 24 | ``` 25 | use prefix; 26 | use prefix::foo; 27 | ``` 28 | 29 | The `mod` keyword cannot be used outside of braces, nor can it be used inside 30 | braces which do not have a prefix path. Both of the following examples are 31 | illegal: 32 | 33 | ``` 34 | use module::mod; 35 | use {mod, foo}; 36 | ``` 37 | 38 | A programmer may write `mod` in a module list with only a single item. E.g., 39 | `use prefix::{mod};`, although this is considered poor style and may be forbidden 40 | by a lint. (The preferred version is `use prefix;`). 41 | 42 | 43 | ## Drawbacks 44 | 45 | Another use of the `mod` keyword. 46 | 47 | We introduce a way (the only way) to have paths in use items which do not 48 | correspond with paths which can be used in the program. For example, with `use 49 | foo::bar::{mod, baz};` the programmer can use `foo::bar::baz` in their program 50 | but not `foo::bar::mod` (instead `foo::bar` is imported). 51 | 52 | ## Alternatives 53 | 54 | Don't do this. 55 | 56 | 57 | ## Unresolved questions 58 | 59 | N/A 60 | -------------------------------------------------------------------------------- /text/0087-trait-bounds-with-plus.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-05-22 2 | - RFC PR: [rust-lang/rfcs#87](https://github.com/rust-lang/rfcs/pull/87) 3 | - Rust Issue: [rust-lang/rust#12778](https://github.com/rust-lang/rust/issues/12778) 4 | 5 | ## Summary 6 | 7 | Bounds on trait objects should be separated with `+`. 8 | 9 | ## Motivation 10 | 11 | With DST there is an ambiguity between the following two forms: 12 | 13 | trait X { 14 | fn f(foo: b); 15 | } 16 | 17 | 18 | and 19 | 20 | trait X { 21 | fn f(Trait: Share); 22 | } 23 | 24 | See Rust issue #12778 for details. 25 | 26 | Also, since kinds are now just built-in traits, it makes sense to treat a bounded trait object as just a combination of traits. This could be extended in the future to allow objects consisting of arbitrary trait combinations. 27 | 28 | ## Detailed design 29 | 30 | Instead of `:` in trait bounds for first-class traits (e.g. `&Trait:Share + Send`), we use `+` (e.g. `&Trait + Share + Send`). 31 | 32 | `+` will not be permitted in `as` without parentheses. This will be done via a special *restriction* in the type grammar: the special `TYPE` production following `as` will be the same as the regular `TYPE` production, with the exception that it does not accept `+` as a binary operator. 33 | 34 | ## Drawbacks 35 | 36 | * It may be that `+` is ugly. 37 | 38 | * Adding a restriction complicates the type grammar more than I would prefer, but the community backlash against the previous proposal was overwhelming. 39 | 40 | ## Alternatives 41 | 42 | The impact of not doing this is that the inconsistencies and ambiguities above remain. 43 | 44 | ## Unresolved questions 45 | 46 | Where does the `'static` bound fit into all this? 47 | -------------------------------------------------------------------------------- /text/1467-volatile.md: -------------------------------------------------------------------------------- 1 | - Feature Name: volatile 2 | - Start Date: 2016-01-18 3 | - RFC PR: [rust-lang/rfcs#1467](https://github.com/rust-lang/rfcs/pull/1467) 4 | - Rust Issue: [rust-lang/rust#31756](https://github.com/rust-lang/rust/issues/31756) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Stabilize the `volatile_load` and `volatile_store` intrinsics as `ptr::read_volatile` and `ptr::write_volatile`. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | This is necessary to allow volatile access to memory-mapping I/O in stable code. Currently this is only possible using unstable intrinsics, or by abusing a bug in the `load` and `store` functions on atomic types which gives them volatile semantics ([rust-lang/rust#30962](https://github.com/rust-lang/rust/pull/30962)). 15 | 16 | ## Detailed design 17 | [design]: #detailed-design 18 | 19 | `ptr::read_volatile` and `ptr::write_volatile` will work the same way as `ptr::read` and `ptr::write` respectively, except that the memory access will be done with volatile semantics. The semantics of a volatile access are already pretty well defined by the C standard and by LLVM. In documentation we can refer to http://llvm.org/docs/LangRef.html#volatile-memory-accesses. 20 | 21 | ## Drawbacks 22 | [drawbacks]: #drawbacks 23 | 24 | None. 25 | 26 | ## Alternatives 27 | [alternatives]: #alternatives 28 | 29 | We could also stabilize the `volatile_set_memory`, `volatile_copy_memory` and `volatile_copy_nonoverlapping_memory` intrinsics as `ptr::write_bytes_volatile`, `ptr::copy_volatile` and `ptr::copy_nonoverlapping_volatile`, but these are not as widely used and are not available in C. 30 | 31 | ## Unresolved questions 32 | [unresolved]: #unresolved-questions 33 | 34 | None. 35 | -------------------------------------------------------------------------------- /text/1260-main-reexport.md: -------------------------------------------------------------------------------- 1 | - Feature Name: main_reexport 2 | - Start Date: 2015-08-19 3 | - RFC PR: [rust-lang/rfcs#1260](https://github.com/rust-lang/rfcs/pull/1260) 4 | - Rust Issue: [rust-lang/rust#28937](https://github.com/rust-lang/rust/issues/28937) 5 | 6 | ## Summary 7 | 8 | Allow a re-export of a function as entry point `main`. 9 | 10 | ## Motivation 11 | 12 | Functions and re-exports of functions usually behave the same way, but they do 13 | not for the program entry point `main`. This RFC aims to fix this inconsistency. 14 | 15 | The above mentioned inconsistency means that e.g. you currently cannot use a 16 | library's exported function as your main function. 17 | 18 | Example: 19 | 20 | pub mod foo { 21 | pub fn bar() { 22 | println!("Hello world!"); 23 | } 24 | } 25 | use foo::bar as main; 26 | 27 | Example 2: 28 | 29 | extern crate main_functions; 30 | pub use main_functions::rmdir as main; 31 | 32 | See also https://github.com/rust-lang/rust/issues/27640 for the corresponding 33 | issue discussion. 34 | 35 | The `#[main]` attribute can also be used to change the entry point of the 36 | generated binary. This is largely irrelevant for this RFC as this RFC tries to 37 | fix an inconsistency with re-exports and directly defined functions. 38 | Nevertheless, it can be pointed out that the `#[main]` attribute does not cover 39 | all the above-mentioned use cases. 40 | 41 | ## Detailed design 42 | 43 | Use the symbol `main` at the top-level of a crate that is compiled as a program 44 | (`--crate-type=bin`) – instead of explicitly only accepting directly-defined 45 | functions, also allow (possibly non-`pub`) re-exports. 46 | 47 | ## Drawbacks 48 | 49 | None. 50 | 51 | ## Alternatives 52 | 53 | None. 54 | 55 | ## Unresolved questions 56 | 57 | None. 58 | -------------------------------------------------------------------------------- /triagebot.toml: -------------------------------------------------------------------------------- 1 | [relabel] 2 | allow-unauthenticated = [ 3 | "A-*", 4 | "T-*", 5 | "not-rfc", 6 | ] 7 | 8 | [rendered-link] 9 | trigger-files = ["text/"] 10 | 11 | [assign] 12 | 13 | [assign.owners] 14 | "/.github/" = ["internal-sites"] 15 | "/.gitattributes" = ["internal-sites"] 16 | "/.gitignore" = ["internal-sites"] 17 | "/book.toml" = ["internal-sites"] 18 | "/generate-book.py" = ["internal-sites"] 19 | "/LICENSE-APACHE" = ["internal-sites"] 20 | "/LICENSE-MIT" = ["internal-sites"] 21 | "/README.md" = ["internal-sites"] 22 | "/triagebot.toml" = ["internal-sites"] 23 | 24 | [shortcut] 25 | 26 | [range-diff] 27 | 28 | [notify-zulip."T-cargo"] 29 | zulip_stream = 246057 # t-cargo 30 | topic = "RFC #{number} - {title}" 31 | message_on_add = "A new T-cargo RFC has been opened: https://github.com/rust-lang/rfcs/pull/{number}" 32 | 33 | [notify-zulip."T-crates-io"] 34 | zulip_stream = 318791 # t-crates-io 35 | topic = "RFC #{number} - {title}" 36 | message_on_add = "A new T-crates-io RFC has been opened: https://github.com/rust-lang/rfcs/pull/{number}" 37 | 38 | [notify-zulip."I-types-nominated"] 39 | zulip_stream = 326866 # #T-types/nominated 40 | topic = "RFC #{number}: {title}" 41 | message_on_add = """\ 42 | @*T-types* RFC [{number}](https://github.com/rust-lang/rfcs/pull/{number}) "{title}" has been nominated for team discussion. 43 | """ 44 | message_on_remove = "RFC [{number}](https://github.com/rust-lang/rfcs/pull/{number})'s nomination has been removed. Thanks all for participating!" 45 | message_on_close = "RFC [{number}](https://github.com/rust-lang/rfcs/pull/{number}) has been closed. Thanks for participating!" 46 | message_on_reopen = "RFC [{number}](https://github.com/rust-lang/rfcs/pull/{number}) has been reopened. Pinging @*T-types*." 47 | -------------------------------------------------------------------------------- /text/0909-move-thread-local-to-std-thread.md: -------------------------------------------------------------------------------- 1 | - Feature Name: N/A 2 | - Start Date: 2015-02-25 3 | - RFC PR: [rust-lang/rfcs#909](https://github.com/rust-lang/rfcs/pull/909) 4 | - Rust Issue: [rust-lang/rust#23547](https://github.com/rust-lang/rust/issues/23547) 5 | 6 | ## Summary 7 | 8 | Move the contents of `std::thread_local` into `std::thread`. Fully 9 | remove `std::thread_local` from the standard library. 10 | 11 | ## Motivation 12 | 13 | Thread locals are directly related to threading. Combining the modules 14 | would reduce the number of top level modules, combine related concepts, 15 | and make browsing the docs easier. It also would have the potential to 16 | slightly reduce the number of `use` statements. 17 | 18 | ## Detailed design 19 | 20 | The contents of`std::thread_local` module would be moved into to 21 | `std::thread::local`. `Key` would be renamed to `LocalKey`, and 22 | `scoped` would also be flattened, providing `ScopedKey`, etc. This 23 | way, all thread related code is combined in one module. 24 | 25 | It would also allow using it as such: 26 | 27 | ```rust 28 | use std::thread::{LocalKey, Thread}; 29 | ``` 30 | 31 | ## Drawbacks 32 | 33 | It's pretty late in the 1.0 release cycle. This is a mostly bike 34 | shedding level of a change. It may not be worth changing it at this 35 | point and staying with two top level modules in `std`. Also, some users 36 | may prefer to have more top level modules. 37 | 38 | ## Alternatives 39 | 40 | An alternative (as the RFC originally proposed) would be to bring 41 | `thread_local` in as a submodule, rather than flattening. This was 42 | decided against in an effort to keep hierarchies flat, and because of 43 | the slim contents on the `thread_local` module. 44 | 45 | ## Unresolved questions 46 | 47 | The exact strategy for moving the contents into `std::thread` 48 | -------------------------------------------------------------------------------- /text/0469-feature-gate-box-patterns.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-11-17 2 | - RFC PR: [rust-lang/rfcs#469](https://github.com/rust-lang/rfcs/pull/469) 3 | - Rust Issue: [rust-lang/rust#21931](https://github.com/rust-lang/rust/issues/21931) 4 | 5 | ## Summary 6 | 7 | Move `box` patterns behind a feature gate. 8 | 9 | ## Motivation 10 | 11 | A recent RFC (https://github.com/rust-lang/rfcs/pull/462) proposed renaming `box` patterns to `deref`. The discussion that followed indicates that while the language community may be in favour of some sort of renaming, there is no significant consensus around any concrete proposal, including the original one or any that emerged from the discussion. 12 | 13 | This RFC proposes moving `box` patterns behind a feature gate to postpone that discussion and decision to when it becomes more clear how `box` patterns should interact with types other than `Box`. 14 | 15 | In addition, in the future `box` patterns are expected to be made more general by enabling them to destructure any type that implements one of the `Deref` family of traits. As such a generalisation may potentially lead to some currently valid programs being rejected due to the interaction with type inference or other language features, it is desirable that this particular feature stays feature gated until then. 16 | 17 | ## Detailed design 18 | 19 | A feature gate `box_patterns` will be defined and all uses of the `box` pattern will require said gate to be enabled. 20 | 21 | ## Drawbacks 22 | 23 | Some currently valid Rust programs will have to opt in to another feature gate. 24 | 25 | ## Alternatives 26 | 27 | Pursue https://github.com/rust-lang/rfcs/pull/462 before 1.0 and stabilise `box patterns` without a feature gate. 28 | 29 | Leave `box` patterns as-is without putting them behind a feature gate. 30 | 31 | ## Unresolved questions 32 | 33 | None. 34 | -------------------------------------------------------------------------------- /text/0593-forbid-Self-definitions.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-18 2 | - RFC PR: [rust-lang/rfcs#593](https://github.com/rust-lang/rfcs/pull/593) 3 | - Rust Issue: [rust-lang/rust#22137](https://github.com/rust-lang/rust/issues/22137) 4 | 5 | ## Summary 6 | 7 | Make `Self` a keyword. 8 | 9 | ## Motivation 10 | 11 | Right now, `Self` is just a regular identifier that happens to get a special meaning 12 | inside trait definitions and impls. Specifically, users are not forbidden from defining 13 | a type called `Self`, which can lead to weird situations: 14 | 15 | ```rust 16 | struct Self; 17 | 18 | struct Foo; 19 | 20 | impl Foo { 21 | fn foo(&self, _: Self) {} 22 | } 23 | ``` 24 | 25 | This piece of code defines types called `Self` and `Foo`, 26 | and a method `foo()` that because of the special meaning of `Self` has 27 | the signature `fn(&Foo, Foo)`. 28 | 29 | So in this case it is not possible to define a method on `Foo` that takes the 30 | actual type `Self` without renaming it or creating a renamed alias. 31 | 32 | It would also be highly unidiomatic to actually name the type `Self` 33 | for a custom type, precisely because of this ambiguity, so preventing it outright seems like the right thing to do. 34 | 35 | Making the identifier `Self` an keyword would prevent this situation because the user could not use it freely for custom definitions. 36 | 37 | ## Detailed design 38 | 39 | Make the identifier `Self` a keyword that is only legal to use inside a trait definition or impl to refer to the `Self` type. 40 | 41 | ## Drawbacks 42 | 43 | It might be unnecessary churn because people already don't run into this 44 | in practice. 45 | 46 | ## Alternatives 47 | 48 | Keep the status quo. It isn't a problem in practice, and just means 49 | `Self` is the special case of a contextual type definition in the language. 50 | 51 | ## Unresolved questions 52 | 53 | None so far 54 | -------------------------------------------------------------------------------- /text/0522-self-impl.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-12-13 2 | - RFC PR: [522](https://github.com/rust-lang/rfcs/pull/522) 3 | - Rust Issue: [20000](https://github.com/rust-lang/rust/issues/20000) 4 | 5 | ## Summary 6 | 7 | Allow `Self` type to be used in impls. 8 | 9 | ## Motivation 10 | 11 | Allows macros which operate on methods to do more, more easily without having to 12 | rebuild the concrete self type. Macros could use the literal self type like 13 | programmers do, but that requires extra machinery in the macro expansion code 14 | and extra work by the macro author. 15 | 16 | Allows easier copy and pasting of method signatures from trait declarations to 17 | implementations. 18 | 19 | Is more succinct where the self type is complex. 20 | 21 | ### Motivation for doing this now 22 | 23 | I'm hitting the macro problem in a side project. I wrote and hope to land the 24 | compiler code to make it work, but it is ugly and this is a much nicer solution. 25 | It is also really easy to implement, and since it is just a desugaring, it 26 | should not add any additional complexity to the compiler. Obviously, this should 27 | not block 1.0. 28 | 29 | ## Detailed design 30 | 31 | When used inside an impl, `Self` is desugared during syntactic expansion to the 32 | concrete type being implemented. `Self` can be used anywhere the desugared type 33 | could be used. 34 | 35 | ## Drawbacks 36 | 37 | There are some advantages to being explicit about the self type where it is 38 | possible - clarity and fewer type aliases. 39 | 40 | ## Alternatives 41 | 42 | We could just force authors to use the concrete type as we do currently. This 43 | would require macro expansion code to make available the concrete type (or the 44 | whole impl AST) to macros working on methods. The macro author would then 45 | extract/construct the self type and use it instead of `Self`. 46 | 47 | ## Unresolved questions 48 | 49 | None. 50 | -------------------------------------------------------------------------------- /text/0202-subslice-syntax-change.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-08-15 2 | - RFC PR: [rust-lang/rfcs#202](https://github.com/rust-lang/rfcs/pull/202) 3 | - Rust Issue: [rust-lang/rust#16967](https://github.com/rust-lang/rust/issues/16967) 4 | 5 | ## Summary 6 | 7 | Change syntax of subslices matching from `..xs` to `xs..` 8 | to be more consistent with the rest of the language 9 | and allow future backwards compatible improvements. 10 | 11 | Small example: 12 | 13 | ```rust 14 | match slice { 15 | [xs.., _] => xs, 16 | [] => fail!() 17 | } 18 | ``` 19 | 20 | This is basically heavily stripped version of [RFC 101](https://github.com/rust-lang/rfcs/pull/101). 21 | 22 | ## Motivation 23 | 24 | In Rust, symbol after `..` token usually describes number of things, 25 | as in `[T, ..N]` type or in `[e, ..N]` expression. 26 | But in following pattern: `[_, ..xs]`, `xs` doesn't describe any number, 27 | but the whole subslice. 28 | 29 | I propose to move dots to the right for several reasons (including one mentioned above): 30 | 31 | 1. Looks more natural (but that might be subjective). 32 | 2. Consistent with the rest of the language. 33 | 3. C++ uses `args...` in variadic templates. 34 | 4. It allows extending slice pattern matching as described in [RFC 101](https://github.com/rust-lang/rfcs/pull/101). 35 | 36 | ## Detailed design 37 | 38 | Slice matching grammar would change to (assuming trailing commas; 39 | grammar syntax as in Rust manual): 40 | 41 | slice_pattern : "[" [[pattern | subslice_pattern] ","]* "]" ; 42 | subslice_pattern : ["mut"? ident]? ".." ["@" slice_pattern]? ; 43 | 44 | To compare, currently it looks like: 45 | 46 | slice_pattern : "[" [[pattern | subslice_pattern] ","]* "]" ; 47 | subslice_pattern : ".." ["mut"? ident ["@" slice_pattern]?]? ; 48 | 49 | ## Drawbacks 50 | 51 | Backward incompatible. 52 | 53 | ## Alternatives 54 | 55 | Don't do it at all. 56 | 57 | ## Unresolved questions 58 | 59 | Whether subslice matching combined with `@` should be written as `xs.. @[1, 2]` 60 | or maybe in another way: `xs @[1, 2]..`. 61 | -------------------------------------------------------------------------------- /text/0601-replace-be-with-become.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-20 2 | - RFC PR: [rust-lang/rfcs#601](https://github.com/rust-lang/rfcs/pull/601) 3 | - Rust Issue: [rust-lang/rust#22141](https://github.com/rust-lang/rust/issues/22141) 4 | 5 | ## Summary 6 | 7 | Rename the `be` reserved keyword to `become`. 8 | 9 | ## Motivation 10 | 11 | A keyword needs to be reserved to support guaranteed tail calls in a backward-compatible way. Currently the keyword reserved for this purpose is `be`, but the `become` alternative was proposed in 12 | the old [RFC](https://github.com/rust-lang/rfcs/pull/81) for guaranteed tail calls, which is now postponed and tracked in [PR#271](https://github.com/rust-lang/rfcs/issues/271). 13 | 14 | Some advantages of the `become` keyword are: 15 | - it provides a clearer indication of its meaning ("this function becomes that function") 16 | - its syntax results in better code alignment (`become` is exactly as long as `return`) 17 | 18 | The expected result is that users will be unable to use `become` as identifier, ensuring that it will be available for future language extensions. 19 | 20 | This RFC is not about implementing tail call elimination, only on whether the `be` keyword should be replaced with `become`. 21 | 22 | ## Detailed design 23 | 24 | Rename the `be` reserved word to `become`. This is a very simple find-and-replace. 25 | 26 | ## Drawbacks 27 | 28 | Some code might be using `become` as an identifier. 29 | 30 | ## Alternatives 31 | 32 | The main alternative is to do nothing, i.e. to keep the `be` keyword reserved for supporting guaranteed tail calls in a backward-compatible way. Using `become` as the keyword for tail calls would not be backward-compatible because it would introduce a new keyword, which might have been used in valid code. 33 | 34 | Another option is to add the `become` keyword, without removing `be`. This would have the same drawbacks as the current proposal (might break existing code), but it would also guarantee that the `become` keyword is available in the future. 35 | 36 | ## Unresolved questions 37 | 38 | -------------------------------------------------------------------------------- /text/1590-macro-lifetimes.md: -------------------------------------------------------------------------------- 1 | - Feature Name: Allow `lifetime` specifiers to be passed to macros 2 | - Start Date: 2016-04-22 3 | - RFC PR: [rust-lang/rfcs#1590](https://github.com/rust-lang/rfcs/pull/1590) 4 | - Rust Issue: [rust-lang/rust#34303](https://github.com/rust-lang/rust/issues/34303) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Add a `lifetime` specifier for `macro_rules!` patterns, that matches any valid 10 | lifetime. 11 | 12 | ## Motivation 13 | [motivation]: #motivation 14 | 15 | Certain classes of macros are completely impossible without the ability to pass 16 | lifetimes. Specifically, anything that wants to implement a trait from inside of 17 | a macro is going to need to deal with lifetimes eventually. They're also 18 | commonly needed for any macros that need to deal with types in a more granular 19 | way than just `ty`. 20 | 21 | Since a lifetime is a single token, the only way to match against a lifetime is 22 | by capturing it as `tt`. Something like `'$lifetime:ident` would fail to 23 | compile. This is extremely limiting, as it becomes difficult to sanitize input, 24 | and `tt` is extremely difficult to use in a sequence without using awkward 25 | separators. 26 | 27 | ## Detailed design 28 | [design]: #detailed-design 29 | 30 | This RFC proposes adding `lifetime` as an additional specifier to 31 | `macro_rules!` (alternatively: `life` or `lt`). As it is a single token, it is 32 | able to be followed by any other specifier. Since a lifetime acts very much 33 | like an identifier, and can appear in almost as many places, it can be handled 34 | almost identically. 35 | 36 | A preliminary implementation can be found at 37 | https://github.com/rust-lang/rust/pull/33135 38 | 39 | ## Drawbacks 40 | [drawbacks]: #drawbacks 41 | 42 | None 43 | 44 | ## Alternatives 45 | [alternatives]: #alternatives 46 | 47 | A more general specifier, such as a "type parameter list", which would roughly 48 | map to `ast::Generics` would cover most of the cases that matching lifetimes 49 | individually would cover. 50 | 51 | ## Unresolved questions 52 | [unresolved]: #unresolved-questions 53 | 54 | None 55 | -------------------------------------------------------------------------------- /text/1030-prelude-additions.md: -------------------------------------------------------------------------------- 1 | - Feature Name: NA 2 | - Start Date: 2015-04-03 3 | - RFC PR: [rust-lang/rfcs#1030](https://github.com/rust-lang/rfcs/pull/1030) 4 | - Rust Issue: [rust-lang/rust#24538](https://github.com/rust-lang/rust/issues/24538) 5 | 6 | ## Summary 7 | 8 | Add `Default`, `IntoIterator` and `ToOwned` trait to the prelude. 9 | 10 | ## Motivation 11 | 12 | Each trait has a distinct motivation: 13 | 14 | * For `Default`, the ergonomics have vastly improved now that you can 15 | write `MyType::default()` (thanks to UFCS). Thanks to this 16 | improvement, it now makes more sense to promote widespread use of 17 | the trait. 18 | 19 | * For `IntoIterator`, promoting to the prelude will make it feasible 20 | to deprecate the inherent `into_iter` methods and directly-exported 21 | iterator types, in favor of the trait (which is currently redundant). 22 | 23 | * For `ToOwned`, promoting to the prelude would add a uniform, 24 | idiomatic way to acquire an owned copy of data (including going from 25 | `str` to `String`, for which `Clone` does not work). 26 | 27 | ## Detailed design 28 | 29 | * Add `Default`, `IntoIterator` and `ToOwned` trait to the prelude. 30 | 31 | * Deprecate inherent `into_iter` methods. 32 | 33 | * Ultimately deprecate module-level `IntoIter` types (e.g. in `vec`); 34 | this may want to wait until you can write `Vec::IntoIter` rather 35 | than ` as IntoIterator>::IntoIter`. 36 | 37 | ## Drawbacks 38 | 39 | The main downside is that prelude entries eat up some amount of 40 | namespace (particularly, method namespace). However, these are all 41 | important, core traits in `std`, meaning that the method names are 42 | already quite unlikely to be used. 43 | 44 | Strictly speaking, a prelude addition is a breaking change, but as 45 | above, this is highly unlikely to cause actual breakage. In any case, 46 | it can be landed prior to 1.0. 47 | 48 | ## Alternatives 49 | 50 | None. 51 | 52 | ## Unresolved questions 53 | 54 | The exact timeline of deprecation for `IntoIter` types. 55 | 56 | Are there other traits or types that should be promoted before 1.0? 57 | -------------------------------------------------------------------------------- /text/1219-use-group-as.md: -------------------------------------------------------------------------------- 1 | - Feature Name: use_group_as 2 | - Start Date: 2015-02-15 3 | - RFC PR: [rust-lang/rfcs#1219](https://github.com/rust-lang/rfcs/pull/1219) 4 | - Rust Issue: [rust-lang/rust#27578](https://github.com/rust-lang/rust/issues/27578) 5 | 6 | ## Summary 7 | 8 | Allow renaming imports when importing a group of symbols from a module. 9 | 10 | ```rust 11 | use std::io::{ 12 | Error as IoError, 13 | Result as IoResult, 14 | Read, 15 | Write 16 | } 17 | ``` 18 | 19 | ## Motivation 20 | 21 | The current design requires the above example to be written like this: 22 | 23 | ```rust 24 | use std::io::Error as IoError; 25 | use std::io::Result as IoResult; 26 | use std::io::{Read, Write}; 27 | ``` 28 | 29 | It's unfortunate to duplicate `use std::io::` on the 3 lines, and the proposed 30 | example feels logical, and something you reach for in this instance, without 31 | knowing for sure if it worked. 32 | 33 | ## Detailed design 34 | 35 | The current grammar for use statements is something like: 36 | 37 | ``` 38 | use_decl : "pub" ? "use" [ path "as" ident 39 | | path_glob ] ; 40 | 41 | path_glob : ident [ "::" [ path_glob 42 | | '*' ] ] ? 43 | | '{' path_item [ ',' path_item ] * '}' ; 44 | 45 | path_item : ident | "self" ; 46 | ``` 47 | 48 | This RFC proposes changing the grammar to something like: 49 | 50 | ``` 51 | use_decl : "pub" ? "use" [ path [ "as" ident ] ? 52 | | path_glob ] ; 53 | 54 | path_glob : ident [ "::" [ path_glob 55 | | '*' ] ] ? 56 | | '{' path_item [ ',' path_item ] * '}' ; 57 | 58 | path_item : ident [ "as" ident] ? 59 | | "self" [ "as" ident]; 60 | ``` 61 | 62 | The `"as" ident` part is optional in each location, and if omitted, it is expanded 63 | to alias to the same name, e.g. `use foo::{bar}` expands to `use foo::{bar as bar}`. 64 | 65 | This includes being able to rename `self`, such as `use std::io::{self 66 | as stdio, Result as IoResult};`. 67 | 68 | ## Drawbacks 69 | 70 | ## Alternatives 71 | 72 | ## Unresolved Questions 73 | -------------------------------------------------------------------------------- /text/0151-capture-by-value.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-07-02 2 | - RFC PR: [rust-lang/rfcs#151](https://github.com/rust-lang/rfcs/pull/151) 3 | - Rust Issue: [rust-lang/rust#12831](https://github.com/rust-lang/rust/issues/12831) 4 | 5 | ## Summary 6 | 7 | Closures should capture their upvars by value unless the `ref` keyword is used. 8 | 9 | ## Motivation 10 | 11 | For unboxed closures, we will need to syntactically distinguish between captures by value and captures by reference. 12 | 13 | ## Detailed design 14 | 15 | This is a small part of #114, split off to separate it from the rest of the discussion going on in that RFC. 16 | 17 | Closures should capture their upvars (closed-over variables) by value unless the `ref` keyword precedes the opening `|` of the argument list. Thus `|x| x + 2` will capture `x` by value (and thus, if `x` is not `Copy`, it will move `x` into the closure), but `ref |x| x + 2` will capture `x` by reference. 18 | 19 | In an unboxed-closures world, the immutability/mutability of the borrow (as the case may be) is inferred from the type of the closure: `Fn` captures by immutable reference, while `FnMut` captures by mutable reference. In a boxed-closures world, the borrows are always mutable. 20 | 21 | ## Drawbacks 22 | 23 | It may be that `ref` is unwanted complexity; it only changes the semantics of 10%-20% of closures, after all. This does not add any core functionality to the language, as a reference can always be made explicitly and then captured. However, there are a *lot* of closures, and the workaround to capture a reference by value is painful. 24 | 25 | ## Alternatives 26 | 27 | As above, the impact of not doing this is that reference semantics would have to be achieved. However, the diff against current Rust was thousands of lines of pretty ugly code. 28 | 29 | Another alternative would be to annotate each individual upvar with its capture semantics, like capture clauses in C++11. This proposal does not preclude adding that functionality should it be deemed useful in the future. Note that C++11 provides a syntax for capturing all upvars by reference, exactly as this proposal does. 30 | 31 | ## Unresolved questions 32 | 33 | None. 34 | -------------------------------------------------------------------------------- /lang_changes.md: -------------------------------------------------------------------------------- 1 | # RFC policy - language design 2 | 3 | Pretty much every change to the language needs an RFC. Note that new 4 | lints (or major changes to an existing lint) are considered changes to 5 | the language. 6 | 7 | Language RFCs are managed by the language sub-team, and tagged `T-lang`. The 8 | language sub-team will do an initial triage of new PRs within a week of 9 | submission. The result of triage will either be that the PR is assigned to a 10 | member of the sub-team for shepherding, the PR is closed as postponed because 11 | the subteam believe it might be a good idea, but is not currently aligned with 12 | Rust's priorities, or the PR is closed because the sub-team feel it should 13 | clearly not be done and further discussion is not necessary. In the latter two 14 | cases, the sub-team will give a detailed explanation. We'll follow the standard 15 | procedure for shepherding, final comment period, etc. 16 | 17 | 18 | ## Amendments 19 | 20 | Sometimes in the implementation of an RFC, changes are required. In general 21 | these don't require an RFC as long as they are very minor and in the spirit of 22 | the accepted RFC (essentially bug fixes). In this case implementers should 23 | submit an RFC PR which amends the accepted RFC with the new details. Although 24 | the RFC repository is not intended as a reference manual, it is preferred that 25 | RFCs do reflect what was actually implemented. Amendment RFCs will go through 26 | the same process as regular RFCs, but should be less controversial and thus 27 | should move more quickly. 28 | 29 | When a change is more dramatic, it is better to create a new RFC. The RFC should 30 | be standalone and reference the original, rather than modifying the existing 31 | RFC. You should add a comment to the original RFC with referencing the new RFC 32 | as part of the PR. 33 | 34 | Obviously there is some scope for judgment here. As a guideline, if a change 35 | affects more than one part of the RFC (i.e., is a non-local change), affects the 36 | applicability of the RFC to its motivating use cases, or there are multiple 37 | possible new solutions, then the feature is probably not 'minor' and should get 38 | a new RFC. 39 | -------------------------------------------------------------------------------- /text/1535-stable-overflow-checks.md: -------------------------------------------------------------------------------- 1 | - Feature Name: N/A 2 | - Start Date: 2016-03-09 3 | - RFC PR: [rust-lang/rfcs#1535](https://github.com/rust-lang/rfcs/pull/1535) 4 | - Rust Issue: [rust-lang/rust#33134](https://github.com/rust-lang/rust/issues/33134) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Stabilize the `-C overflow-checks` command line argument. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | This is an easy way to turn on overflow checks in release builds 15 | without otherwise turning on debug assertions, via the `-C 16 | debug-assertions` flag. In stable Rust today you can't get one without 17 | the other. 18 | 19 | Users can use the `-C overflow-checks` flag from their Cargo 20 | config to turn on overflow checks for an entire application. 21 | 22 | This flag, which accepts values of 'yes'/'no', 'on'/'off', is being 23 | renamed from `force-overflow-checks` because the `force` doesn't add 24 | anything that the 'yes'/'no' 25 | 26 | ## Detailed design 27 | [design]: #detailed-design 28 | 29 | This is a stabilization RFC. The only steps will be to move 30 | `force-overflow-checks` from `-Z` to `-C`, renaming it to 31 | `overflow-checks`, and making it stable. 32 | 33 | ## Drawbacks 34 | [drawbacks]: #drawbacks 35 | 36 | It's another rather ad-hoc flag for modifying code generation. 37 | 38 | Like other such flags, this applies to the entire code unit, 39 | regardless of monomorphizations. This means that code generation for a 40 | single function can be different based on which code unit it's 41 | instantiated in. 42 | 43 | ## Alternatives 44 | [alternatives]: #alternatives 45 | 46 | The flag could instead be tied to crates such that any time code from 47 | that crate is inlined/monomorphized it turns on overflow checks. 48 | 49 | We might also want a design that provides per-function control over 50 | overflow checks. 51 | 52 | ## Unresolved questions 53 | [unresolved]: #unresolved-questions 54 | 55 | Cargo might also add a profile option like 56 | 57 | ```toml 58 | [profile.dev] 59 | overflow-checks = true 60 | ``` 61 | 62 | This may also be accomplished by Cargo's pending support for passing 63 | arbitrary flags to rustc. 64 | 65 | -------------------------------------------------------------------------------- /text/0771-std-iter-once.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-30 2 | - RFC PR: [rust-lang/rfcs#771](https://github.com/rust-lang/rfcs/pull/771) 3 | - Rust Issue: [rust-lang/rust#24443](https://github.com/rust-lang/rust/issues/24443) 4 | 5 | ## Summary 6 | 7 | Add a `once` function to `std::iter` to construct an iterator yielding a given value one time, and an `empty` function to construct an iterator yielding no values. 8 | 9 | ## Motivation 10 | 11 | This is a common task when working with iterators. Currently, this can be done in many ways, most of which are unergonomic, do not work for all types (e.g. requiring Copy/Clone), or both. `once` and `empty` are simple to implement, simple to use, and simple to understand. 12 | 13 | ## Detailed design 14 | 15 | `once` will return a new struct, `std::iter::Once`, implementing `Iterator`. Internally, `Once` is simply a newtype wrapper around `std::option::IntoIter`. The actual body of `once` is thus trivial: 16 | 17 | ```rust 18 | pub struct Once(std::option::IntoIter); 19 | 20 | pub fn once(x: T) -> Once { 21 | Once( 22 | Some(x).into_iter() 23 | ) 24 | } 25 | ``` 26 | 27 | `empty` is similar: 28 | 29 | ```rust 30 | pub struct Empty(std::option::IntoIter); 31 | 32 | pub fn empty(x: T) -> Empty { 33 | Empty( 34 | None.into_iter() 35 | ) 36 | } 37 | ``` 38 | 39 | These wrapper structs exist to allow future backwards-compatible changes, and hide the implementation. 40 | 41 | ## Drawbacks 42 | 43 | Although a tiny amount of code, it still does come with a testing, maintenance, etc. cost. 44 | 45 | It's already possible to do this via `Some(x).into_iter()`, `std::iter::repeat(x).take(1)` (for `x: Clone`), `vec![x].into_iter()`, various contraptions involving `iterate`... 46 | 47 | The existence of the `Once` struct is not technically necessary. 48 | 49 | ## Alternatives 50 | 51 | There are already many, many alternatives to this- `Option::into_iter()`, `iterate`... 52 | 53 | The `Once` struct could be not used, with `std::option::IntoIter` used instead. 54 | 55 | ## Unresolved questions 56 | 57 | Naturally, `once` is fairly bikesheddable. `one_time`? `repeat_once`? 58 | 59 | Are versions of `once` that return `&T`/`&mut T` desirable? 60 | -------------------------------------------------------------------------------- /text/0532-self-in-use.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-12-19 2 | - RFC PR: [532](https://github.com/rust-lang/rfcs/pull/532) 3 | - Rust Issue: [20361](https://github.com/rust-lang/rust/issues/20361) 4 | 5 | ## Summary 6 | 7 | This RFC proposes the `mod` keyword used to refer 8 | the immediate parent namespace in `use` items (`use a::b::{mod, c}`) 9 | to be changed to `self`. 10 | 11 | ## Motivation 12 | 13 | While this looks fine: 14 | 15 | ````rust 16 | use a::b::{mod, c}; 17 | 18 | pub mod a { 19 | pub mod b { 20 | pub type c = (); 21 | } 22 | } 23 | ```` 24 | 25 | This looks strange, since we are not really importing a module: 26 | 27 | ````rust 28 | use Foo::{mod, Bar, Baz}; 29 | 30 | enum Foo { Bar, Baz } 31 | ```` 32 | 33 | RFC #168 was written when there was no namespaced `enum`, 34 | therefore the choice of the keyword was suboptimal. 35 | 36 | ## Detailed design 37 | 38 | This RFC simply proposes to use `self` in place of `mod`. 39 | This should amount to one line change to the parser, 40 | possibly with a renaming of relevant AST node (`PathListMod`). 41 | 42 | ## Drawbacks 43 | 44 | `self` is already used to denote a relative path in the `use` item. 45 | While they can be clearly distinguished 46 | (any use of `self` proposed in this RFC will appear inside braces), 47 | this can cause some confusion to beginners. 48 | 49 | ## Alternatives 50 | 51 | Don't do this. 52 | Simply accept that `mod` also acts as a general term for namespaces. 53 | 54 | Allow `enum` to be used in place of `mod` when the parent item is `enum`. 55 | This clearly expresses the intent and it doesn't reuse `self`. 56 | However, this is not very future-proof for several reasons. 57 | 58 | * Any item acting as a namespace would need a corresponding keyword. 59 | This is backward compatible but cumbersome. 60 | * If such namespace is not defined with an item but only implicitly, 61 | we may not have a suitable keyword to use. 62 | * We currently import all items sharing the same name (e.g. `struct P(Q);`), 63 | with no way of selectively importing one of them by the item type. 64 | An explicit item type in `use` will imply that we *can* selectively import, 65 | while we actually can't. 66 | 67 | ## Unresolved questions 68 | 69 | None. 70 | -------------------------------------------------------------------------------- /text/1660-try-borrow.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `try_borrow` 2 | - Start Date: 2016-06-27 3 | - RFC PR: [rust-lang/rfcs#1660](https://github.com/rust-lang/rfcs/pull/1660) 4 | - Rust Issue: [rust-lang/rust#35070](https://github.com/rust-lang/rust/issues/35070) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Introduce non-panicking borrow methods on `RefCell`. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | Whenever something is built from user input, for example a graph in which nodes 15 | are `RefCell` values, it is primordial to avoid panicking on bad input. The 16 | only way to avoid panics on cyclic input in this case is a way to 17 | conditionally-borrow the cell contents. 18 | 19 | ## Detailed design 20 | [design]: #detailed-design 21 | 22 | ```rust 23 | /// Returned when `RefCell::try_borrow` fails. 24 | pub struct BorrowError { _inner: () } 25 | 26 | /// Returned when `RefCell::try_borrow_mut` fails. 27 | pub struct BorrowMutError { _inner: () } 28 | 29 | impl RefCell { 30 | /// Tries to immutably borrows the value. This returns `Err(_)` if the cell 31 | /// was already borrowed mutably. 32 | pub fn try_borrow(&self) -> Result, BorrowError> { ... } 33 | 34 | /// Tries to mutably borrows the value. This returns `Err(_)` if the cell 35 | /// was already borrowed. 36 | pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { ... } 37 | } 38 | ``` 39 | 40 | ## Drawbacks 41 | [drawbacks]: #drawbacks 42 | 43 | This departs from the fallible/infallible convention where we avoid providing 44 | both panicking and non-panicking methods for the same operation. 45 | 46 | ## Alternatives 47 | [alternatives]: #alternatives 48 | 49 | The alternative is to provide a `borrow_state` method returning the state 50 | of the borrow flag of the cell, i.e: 51 | 52 | ```rust 53 | pub enum BorrowState { 54 | Reading, 55 | Writing, 56 | Unused, 57 | } 58 | 59 | impl RefCell { 60 | pub fn borrow_state(&self) -> BorrowState { ... } 61 | } 62 | ``` 63 | 64 | See [the Rust tracking issue](https://github.com/rust-lang/rust/issues/27733) 65 | for this feature. 66 | 67 | ## Unresolved questions 68 | [unresolved]: #unresolved-questions 69 | 70 | There are no unresolved questions. 71 | -------------------------------------------------------------------------------- /text/0531-define-rfc-scope.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-12-18 2 | - RFC PR: [531](https://github.com/rust-lang/rfcs/pull/531) 3 | - Rust Issue: n/a 4 | 5 | ## Summary 6 | 7 | According to current documents, the RFC process is required to make "substantial" changes to the Rust 8 | distribution. It is currently lightweight, but lacks a definition for the Rust distribution. This RFC 9 | aims to amend the process with a both broad and clear definition of "Rust distribution," while still 10 | keeping the process itself in tact. 11 | 12 | ## Motivation 13 | 14 | The motivation for this change comes from the recent decision for Crates.io to affirm its first come, 15 | first serve policy. While there was discussion of the matter on a GitHub issue, this discussion was 16 | rather low visibility. Regardless of the outcome of this particular decision, it highlights the 17 | fact that there is not a clear place for thorough discussion of policy decisions related to the 18 | outermost parts of Rust. 19 | 20 | ## Detailed design 21 | 22 | To remedy this issue, there must be a defined scope for the RFC process. This definition would be 23 | incorporated into the section titled "When you need to follow this process." The goal here is to be as 24 | explicit as possible. This RFC proposes that the scope of the RFC process be defined as follows: 25 | 26 | * Rust 27 | * Cargo 28 | * Crates.io 29 | * The RFC process itself 30 | 31 | This definition explicitly does not include: 32 | 33 | * Other crates maintained under the rust-lang organization, such as time. 34 | 35 | ## Drawbacks 36 | 37 | The only particular drawback would be if this definition is too narrow, it might be restrictive. 38 | However, this definition fortunately includes the ability to amend the RFC process. So, this 39 | could be expanded if the need exists. 40 | 41 | ## Alternatives 42 | 43 | The alternative is leaving the process as is. However, adding clarity at little to no cost should 44 | be preferred as it lowers the barrier to entry for contributions, and increases the visibility of 45 | potential changes that may have previously been discussed outside of an RFC. 46 | 47 | ## Unresolved questions 48 | 49 | Are there other things that should be explicitly included as part of the scope of the RFC process right now? 50 | -------------------------------------------------------------------------------- /text/0450-un-feature-gate-some-more-gates.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-12-02 2 | - RFC PR: [450](https://github.com/rust-lang/rfcs/pull/450) 3 | - Rust Issue: [19469](https://github.com/rust-lang/rust/issues/19469) 4 | 5 | ## Summary 6 | 7 | Remove the `tuple_indexing`, `if_let`, and `while_let` feature gates and add 8 | them to the language. 9 | 10 | ## Motivation 11 | 12 | ### Tuple Indexing 13 | 14 | This feature has proven to be quite useful for tuples and struct variants, and 15 | it allows for the removal of some unnecessary tuple accessing traits in the 16 | standard library (TupleN). 17 | 18 | The implementation has also proven to be quite solid with very few reported 19 | internal compiler errors related to this feature. 20 | 21 | ### `if let` and `while let` 22 | 23 | This feature has also proven to be quite useful over time. Many projects are now 24 | leveraging these feature gates which is a testament to their usefulness. 25 | 26 | Additionally, the implementation has also proven to be quite solid with very 27 | few reported internal compiler errors related to this feature. 28 | 29 | ## Detailed design 30 | 31 | * Remove the `if_let`, `while_let`, and `tuple_indexing` feature gates. 32 | * Add these features to the language (do not require a feature gate to use them). 33 | * Deprecate the `TupleN` traits in `std::tuple`. 34 | 35 | ## Drawbacks 36 | 37 | Adding features to the language this late in the game is always somewhat of a 38 | risky business. These features, while having baked for a few weeks, haven't had 39 | much time to bake in the grand scheme of the language. These are both backwards 40 | compatible to accept, and it could be argued that this could be done later 41 | rather than sooner. 42 | 43 | In general, the major drawbacks of this RFC are the scheduling risks and 44 | "feature bloat" worries. This RFC, however, is quite easy to implement (reducing 45 | schedule risk) and concerns two fairly minor features which are unambiguously 46 | nice to have. 47 | 48 | ## Alternatives 49 | 50 | * Instead of un-feature-gating before 1.0, these features could be released 51 | after 1.0 (if at all). The `TupleN` traits would then be required to be 52 | deprecated for the entire 1.0 release cycle. 53 | 54 | ## Unresolved questions 55 | 56 | None at the moment. 57 | -------------------------------------------------------------------------------- /text/1419-slice-copy.md: -------------------------------------------------------------------------------- 1 | - Feature Name: slice\_copy\_from 2 | - Start Date: 2015-12-20 3 | - RFC PR: [rust-lang/rfcs#1419](https://github.com/rust-lang/rfcs/pull/1419) 4 | - Rust Issue: [rust-lang/rust#31755](https://github.com/rust-lang/rust/issues/31755) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Safe `memcpy` from one slice to another of the same type and length. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | Currently, the only way to quickly copy from one non-`u8` slice to another is to 15 | use a loop, or unsafe methods like `std::ptr::copy_nonoverlapping`. This allows 16 | us to guarantee a `memcpy` for `Copy` types, and is safe. 17 | 18 | ## Detailed design 19 | [design]: #detailed-design 20 | 21 | Add one method to Primitive Type `slice`. 22 | 23 | ```rust 24 | impl [T] where T: Copy { 25 | pub fn copy_from_slice(&mut self, src: &[T]); 26 | } 27 | ``` 28 | 29 | `copy_from_slice` asserts that `src.len() == self.len()`, then `memcpy`s the 30 | members into `self` from `src`. Calling `copy_from_slice` is semantically 31 | equivalent to a `memcpy`. `self` shall have exactly the same members as `src` 32 | after a call to `copy_from_slice`. 33 | 34 | ## Drawbacks 35 | [drawbacks]: #drawbacks 36 | 37 | One new method on `slice`. 38 | 39 | ## Alternatives 40 | [alternatives]: #alternatives 41 | 42 | `copy_from_slice` could be called `copy_to`, and have the order of the arguments 43 | switched around. This would follow `ptr::copy_nonoverlapping` ordering, and not 44 | `dst = src` or `.clone_from_slice()` ordering. 45 | 46 | `copy_from_slice` could panic only if `dst.len() < src.len()`. This would be the 47 | same as what came before, but we would also lose the guarantee that an 48 | uninitialized slice would be fully initialized. 49 | 50 | `copy_from_slice` could be a free function, as it was in the original draft of 51 | this document. However, there was overwhelming support for it as a method. 52 | 53 | `copy_from_slice` could be not merged, and `clone_from_slice` could be 54 | specialized to `memcpy` in cases of `T: Copy`. I think it's good to have a 55 | specific function to do this, however, which asserts that `T: Copy`. 56 | 57 | ## Unresolved questions 58 | [unresolved]: #unresolved-questions 59 | 60 | None, as far as I can tell. 61 | -------------------------------------------------------------------------------- /text/1653-assert_ne.md: -------------------------------------------------------------------------------- 1 | - Feature Name: Assert Not Equals Macro (`assert_ne`) 2 | - Start Date: (2016-06-17) 3 | - RFC PR: [rust-lang/rfcs#1653](https://github.com/rust-lang/rfcs/pull/1653) 4 | - Rust Issue: [rust-lang/rust#35073](https://github.com/rust-lang/rust/issues/35073) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | `assert_ne` is a macro that takes 2 arguments and panics if they are equal. It 10 | works and is implemented identically to `assert_eq` and serves as its complement. 11 | This proposal also includes a `debug_asset_ne`, matching `debug_assert_eq`. 12 | 13 | ## Motivation 14 | [motivation]: #motivation 15 | 16 | This feature, among other reasons, makes testing more readable and consistent as 17 | it complements `asset_eq`. It gives the same style panic message as `assert_eq`, 18 | which eliminates the need to write it yourself. 19 | 20 | ## Detailed design 21 | [design]: #detailed-design 22 | 23 | This feature has exactly the same design and implementation as `assert_eq`. 24 | 25 | Here is the definition: 26 | 27 | ```rust 28 | macro_rules! assert_ne { 29 | ($left:expr , $right:expr) => ({ 30 | match (&$left, &$right) { 31 | (left_val, right_val) => { 32 | if *left_val == *right_val { 33 | panic!("assertion failed: `(left != right)` \ 34 | (left: `{:?}`, right: `{:?}`)", left_val, right_val) 35 | } 36 | } 37 | } 38 | }) 39 | } 40 | ``` 41 | 42 | This is complemented by a `debug_assert_ne` (similar to `debug_assert_eq`): 43 | 44 | ```rust 45 | macro_rules! debug_assert_ne { 46 | ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); }) 47 | } 48 | ``` 49 | 50 | ## Drawbacks 51 | [drawbacks]: #drawbacks 52 | 53 | Any addition to the standard library will need to be maintained forever, so it is 54 | worth weighing the maintenance cost of this over the value add. Given that it is so 55 | similar to `assert_eq`, I believe the weight of this drawback is low. 56 | 57 | ## Alternatives 58 | [alternatives]: #alternatives 59 | 60 | Alternatively, users implement this feature themselves, or use the crate `assert_ne` 61 | that I published. 62 | 63 | ## Unresolved questions 64 | [unresolved]: #unresolved-questions 65 | 66 | None at this moment. 67 | -------------------------------------------------------------------------------- /text/0066-better-temporary-lifetimes.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-05-04 2 | - RFC PR: [rust-lang/rfcs#66](https://github.com/rust-lang/rfcs/pull/66) 3 | - Rust Issue: [rust-lang/rust#15023](https://github.com/rust-lang/rust/issues/15023) 4 | 5 | ## Summary 6 | 7 | Temporaries live for the enclosing block when found in a let-binding. This only 8 | holds when the reference to the temporary is taken directly. This logic should 9 | be extended to extend the cleanup scope of any temporary whose lifetime ends up 10 | in the let-binding. 11 | 12 | For example, the following doesn't work now, but should: 13 | 14 | ```rust 15 | use std::os; 16 | 17 | fn main() { 18 | let x = os::args().slice_from(1); 19 | println!("{}", x); 20 | } 21 | ``` 22 | 23 | ## Motivation 24 | 25 | Temporary lifetimes are a bit confusing right now. Sometimes you can keep 26 | references to them, and sometimes you get the dreaded "borrowed value does not 27 | live long enough" error. Sometimes one operation works but an equivalent 28 | operation errors, e.g. autoref of `~[T]` to `&[T]` works but calling 29 | `.as_slice()` doesn't. In general it feels as though the compiler is simply 30 | being overly restrictive when it decides the temporary doesn't live long 31 | enough. 32 | 33 | ## Drawbacks 34 | 35 | I can't think of any drawbacks. 36 | 37 | ## Detailed design 38 | 39 | When a reference to a temporary is passed to a function (either as a regular 40 | argument or as the `self` argument of a method), and the function returns a 41 | value with the same lifetime as the temporary reference, the lifetime of the 42 | temporary should be extended the same way it would if the function was not 43 | invoked. 44 | 45 | For example, `~[T].as_slice()` takes `&'a self` and returns `&'a [T]`. Calling 46 | `as_slice()` on a temporary of type `~[T]` will implicitly take a reference 47 | `&'a ~[T]` and return a value `&'a [T]` This return value should be considered 48 | to extend the lifetime of the `~[T]` temporary just as taking an explicit 49 | reference (and skipping the method call) would. 50 | 51 | ## Alternatives 52 | 53 | Don't do this. We live with the surprising borrowck errors and the ugly workarounds that look like 54 | 55 | ```rust 56 | let x = os::args(); 57 | let x = x.slice_from(1); 58 | ``` 59 | 60 | ## Unresolved questions 61 | 62 | None that I know of. 63 | -------------------------------------------------------------------------------- /text/1548-global-asm.md: -------------------------------------------------------------------------------- 1 | - Feature Name: global_asm 2 | - Start Date: 2016-03-18 3 | - RFC PR: [rust-lang/rfcs#1548](https://github.com/rust-lang/rfcs/pull/1548) 4 | - Rust Issue: [rust-lang/rust#35119](https://github.com/rust-lang/rust/issues/35119) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | This RFC exposes LLVM's support for [module-level inline assembly](http://llvm.org/docs/LangRef.html#module-level-inline-assembly) by adding a `global_asm!` macro. The syntax is very simple: it just takes a string literal containing the assembly code. 10 | 11 | Example: 12 | ```rust 13 | global_asm!(r#" 14 | .globl my_asm_func 15 | my_asm_func: 16 | ret 17 | "#); 18 | 19 | extern { 20 | fn my_asm_func(); 21 | } 22 | ``` 23 | 24 | ## Motivation 25 | [motivation]: #motivation 26 | 27 | There are two main use cases for this feature. The first is that it allows functions to be written completely in assembly, which mostly eliminates the need for a `naked` attribute. This is mainly useful for function that use a custom calling convention, such as interrupt handlers. 28 | 29 | Another important use case is that it allows external assembly files to be used in a Rust module without needing hacks in the build system: 30 | 31 | ```rust 32 | global_asm!(include_str!("my_asm_file.s")); 33 | ``` 34 | 35 | Assembly files can also be preprocessed or generated by `build.rs` (for example using the C preprocessor), which will produce output files in the Cargo output directory: 36 | 37 | ```rust 38 | global_asm!(include_str!(concat!(env!("OUT_DIR"), "/preprocessed_asm.s"))); 39 | ``` 40 | 41 | ## Detailed design 42 | [design]: #detailed-design 43 | 44 | See description above, not much to add. The macro will map directly to LLVM's `module asm`. 45 | 46 | ## Drawbacks 47 | [drawbacks]: #drawbacks 48 | 49 | Like `asm!`, this feature depends on LLVM's integrated assembler. 50 | 51 | ## Alternatives 52 | [alternatives]: #alternatives 53 | 54 | The current way of including external assembly is to compile the assembly files using gcc in `build.rs` and link them into the Rust program as a static library. 55 | 56 | An alternative for functions written entirely in assembly is to add a [`#[naked]` function attribute](https://github.com/rust-lang/rfcs/pull/1201). 57 | 58 | ## Unresolved questions 59 | [unresolved]: #unresolved-questions 60 | 61 | None 62 | -------------------------------------------------------------------------------- /text/0234-variants-namespace.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-09-16 2 | - RFC PR #: https://github.com/rust-lang/rfcs/pull/234 3 | - Rust Issue #: https://github.com/rust-lang/rust/issues/17323 4 | 5 | ## Summary 6 | 7 | Make enum variants part of both the type and value namespaces. 8 | 9 | ## Motivation 10 | 11 | We might, post-1.0, want to allow using enum variants as types. This would be 12 | backwards incompatible, because if a module already has a value with the same name 13 | as the variant in scope, then there will be a name clash. 14 | 15 | ## Detailed design 16 | 17 | Enum variants would always be part of both the type and value namespaces. 18 | Variants would not, however, be usable as types - we might want to allow this 19 | later, but it is out of scope for this RFC. 20 | 21 | ### Data 22 | 23 | Occurrences of name clashes in the Rust repo: 24 | 25 | * `Key` in `rustrt::local_data` 26 | 27 | * `InAddr` in `native::io::net` 28 | 29 | * `Ast` in `regex::parse` 30 | 31 | * `Class` in `regex::parse` 32 | 33 | * `Native` in `regex::re` 34 | 35 | * `Dynamic` in `regex::re` 36 | 37 | * `Zero` in `num::bigint` 38 | 39 | * `String` in `term::terminfo::parm` 40 | 41 | * `String` in `serialize::json` 42 | 43 | * `List` in `serialize::json` 44 | 45 | * `Object` in `serialize::json` 46 | 47 | * `Argument` in `fmt_macros` 48 | 49 | * `Metadata` in `rustc_llvm` 50 | 51 | * `ObjectFile` in `rustc_llvm` 52 | 53 | * 'ItemDecorator' in `syntax::ext::base` 54 | 55 | * 'ItemModifier' in `syntax::ext::base` 56 | 57 | * `FunctionDebugContext` in `rustc::middle::trans::debuginfo` 58 | 59 | * `AutoDerefRef` in `rustc::middle::ty` 60 | 61 | * `MethodParam` in `rustc::middle::typeck` 62 | 63 | * `MethodObject` in `rustc::middle::typeck` 64 | 65 | That's a total of 20 in the compiler and libraries. 66 | 67 | 68 | ## Drawbacks 69 | 70 | Prevents the common-ish idiom of having a struct with the same name as a variant 71 | and then having a value of that struct be the variant's data. 72 | 73 | ## Alternatives 74 | 75 | Don't do it. That would prevent us making changes to the typed-ness of enums in 76 | the future. If we accept this RFC, but at some point we decide we never want to 77 | do anything with enum variants and types, we could always roll back this change 78 | backwards compatibly. 79 | 80 | ## Unresolved questions 81 | 82 | N/A 83 | -------------------------------------------------------------------------------- /text/0968-closure-return-type-syntax.md: -------------------------------------------------------------------------------- 1 | - Feature Name: N/A 2 | - Start Date: 2015-03-16 3 | - RFC PR: [rust-lang/rfcs#968](https://github.com/rust-lang/rfcs/pull/968) 4 | - Rust Issue: [rust-lang/rust#23420](https://github.com/rust-lang/rust/issues/23420) 5 | 6 | ## Summary 7 | 8 | Restrict closure return type syntax for future compatibility. 9 | 10 | ## Motivation 11 | 12 | Today's closure return type syntax juxtaposes a type and an 13 | expression. This is dangerous: if we choose to extend the type grammar 14 | to be more acceptable, we can easily break existing code. 15 | 16 | ## Detailed design 17 | 18 | The current closure syntax for annotating the return type is `|Args| 19 | -> Type Expr`, where `Type` is the return type and `Expr` is the body 20 | of the closure. This syntax is future hostile and relies on being able 21 | to determine the end point of a type. If we extend the syntax for 22 | types, we could cause parse errors in existing code. 23 | 24 | An example from history is that we extended the type grammar to 25 | include things like `Fn(..)`. This would have caused the following, 26 | previous, legal -- closure not to parse: `|| -> Foo (Foo)`. As a 27 | simple fix, this RFC proposes that if a return type annotation is 28 | supplied, the body must be enclosed in braces: `|| -> Foo { (Foo) }`. 29 | Types are already juxtaposed with open braces in `fn` items, so this 30 | should not be an additional danger for future evolution. 31 | 32 | ## Drawbacks 33 | 34 | This design is minimally invasive but perhaps unfortunate in that it's 35 | not obvious that braces would be required. But then, return type 36 | annotations are very rarely used. 37 | 38 | ## Alternatives 39 | 40 | I am not aware of any alternate designs. One possibility would be to 41 | remove return type annotations altogether, perhaps relying on type 42 | ascription or other annotations to force the inferencer to figure 43 | things out, but they are useful in rare scenarios. In particular type 44 | ascription would not be able to handle a higher-ranked signature like 45 | `for<'a> &'a X -> &'a Y` without improving the type checker 46 | implementation in other ways (in particular, we don't infer 47 | generalization over lifetimes at present, unless we can figure it out 48 | from the expected type or explicit annotations). 49 | 50 | ## Unresolved questions 51 | 52 | None. 53 | -------------------------------------------------------------------------------- /text/1135-raw-pointer-comparisons.md: -------------------------------------------------------------------------------- 1 | - Feature Name: raw-pointer-comparisons 2 | - Start Date: 2015-05-27 3 | - RFC PR: [rust-lang/rfcs#1135](https://github.com/rust-lang/rfcs/pull/1135) 4 | - Rust Issue: [rust-lang/rust#28235](https://github.com/rust-lang/rust/issues/28236) 5 | 6 | ## Summary 7 | 8 | Allow equality, but not order, comparisons between fat raw pointers 9 | of the same type. 10 | 11 | ## Motivation 12 | 13 | Currently, fat raw pointers can't be compared via either PartialEq or 14 | PartialOrd (currently this causes an ICE). It seems to me that a primitive 15 | type like a fat raw pointer should implement equality in some way. 16 | 17 | However, there doesn't seem to be a sensible way to order raw fat pointers 18 | unless we take vtable addresses into account, which is relatively weird. 19 | 20 | ## Detailed design 21 | 22 | Implement PartialEq/Eq for fat raw pointers, defined as comparing both the 23 | unsize-info and the address. This means that these are true: 24 | 25 | ```Rust 26 | &s as &fmt::Debug as *const _ == &s as &fmt::Debug as *const _ // of course 27 | &s.first_field as &fmt::Debug as *const _ 28 | != &s as &fmt::Debug as *const _ // these are *different* (one 29 | // prints only the first field, 30 | // the other prints all fields). 31 | ``` 32 | 33 | But 34 | ```Rust 35 | &s.first_field as &fmt::Debug as *const _ as *const () == 36 | &s as &fmt::Debug as *const _ as *const () // addresses are equal 37 | ``` 38 | 39 | ## Drawbacks 40 | 41 | Order comparisons may be useful for putting fat raw pointers into 42 | ordering-based data structures (e.g. BinaryTree). 43 | 44 | ## Alternatives 45 | 46 | @nrc suggested to implement heterogeneous comparisons between all thin 47 | raw pointers and all fat raw pointers. I don't like this because equality 48 | between fat raw pointers of different traits is false most of the 49 | time (unless one of the traits is a supertrait of the other and/or the 50 | only difference is in free lifetimes), and anyway you can always compare 51 | by casting both pointers to a common type. 52 | 53 | It is also possible to implement ordering too, either in unsize -> addr 54 | lexicographic order or addr -> unsize lexicographic order. 55 | 56 | ## Unresolved questions 57 | 58 | What form of ordering should be adopted, if any? 59 | 60 | 61 | -------------------------------------------------------------------------------- /text/1300-intrinsic-semantics.md: -------------------------------------------------------------------------------- 1 | - Feature Name: intrinsic-semantics 2 | - Start Date: 2015-09-29 3 | - RFC PR: [rust-lang/rfcs#1300](https://github.com/rust-lang/rfcs/pull/1300) 4 | - Rust Issue: N/A 5 | 6 | ## Summary 7 | 8 | Define the general semantics of intrinsic functions. This does not define the semantics of the 9 | individual intrinsics, instead defines the semantics around intrinsic functions in general. 10 | 11 | ## Motivation 12 | 13 | Intrinsics are currently poorly-specified in terms of how they function. This means they are a 14 | cause of ICEs and general confusion. The poor specification of them also means discussion affecting 15 | intrinsics gets mired in opinions about what intrinsics should be like and how they should act or 16 | be implemented. 17 | 18 | ## Detailed design 19 | 20 | Intrinsics are currently implemented by generating the code for the intrinsic at the call 21 | site. This allows for intrinsics to be implemented much more efficiently in many cases. For 22 | example, `transmute` is able to evaluate the input expression directly into the storage for the 23 | result, removing a potential copy. This is the main idea of intrinsics, a way to generate code that 24 | is otherwise inexpressible in Rust. 25 | 26 | Keeping this in-place behaviour is desirable, so this RFC proposes that intrinsics should only be 27 | usable as functions when called. This is not a change from the current behaviour, as you already 28 | cannot use intrinsics as function pointers. Using an intrinsic in any way other than directly 29 | calling should be considered an error. 30 | 31 | Intrinsics should continue to be defined and declared the same way. The `rust-intrinsic` and 32 | `platform-intrinsic` ABIs indicate that the function is an intrinsic function. 33 | 34 | ## Drawbacks 35 | 36 | * Fewer bikesheds to paint. 37 | * Doesn't allow intrinsics to be used as regular functions. (Note that this is not something we 38 | have evidence to suggest is a desired property, as it is currently the case anyway) 39 | 40 | ## Alternatives 41 | 42 | * Allow coercion to regular functions and generate wrappers. This is similar to how we handle named 43 | tuple constructors. Doing this undermines the idea of intrinsics as a way of getting the compiler 44 | to generate specific code at the call-site however. 45 | * Do nothing. 46 | 47 | ## Unresolved questions 48 | 49 | None. 50 | -------------------------------------------------------------------------------- /text/1725-unaligned-access.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `unaligned_access` 2 | - Start Date: 2016-08-22 3 | - RFC PR: [rust-lang/rfcs#1725](https://github.com/rust-lang/rfcs/pull/1725) 4 | - Rust Issue: [rust-lang/rust#37955](https://github.com/rust-lang/rust/issues/37955) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Add two functions, `ptr::read_unaligned` and `ptr::write_unaligned`, which allows reading/writing to an unaligned pointer. All other functions that access memory (`ptr::{read,write}`, `ptr::copy{_nonoverlapping}`, etc) require that a pointer be suitably aligned for its type. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | One major use case is to make working with packed structs easier: 15 | 16 | ```rust 17 | #[repr(packed)] 18 | struct Packed(u8, u16, u8); 19 | 20 | let mut a = Packed(0, 1, 0); 21 | unsafe { 22 | let b = ptr::read_unaligned(&a.1); 23 | ptr::write_unaligned(&mut a.1, b + 1); 24 | } 25 | ``` 26 | 27 | Other use cases generally involve parsing some file formats or network protocols that use unaligned values. 28 | 29 | ## Detailed design 30 | [design]: #detailed-design 31 | 32 | The implementation of these functions are simple wrappers around `ptr::copy_nonoverlapping`. The pointers are cast to `u8` to ensure that LLVM does not make any assumptions about the alignment. 33 | 34 | ```rust 35 | pub unsafe fn read_unaligned(p: *const T) -> T { 36 | let mut r = mem::uninitialized(); 37 | ptr::copy_nonoverlapping(p as *const u8, 38 | &mut r as *mut _ as *mut u8, 39 | mem::size_of::()); 40 | r 41 | } 42 | 43 | pub unsafe fn write_unaligned(p: *mut T, v: T) { 44 | ptr::copy_nonoverlapping(&v as *const _ as *const u8, 45 | p as *mut u8, 46 | mem::size_of::()); 47 | } 48 | ``` 49 | 50 | ## Drawbacks 51 | [drawbacks]: #drawbacks 52 | 53 | There functions aren't *strictly* necessary since they are just convenience wrappers around `ptr::copy_nonoverlapping`. 54 | 55 | ## Alternatives 56 | [alternatives]: #alternatives 57 | 58 | We could simply not add these, however figuring out how to do unaligned access properly is extremely unintuitive: you need to cast the pointer to `*mut u8` and then call `ptr::copy_nonoverlapping`. 59 | 60 | ## Unresolved questions 61 | [unresolved]: #unresolved-questions 62 | 63 | None 64 | -------------------------------------------------------------------------------- /text/1695-add-error-macro.md: -------------------------------------------------------------------------------- 1 | - Feature Name: compile\_error\_macro 2 | - Start Date: 2016-08-01 3 | - RFC PR: [rust-lang/rfcs#1695](https://github.com/rust-lang/rfcs/pull/1695) 4 | - Rust Issue: [rust-lang/rust#40872](https://github.com/rust-lang/rust/issues/40872) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | This RFC proposes adding a new macro to `libcore`, `compile_error!` which will 10 | unconditionally cause compilation to fail with the given error message when 11 | encountered. 12 | 13 | ## Motivation 14 | [motivation]: #motivation 15 | 16 | Crates which work with macros or annotations such as `cfg` have no tools to 17 | communicate error cases in a meaningful way on stable. For example, given the 18 | following macro: 19 | 20 | ```rust 21 | macro_rules! give_me_foo_or_bar { 22 | (foo) => {}; 23 | (bar) => {}; 24 | } 25 | ``` 26 | 27 | when invoked with `baz`, the error message will be `error: no rules expected the 28 | token baz`. In a real world scenario, this error may actually occur deep in a 29 | stack of macro calls, with an even more confusing error message. With this RFC, 30 | the macro author could provide the following: 31 | 32 | ```rust 33 | macro_rules! give_me_foo_or_bar { 34 | (foo) => {}; 35 | (bar) => {}; 36 | ($x:ident) => { 37 | compile_error!("This macro only accepts `foo` or `bar`"); 38 | } 39 | } 40 | ``` 41 | 42 | When combined with attributes, this also provides a way for authors to validate 43 | combinations of features. 44 | 45 | ```rust 46 | #[cfg(not(any(feature = "postgresql", feature = "sqlite")))] 47 | compile_error!("At least one backend must be used with this crate. \ 48 | Please specify `features = ["postgresql"]` or `features = ["sqlite"]`") 49 | ``` 50 | 51 | ## Detailed design 52 | [design]: #detailed-design 53 | 54 | The span given for the failure should be the invocation of the `compile_error!` 55 | macro. The macro must take exactly one argument, which is a string literal. The 56 | macro will then call `span_err` with the provided message on the expansion 57 | context, and will not expand to any further code. 58 | 59 | ## Drawbacks 60 | [drawbacks]: #drawbacks 61 | 62 | None 63 | 64 | ## Alternatives 65 | [alternatives]: #alternatives 66 | 67 | Wait for the stabilization of procedural macros, at which point a crate could 68 | provide this functionality. 69 | 70 | ## Unresolved questions 71 | [unresolved]: #unresolved-questions 72 | 73 | None 74 | -------------------------------------------------------------------------------- /text/2296-option-replace.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `option-replace` 2 | - Start Date: 2017-01-16 3 | - RFC PR: [rust-lang/rfcs#2296](https://github.com/rust-lang/rfcs/pull/2296) 4 | - Rust Issue: [rust-lang/rust#51998](https://github.com/rust-lang/rust/issues/51998) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | This RFC proposes the addition of `Option::replace` to complete the `Option::take` method, it replaces the actual value in the option by `Some` with the value given in parameter, returning the old value if present, without deinitializing either one. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | You can see the `Option` as a container and other containers already have this kind of method to change a value in-place like the [HashMap::replace](https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.replace) method. 15 | 16 | How do you replace a value inside an `Option`, you can use `mem::replace` but it can be really inconvenient to import the `mem` module just for that. Why not adding a useful method to do that ? 17 | 18 | This is the symmetry of the already present `Option::take` method. 19 | 20 | ## Detailed design 21 | [design]: #detailed-design 22 | 23 | This method will be added to the `core::option::Option` type implementation: 24 | 25 | ```rust 26 | use core::mem::replace; 27 | 28 | impl Option { 29 | // ... 30 | 31 | pub fn replace(&mut self, value: T) -> Option { 32 | mem::replace(self, Some(value)) 33 | } 34 | } 35 | ``` 36 | 37 | ## Drawbacks 38 | [drawbacks]: #drawbacks 39 | 40 | It increases the size of the standard library by a tiny bit. 41 | 42 | The add of this method could be a breaking change in the case of an already implemented method on the `Option` enum with the `replace` name. (i.e. a Trait defining the `replace` method that has been implemented on the `Option` type). 43 | 44 | This method behavior could be misinterpreted: Updating the `Option` only if the variant is `Some`, doing nothing if its `None`. This other method could exist too and be named `map_in_place` or `modify`, no method having this kind of behavior already exist in the Rust std library. 45 | 46 | ## Alternatives 47 | [alternatives]: #alternatives 48 | 49 | - Don't use the `replace` name and use `give` instead in symmetry with the actual `take` method. 50 | - Use directly `mem::replace`. 51 | 52 | ## Unresolved questions 53 | [unresolved]: #unresolved-questions 54 | 55 | None. 56 | -------------------------------------------------------------------------------- /text/0026-remove-priv.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-03-31 2 | - RFC PR: [rust-lang/rfcs#26](https://github.com/rust-lang/rfcs/pull/26) 3 | - Rust Issue: [rust-lang/rust#13535](https://github.com/rust-lang/rust/issues/13535) 4 | 5 | ## Summary 6 | 7 | This RFC is a proposal to remove the usage of the keyword `priv` from the Rust 8 | language. 9 | 10 | ## Motivation 11 | 12 | By removing `priv` entirely from the language, it significantly simplifies the 13 | privacy semantics as well as the ability to explain it to newcomers. The one 14 | remaining case, private enum variants, can be rewritten as such: 15 | 16 | ```rust 17 | // pub enum Foo { 18 | // Bar, 19 | // priv Baz, 20 | // } 21 | 22 | pub enum Foo { 23 | Bar, 24 | Baz(BazInner) 25 | } 26 | 27 | pub struct BazInner(()); 28 | 29 | // pub enum Foo2 { 30 | // priv Bar2, 31 | // priv Baz2, 32 | // } 33 | 34 | pub struct Foo2 { 35 | variant: FooVariant 36 | } 37 | 38 | enum FooVariant { 39 | Bar2, 40 | Baz2, 41 | } 42 | ``` 43 | 44 | Private enum variants are a rarely used feature of the language, and are 45 | generally not regarded as a strong enough feature to justify the `priv` keyword 46 | entirely. 47 | 48 | ## Detailed design 49 | 50 | There remains only one use case of the `priv` visibility qualifier in the Rust 51 | language, which is to make enum variants private. For example, it is possible 52 | today to write a type such as: 53 | 54 | ```rust 55 | pub enum Foo { 56 | Bar, 57 | priv Baz 58 | } 59 | ``` 60 | 61 | In this example, the variant `Bar` is public, while the variant `Baz` is 62 | private. This RFC would remove this ability to have private enum variants. 63 | 64 | In addition to disallowing the `priv` keyword on enum variants, this RFC would 65 | also forbid visibility qualifiers in front of enum variants entirely, as they no 66 | longer serve any purpose. 67 | 68 | ### Status of the identifier `priv` 69 | 70 | This RFC would demote the identifier `priv` from being a keyword to being a 71 | reserved keyword (in case we find a use for it in the future). 72 | 73 | ## Alternatives 74 | 75 | * Allow private enum variants, as-is today. 76 | * Add a new keyword for `enum` which means "my variants are all private" with 77 | controls to make variants public. 78 | 79 | ## Unresolved questions 80 | 81 | * Is the assertion that private enum variants are rarely used true? Are there 82 | legitimate use cases for keeping the `priv` keyword? 83 | -------------------------------------------------------------------------------- /compiler_changes.md: -------------------------------------------------------------------------------- 1 | # RFC policy - the compiler 2 | 3 | Compiler RFCs will be managed by the compiler sub-team, and tagged `T-compiler`. 4 | The compiler sub-team will do an initial triage of new PRs within a week of 5 | submission. The result of triage will either be that the PR is assigned to a 6 | member of the sub-team for shepherding, the PR is closed because the sub-team 7 | believe it should be done without an RFC, or closed because the sub-team feel it 8 | should clearly not be done and further discussion is not necessary. We'll follow 9 | the standard procedure for shepherding, final comment period, etc. 10 | 11 | Most compiler decisions that go beyond the scope of a simple PR are done using [MCP]s, 12 | not RFCs. It is therefore likely that you should file an MCP instead of an RFC for your problem. 13 | 14 | ## Changes which need an RFC 15 | 16 | * Significant user-facing changes to the compiler with a complex design space, 17 | especially if they involve other teams as well (for example, [path sanitization]). 18 | * Any other change which causes significant backwards incompatible changes to stable 19 | behaviour of the compiler, language, or libraries 20 | 21 | ## Changes which don't need an RFC 22 | 23 | * Bug fixes, improved error messages, etc. 24 | * Minor refactoring/tidying up 25 | * Large internal refactorings or redesigns of the compiler (needs an [MCP]) 26 | * Implementing language features which have an accepted RFC. 27 | * New lints (these fall under the lang team). Lints are best first tried out in clippy 28 | and then uplifted later. 29 | * Changing the API presented to syntax extensions or other compiler plugins in 30 | non-trivial ways 31 | * Adding, removing, or changing a stable compiler flag 32 | (needs an FCP somewhere, like on an [MCP] or just on a PR) 33 | * Adding unstable API for tools (note that all compiler API is currently unstable) 34 | * Adding, removing, or changing an unstable compiler flag (if the compiler flag 35 | is widely used there should be at least some discussion on discuss, or an RFC 36 | in some cases) 37 | 38 | If in doubt it is probably best to just announce the change you want to make to 39 | the compiler subteam on [Zulip], and see if anyone feels it needs an RFC. 40 | 41 | [MCP]: https://github.com/rust-lang/compiler-team/issues 42 | [path sanitization]: https://github.com/rust-lang/rfcs/pull/3127 43 | [Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler 44 | 45 | -------------------------------------------------------------------------------- /text/0059-remove-tilde.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-04-30 2 | - RFC PR: [rust-lang/rfcs#59](https://github.com/rust-lang/rfcs/pull/59) 3 | - Rust Issue: [rust-lang/rust#13885](https://github.com/rust-lang/rust/issues/13885) 4 | 5 | ## Summary 6 | 7 | The tilde (`~`) operator and type construction do not support allocators and therefore should be removed in favor of the `box` keyword and a language item for the type. 8 | 9 | ## Motivation 10 | 11 | * There will be a unique pointer type in the standard library, `Box` where `A` is an allocator. The `~T` type syntax does not allow for custom allocators. Therefore, in order to keep `~T` around while still supporting allocators, we would need to make it an alias for `Box`. In the spirit of having one way to do things, it seems better to remove `~` entirely as a type notation. 12 | 13 | * `~EXPR` and `box EXPR` are duplicate functionality; the former does not support allocators. Again in the spirit of having one and only one way to do things, I would like to remove `~EXPR`. 14 | 15 | * Some people think `~` is confusing, as it is less self-documenting than `Box`. 16 | 17 | * `~` can encourage people to blindly add sigils attempting to get their code to compile instead of consulting the library documentation. 18 | 19 | ## Drawbacks 20 | 21 | `~T` may be seen as convenient sugar for a common pattern in some situations. 22 | 23 | ## Detailed design 24 | 25 | The `~EXPR` production is removed from the language, and all such uses are converted into `box`. 26 | 27 | Add a lang item, `box`. That lang item will be defined in `liballoc` (NB: not `libmetal`/`libmini`, for bare-metal programming) as follows: 28 | 29 | #[lang="box"] 30 | pub struct Box(*T); 31 | 32 | All parts of the compiler treat instances of `Box` identically to the way it treats `~T` today. 33 | 34 | The destructuring form for `Box` will be `box PAT`, as follows: 35 | 36 | let box(x) = box(10); 37 | println!("{}", x); // prints 10 38 | 39 | ## Alternatives 40 | 41 | The other possible design here is to keep `~T` as sugar. The impact of doing this would be that a common pattern would be terser, but I would like to not do this for the reasons stated in "Motivation" above. 42 | 43 | ## Unresolved questions 44 | 45 | The allocator design is not yet fully worked out. 46 | 47 | It may be possible that unforeseen interactions will appear between the struct nature of `Box` and the built-in nature of `~T` when merged. 48 | -------------------------------------------------------------------------------- /text/0702-rangefull-expression.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-21 2 | - RFC PR: [#702](https://github.com/rust-lang/rfcs/pull/702) 3 | - Rust Issue: [#21879](https://github.com/rust-lang/rust/issues/21879) 4 | 5 | ## Summary 6 | 7 | Add the syntax `..` for `std::ops::RangeFull`. 8 | 9 | ## Motivation 10 | 11 | Range expressions `a..b`, `a..` and `..b` all have dedicated syntax and 12 | produce first-class values. This means that they will be usable and 13 | useful in custom APIs, so for consistency, the fourth slicing range, 14 | `RangeFull`, could have its own syntax `..` 15 | 16 | ## Detailed design 17 | 18 | `..` will produce a `std::ops::RangeFull` value when it is used in an 19 | expression. This means that slicing the whole range of a sliceable 20 | container is written `&foo[..]`. 21 | 22 | We should remove the old `&foo[]` syntax for consistency. Because of 23 | this breaking change, it would be best to change this before Rust 1.0. 24 | 25 | As previously stated, when we have range expressions in the language, 26 | they become convenient to use when stating ranges in an API. 27 | 28 | @Gankro fielded ideas where 29 | methods like for example `.remove(index) -> element` on a collection 30 | could be generalized by accepting either indices or ranges. Today's `.drain()` 31 | could be expressed as `.remove(..)`. 32 | 33 | Matrix or multidimensional array APIs can use the range expressions for 34 | indexing and/or generalized slicing and `..` represents selecting a full axis 35 | in a multidimensional slice, i.e. `(1..3, ..)` slices the first axis and 36 | preserves the second. 37 | 38 | Because of deref coercions, the very common conversions of String or Vec to 39 | slices don't need to use slicing syntax at all, so the change in verbosity from 40 | `[]` to `[..]` is not a concern. 41 | 42 | ## Drawbacks 43 | 44 | * Removing the slicing syntax `&foo[]` is a breaking change. 45 | 46 | * `..` already appears in patterns, as in this example: 47 | `if let Some(..) = foo { }`. This is not a conflict per se, but the 48 | same syntax element is used in two different ways in Rust. 49 | 50 | ## Alternatives 51 | 52 | * We could add this syntax later, but we would end up with duplicate 53 | slicing functionality using `&foo[]` and `&foo[..]`. 54 | 55 | * `0..` could replace `..` in many use cases (but not for ranges in 56 | ordered maps). 57 | 58 | ## Unresolved questions 59 | 60 | Any parsing questions should already be mostly solved because of the 61 | `a..` and `..b` cases. 62 | -------------------------------------------------------------------------------- /generate-book.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | This auto-generates the mdBook SUMMARY.md file based on the layout on the filesystem. 5 | 6 | This generates the `src` directory based on the contents of the `text` directory. 7 | 8 | Most RFCs should be kept to a single chapter. However, in some rare cases it 9 | may be necessary to spread across multiple pages. In that case, place them in 10 | a subdirectory with the same name as the RFC. For example: 11 | 12 | 0123-my-awesome-feature.md 13 | 0123-my-awesome-feature/extra-material.md 14 | 15 | It is recommended that if you have static content like images that you use a similar layout: 16 | 17 | 0123-my-awesome-feature.md 18 | 0123-my-awesome-feature/diagram.svg 19 | 20 | The chapters are presented in sorted-order. 21 | """ 22 | 23 | import os 24 | import shutil 25 | import subprocess 26 | 27 | def main(): 28 | if os.path.exists('src'): 29 | # Clear out src to remove stale links in case you switch branches. 30 | shutil.rmtree('src') 31 | os.mkdir('src') 32 | 33 | for path in os.listdir('text'): 34 | symlink(f'../text/{path}', f'src/{path}') 35 | symlink(f'../compiler_changes.md', f'src/compiler_changes.md') 36 | symlink(f'../lang_changes.md', f'src/lang_changes.md') 37 | symlink(f'../libs_changes.md', f'src/libs_changes.md') 38 | symlink('../README.md', 'src/introduction.md') 39 | 40 | with open('src/SUMMARY.md', 'w') as summary: 41 | summary.write('[Introduction](introduction.md)\n\n') 42 | summary.write('- [Guidelines for compiler changes](compiler_changes.md)\n') 43 | summary.write('- [Guidelines for language changes](lang_changes.md)\n') 44 | summary.write('- [Guidelines for library changes](libs_changes.md)\n') 45 | collect(summary, 'text', 0) 46 | 47 | subprocess.call(['mdbook', 'build']) 48 | 49 | def collect(summary, path, depth): 50 | entries = [e for e in os.scandir(path) if e.name.endswith('.md')] 51 | entries.sort(key=lambda e: e.name) 52 | for entry in entries: 53 | indent = ' '*depth 54 | name = entry.name[:-3] 55 | link_path = entry.path[5:] 56 | summary.write(f'{indent}- [{name}]({link_path})\n') 57 | maybe_subdir = os.path.join(path, name) 58 | if os.path.isdir(maybe_subdir): 59 | collect(summary, maybe_subdir, depth+1) 60 | 61 | def symlink(src, dst): 62 | if not os.path.exists(dst): 63 | os.symlink(src, dst) 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /text/0085-pattern-macros.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-05-21 2 | - RFC PR: [rust-lang/rfcs#85](https://github.com/rust-lang/rfcs/pull/85) 3 | - Rust Issue: [rust-lang/rust#14473](https://github.com/rust-lang/rust/issues/14473) 4 | 5 | ## Summary 6 | 7 | Allow macro expansion in patterns, i.e. 8 | 9 | ~~~ .rs 10 | match x { 11 | my_macro!() => 1, 12 | _ => 2, 13 | } 14 | ~~~ 15 | 16 | ## Motivation 17 | 18 | This is consistent with allowing macros in expressions etc. It's also a year-old [open issue](https://github.com/mozilla/rust/issues/6830). 19 | 20 | I have [implemented](https://github.com/mozilla/rust/pull/14298) this feature already and I'm [using it](https://github.com/kmcallister/html5/blob/937684f107090741c8e87135efc6e5476489857b/src/tree_builder/mod.rs#L111-L117) to [condense](https://github.com/kmcallister/html5/blob/937684f107090741c8e87135efc6e5476489857b/src/tree_builder/mod.rs#L261-L269) some ubiquitous patterns in the [HTML parser](https://github.com/kmcallister/html5) I'm writing. This makes the code more concise and easier to cross-reference with the spec. 21 | 22 | ## Drawbacks / alternatives 23 | 24 | A macro invocation in this position: 25 | 26 | ~~~ .rs 27 | match x { 28 | my_macro!() 29 | ~~~ 30 | 31 | could potentially expand to any of three different syntactic elements: 32 | 33 | * A pattern, i.e. `Foo(x)` 34 | * The left side of a `match` arm, i.e. `Foo(x) | Bar(x) if x > 5` 35 | * An entire `match` arm, i.e. `Foo(x) | Bar(x) if x > 5 => 1` 36 | 37 | This RFC proposes only the first of these, but the others would be more useful in some cases. Supporting multiple of the above would be significantly more complex. 38 | 39 | Another alternative is to use a macro for the entire `match` expression, e.g. 40 | 41 | ~~~ .rs 42 | my_match!(x { 43 | my_new_syntax => 1, 44 | _ => 2, 45 | }) 46 | ~~~ 47 | 48 | This doesn't involve any language changes, but requires writing a complicated procedural macro. (My sustained attempts to do things like this with MBE macros have all failed.) Perhaps I could alleviate some of the pain with a library for writing `match`-like macros, or better use of the existing parser in `libsyntax`. 49 | 50 | The `my_match!` approach is also not very composable. 51 | 52 | Another small drawback: `rustdoc` [can't document](https://github.com/kmcallister/rust/blob/af65e3e9824087a472de3fea3c7cb1efcec4550b/src/librustdoc/clean.rs#L1287-L1291) the name of a function argument which is produced by a pattern macro. 53 | 54 | ## Unresolved questions 55 | 56 | None, as far as I know. 57 | -------------------------------------------------------------------------------- /text/1096-remove-static-assert.md: -------------------------------------------------------------------------------- 1 | - Feature Name: remove-static-assert 2 | - Start Date: 2015-04-28 3 | - RFC PR: [rust-lang/rfcs#1096](https://github.com/rust-lang/rfcs/pull/1096) 4 | - Rust Issue: https://github.com/rust-lang/rust/pull/24910 5 | 6 | ## Summary 7 | 8 | Remove the `static_assert` feature. 9 | 10 | ## Motivation 11 | 12 | To recap, `static_assert` looks like this: 13 | 14 | ```rust 15 | #![feature(static_assert)] 16 | #[static_assert] 17 | static assertion: bool = true; 18 | ``` 19 | 20 | If `assertion` is `false` instead, this fails to compile: 21 | 22 | ```text 23 | error: static assertion failed 24 | static assertion: bool = false; 25 | ^~~~~ 26 | ``` 27 | 28 | If you don’t have the `feature` flag, you get another interesting error: 29 | 30 | ```text 31 | error: `#[static_assert]` is an experimental feature, and has a poor API 32 | ``` 33 | 34 | Throughout its life, `static_assert` has been... weird. Graydon suggested it 35 | [in May of 2013][suggest], and it was 36 | [implemented](https://github.com/rust-lang/rust/pull/6670) shortly after. 37 | [Another issue][issue] was created to give it a ‘better interface’. Here’s why: 38 | 39 | > The biggest problem with it is you need a static variable with a name, that 40 | > goes through trans and ends up in the object file. 41 | 42 | In other words, `assertion` above ends up as a symbol in the final output. Not 43 | something you’d usually expect from some kind of static assertion. 44 | 45 | [suggest]: https://github.com/rust-lang/rust/issues/6568 46 | [issue]: https://github.com/rust-lang/rust/issues/6676 47 | 48 | So why not improve `static_assert`? With compile time function evaluation, the 49 | idea of a ‘static assertion’ doesn’t need to have language semantics. Either 50 | `const` functions or full-blown CTFE is a useful feature in its own right that 51 | we’ve said we want in Rust. In light of it being eventually added, 52 | `static_assert` doesn’t make sense any more. 53 | 54 | `static_assert` isn’t used by the compiler at all. 55 | 56 | ## Detailed design 57 | 58 | Remove `static_assert`. [Implementation submitted here][here]. 59 | 60 | [here]: https://github.com/rust-lang/rust/pull/24910 61 | 62 | ## Drawbacks 63 | 64 | Why should we *not* do this? 65 | 66 | ## Alternatives 67 | 68 | This feature is pretty binary: we either remove it, or we don’t. We could keep the feature, 69 | but build out some sort of alternate version that’s not as weird. 70 | 71 | ## Unresolved questions 72 | 73 | None with the design, only “should we do this?” 74 | -------------------------------------------------------------------------------- /text/2471-lint-test-inner-function.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `lint_test_inner_function` 2 | - Start Date: 2018-06-10 3 | - RFC PR: [rust-lang/rfcs#2471](https://github.com/rust-lang/rfcs/pull/2471) 4 | - Rust Issue: [rust-lang/rust#53911](https://github.com/rust-lang/rust/issues/53911) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Add a lint that warns when marking an inner function as `#[test]`. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | `#[test]` is used to mark functions to be run as part of a test suite. The 15 | functions being marked need to be addressable for this to work. Currently, 16 | marking an inner function as `#[test]` will not raise any errors or warnings, 17 | but the test will silently not be run. By adding a lint that identifies these 18 | cases, users are less likely to fail to notice. 19 | 20 | ## Guide-level explanation 21 | [guide-level-explanation]: #guide-level-explanation 22 | 23 | This is a lint that triggers when a `#[test]` annotation is found in a non 24 | addressable function, warning that that function cannot be tested. 25 | 26 | For example, in the following code, `bar` will never be called as part of a 27 | test run: 28 | 29 | ```rust 30 | fn foo() { 31 | #[test] 32 | fn bar() { 33 | assert!(true); 34 | } 35 | } 36 | ``` 37 | 38 | The output should resemble the following: 39 | 40 | ``` 41 | error: cannot test inner function 42 | --> $DIR/test-inner-fn.rs:15:5 43 | | 44 | LL | #[test] //~ ERROR cannot test inner function [untestable_method] 45 | | ^^^^^^^ 46 | | 47 | = note: requested on the command line with `-D untestable-method` 48 | ``` 49 | 50 | ## Reference-level explanation 51 | [reference-level-explanation]: #reference-level-explanation 52 | 53 | This is a new lint that shouldn't interact with others. Due to the interaction 54 | with `cfg` attributes, the lint might only warn when run as part of a `--test` 55 | compilation. This would be acceptable. 56 | 57 | ## Drawbacks 58 | [drawbacks]: #drawbacks 59 | 60 | Can't think of any reason not to do this. 61 | 62 | ## Rationale and alternatives 63 | [alternatives]: #alternatives 64 | 65 | Adding as a lint allows users to silence the error if they so wish. 66 | 67 | Not addressing this issue will let this problem continue happening without 68 | warning to end users. 69 | 70 | ## Prior art 71 | [prior-art]: #prior-art 72 | 73 | This would act in the same way as other lints warning for potentially 74 | problematic valid code. 75 | 76 | ## Unresolved questions 77 | [unresolved]: #unresolved-questions 78 | 79 | None. 80 | -------------------------------------------------------------------------------- /text/2341-const-locals.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `const_locals` 2 | - Start Date: 2018-01-11 3 | - RFC PR: [rust-lang/rfcs#2341](https://github.com/rust-lang/rfcs/pull/2341) 4 | - Rust Issue: [rust-lang/rust#48821](https://github.com/rust-lang/rust/issues/48821) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Allow `let` bindings in the body of constants and const fns. Additionally enable 10 | destructuring in `let` bindings and const fn arguments. 11 | 12 | ## Motivation 13 | [motivation]: #motivation 14 | 15 | It makes writing const fns much more like writing regular functions and is 16 | not possible right now because the old constant evaluator was a constant folder 17 | that could only process expressions. With the miri const evaluator this feature 18 | exists but is still disallowed. 19 | 20 | ## Guide-level explanation 21 | [guide-level-explanation]: #guide-level-explanation 22 | 23 | `let` bindings in constants and const fn work just like `let` bindings 24 | everywhere else. Historically these did not exist in constants and const fn 25 | because it would have been very hard to support them in the old const evaluator. 26 | 27 | This means that you can only move out of any let binding once, even though in a 28 | const environment obtaining a copy of the object could be done by executing the 29 | code twice, side effect free. All invariants held by runtime code are also 30 | upheld by constant evaluation. 31 | 32 | ## Reference-level explanation 33 | [reference-level-explanation]: #reference-level-explanation 34 | 35 | Expressions like `a + b + c` are already transformed to 36 | 37 | ```rust 38 | let tmp = a + b; 39 | tmp + c 40 | ``` 41 | 42 | With this RFC we can create bindings ourselves instead of only allowing compiler 43 | generated bindings. 44 | 45 | ## Drawbacks 46 | [drawbacks]: #drawbacks 47 | 48 | You can create mutable locals in constants and then actually modify them. This 49 | has no real impact on the constness, as the mutation happens entirely at compile 50 | time and results in an immutable value. 51 | 52 | ## Rationale and alternatives 53 | [alternatives]: #alternatives 54 | 55 | The backend already supports this 100%. This is essentially just disabling a 56 | check 57 | 58 | ### Why is this design the best in the space of possible designs? 59 | 60 | Being the only design makes it the best design by definition 61 | 62 | ### What is the impact of not doing this? 63 | 64 | Not having locals and destructuring severely limits the functions that can be 65 | turned into const fn and generally leads to unreadable const fns. 66 | 67 | ## Unresolved questions 68 | [unresolved]: #unresolved-questions 69 | -------------------------------------------------------------------------------- /text/1174-into-raw-fd-socket-handle-traits.md: -------------------------------------------------------------------------------- 1 | - Feature Name: into-raw-fd-socket-handle-traits 2 | - Start Date: 2015-06-24 3 | - RFC PR: [rust-lang/rfcs#1174](https://github.com/rust-lang/rfcs/pull/1174) 4 | - Rust Issue: [rust-lang/rust#27062](https://github.com/rust-lang/rust/issues/27062) 5 | 6 | ## Summary 7 | 8 | Introduce and implement `IntoRaw{Fd, Socket, Handle}` traits to complement the 9 | existing `AsRaw{Fd, Socket, Handle}` traits already in the standard library. 10 | 11 | ## Motivation 12 | 13 | The `FromRaw{Fd, Socket, Handle}` traits each take ownership of the provided 14 | handle, however, the `AsRaw{Fd, Socket, Handle}` traits do not give up 15 | ownership. Thus, converting from one handle wrapper to another (for example 16 | converting an open `fs::File` to a `process::Stdio`) requires the caller to 17 | either manually `dup` the handle, or `mem::forget` the wrapper, which 18 | is unergonomic and can be prone to mistakes. 19 | 20 | Traits such as `IntoRaw{Fd, Socket, Handle}` will allow for easily transferring 21 | ownership of OS handles, and it will allow wrappers to perform any 22 | cleanup/setup as they find necessary. 23 | 24 | ## Detailed design 25 | 26 | The `IntoRaw{Fd, Socket, Handle}` traits will behave exactly like their 27 | `AsRaw{Fd, Socket, Handle}` counterparts, except they will consume the wrapper 28 | before transferring ownership of the handle. 29 | 30 | Note that these traits should **not** have a blanket implementation over `T: 31 | AsRaw{Fd, Socket, Handle}`: these traits should be opt-in so that implementors 32 | can decide if leaking through `mem::forget` is acceptable or another course of 33 | action is required. 34 | 35 | ```rust 36 | // Unix 37 | pub trait IntoRawFd { 38 | fn into_raw_fd(self) -> RawFd; 39 | } 40 | 41 | // Windows 42 | pub trait IntoRawSocket { 43 | fn into_raw_socket(self) -> RawSocket; 44 | } 45 | 46 | // Windows 47 | pub trait IntoRawHandle { 48 | fn into_raw_handle(self) -> RawHandle; 49 | } 50 | ``` 51 | 52 | ## Drawbacks 53 | 54 | This adds three new traits and methods which would have to be maintained. 55 | 56 | ## Alternatives 57 | 58 | Instead of defining three new traits we could instead use the 59 | `std::convert::Into` trait over the different OS handles. However, this 60 | approach will not offer a duality between methods such as 61 | `as_raw_fd()`/`into_raw_fd()`, but will instead be `as_raw_fd()`/`into()`. 62 | 63 | Another possibility is defining both the newly proposed traits as well as the 64 | `Into` trait over the OS handles letting the caller choose what they prefer. 65 | 66 | ## Unresolved questions 67 | 68 | None at the moment. 69 | -------------------------------------------------------------------------------- /text/1651-movecell.md: -------------------------------------------------------------------------------- 1 | - Feature Name: move_cell 2 | - Start Date: 2016-06-15 3 | - RFC PR: [rust-lang/rfcs#1651](https://github.com/rust-lang/rfcs/pull/1651) 4 | - Rust Issue: [rust-lang/rust#39264](https://github.com/rust-lang/rust/issues/39264) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Extend `Cell` to work with non-`Copy` types. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | It allows safe inner-mutability of non-`Copy` types without the overhead of `RefCell`'s reference counting. 15 | 16 | The key idea of `Cell` is to provide a primitive building block to safely support inner mutability. This must be done while maintaining Rust's aliasing requirements for mutable references. Unlike `RefCell` which enforces this at runtime through reference counting, `Cell` does this statically by disallowing any reference (mutable or immutable) to the data contained in the cell. 17 | 18 | While the current implementation only supports `Copy` types, this restriction isn't actually necessary to maintain Rust's aliasing invariants. The only affected API is the `get` function which, by design, is only usable with `Copy` types. 19 | 20 | ## Detailed design 21 | [design]: #detailed-design 22 | 23 | ```rust 24 | impl Cell { 25 | fn set(&self, val: T); 26 | fn replace(&self, val: T) -> T; 27 | fn into_inner(self) -> T; 28 | } 29 | 30 | impl Cell { 31 | fn get(&self) -> T; 32 | } 33 | 34 | impl Cell { 35 | fn take(&self) -> T; 36 | } 37 | ``` 38 | 39 | The `get` method is kept but is only available for `T: Copy`. 40 | 41 | The `set` method is available for all `T`. It will need to be implemented by calling `replace` and dropping the returned value. Dropping the old value in-place is unsound since the `Drop` impl will hold a mutable reference to the cell contents. 42 | 43 | The `into_inner` and `replace` methods are added, which allow the value in a cell to be read even if `T` is not `Copy`. The `get` method can't be used since the cell must always contain a valid value. 44 | 45 | Finally, a `take` method is added which is equivalent to `self.replace(Default::default())`. 46 | 47 | ## Drawbacks 48 | [drawbacks]: #drawbacks 49 | 50 | It makes the `Cell` type more complicated. 51 | 52 | `Cell` will only be able to derive traits like `Eq` and `Ord` for types that are `Copy`, since there is no way to non-destructively read the contents of a non-`Copy` `Cell`. 53 | 54 | ## Alternatives 55 | [alternatives]: #alternatives 56 | 57 | The alternative is to use the `MoveCell` type from crates.io which provides the same functionality. 58 | 59 | ## Unresolved questions 60 | [unresolved]: #unresolved-questions 61 | 62 | None 63 | -------------------------------------------------------------------------------- /text/2836-project-asm.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `project-inline-asm` 2 | - Start Date: 2019-12-07 3 | - RFC PR: [rust-lang/rfcs#2836](https://github.com/rust-lang/rfcs/pull/2836) 4 | - Rust Issue: [rust-lang/rust#29722](https://github.com/rust-lang/rust/issues/29722) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | To create a [project group] with the purpose of designing subsequent RFCs to extend the language to support inline assembly in Rust code. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | In systems programming some tasks require dropping down to the assembly level. The primary reasons are for performance, precise timing, and low level hardware access. Using inline assembly for this is sometimes convenient, and sometimes necessary to avoid function call overhead. 15 | 16 | The inline assembler syntax currently available in nightly Rust is very ad-hoc. It provides a thin wrapper over the inline assembly syntax available in LLVM IR. For stabilization a more user-friendly syntax that lends itself to implementation across various backends is preferable. 17 | 18 | ## Project group details 19 | 20 | [Repository][asm project] 21 | 22 | [Zulip stream][zulip] 23 | 24 | Initial shepherds: 25 | 26 | * [Amanieu (Amanieu d'Antras)](https://github.com/Amanieu) 27 | 28 | Lang team liaisons: 29 | 30 | * [joshtriplett (Josh Triplett)](https://github.com/joshtriplett) 31 | 32 | ## Charter 33 | [charter]: #charter 34 | 35 | The main goal of the asm project group is to design and implement an `asm!` macro using a syntax that we feel we can maintain, easily write, and stabilize. 36 | 37 | The project group has the following additional goals: 38 | * to provide a transition path for existing users of the unstable `asm!` macro. 39 | * to ensure that the chosen `asm!` syntax is portable to different compiler backends such as LLVM, GCC, etc. 40 | * to provide a fallback implementation on compiler backends that do not support inline assembly natively (e.g. [Cranelift][cranelift]). 41 | * to initially support most major architectures (x86, ARM, RISC-V) with the intention of extending to other architectures in the future. 42 | 43 | With a lower priority, the project group also intends to tackle the following secondary, future goals: 44 | * support for module-level assembly (`global_asm!`). 45 | * support for naked functions (`#[naked]`). 46 | 47 | [asm project]: https://github.com/rust-lang/project-inline-asm 48 | [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/216763-project-inline-asm 49 | [cranelift]: https://github.com/CraneStation/cranelift/issues/444 50 | [project group]: https://github.com/rust-lang/wg-governance/blob/master/draft-rfcs/working-group-terminology.md 51 | -------------------------------------------------------------------------------- /text/1307-osstring-methods.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `osstring_simple_functions` 2 | - Start Date: 2015-10-04 3 | - RFC PR: [rust-lang/rfcs#1307](https://github.com/rust-lang/rfcs/pull/1307) 4 | - Rust Issue: [rust-lang/rust#29453](https://github.com/rust-lang/rust/issues/29453) 5 | 6 | ## Summary 7 | 8 | Add some additional utility methods to OsString and OsStr. 9 | 10 | ## Motivation 11 | 12 | OsString and OsStr are extremely bare at the moment; some utilities would make them 13 | easier to work with. The given set of utilities is taken from String, and don't add 14 | any additional restrictions to the implementation. 15 | 16 | I don't think any of the proposed methods are controversial. 17 | 18 | ## Detailed design 19 | 20 | Add the following methods to OsString: 21 | 22 | ```rust 23 | /// Creates a new `OsString` with the given capacity. The string will be able 24 | /// to hold exactly `capacity` bytes without reallocating. If `capacity` is 0, 25 | /// the string will not allocate. 26 | /// 27 | /// See main `OsString` documentation information about encoding. 28 | fn with_capacity(capacity: usize) -> OsString; 29 | 30 | /// Truncates `self` to zero length. 31 | fn clear(&mut self); 32 | 33 | /// Returns the number of bytes this `OsString` can hold without reallocating. 34 | /// 35 | /// See `OsString` introduction for information about encoding. 36 | fn capacity(&self) -> usize; 37 | 38 | /// Reserves capacity for at least `additional` more bytes to be inserted in the 39 | /// given `OsString`. The collection may reserve more space to avoid frequent 40 | /// reallocations. 41 | fn reserve(&mut self, additional: usize); 42 | 43 | /// Reserves the minimum capacity for exactly `additional` more bytes to be 44 | /// inserted in the given `OsString`. Does nothing if the capacity is already 45 | /// sufficient. 46 | /// 47 | /// Note that the allocator may give the collection more space than it 48 | /// requests. Therefore capacity can not be relied upon to be precisely 49 | /// minimal. Prefer reserve if future insertions are expected. 50 | fn reserve_exact(&mut self, additional: usize); 51 | ``` 52 | 53 | Add the following methods to OsStr: 54 | 55 | ```rust 56 | /// Checks whether `self` is empty. 57 | fn is_empty(&self) -> bool; 58 | 59 | /// Returns the number of bytes in this string. 60 | /// 61 | /// See `OsStr` introduction for information about encoding. 62 | fn len(&self) -> usize; 63 | ``` 64 | 65 | ## Drawbacks 66 | 67 | The meaning of `len()` might be a bit confusing because it's the size of 68 | the internal representation on Windows, which isn't otherwise visible to the 69 | user. 70 | 71 | ## Alternatives 72 | 73 | None. 74 | 75 | ## Unresolved questions 76 | 77 | None. 78 | -------------------------------------------------------------------------------- /text/3392-leadership-council/non-goals.md: -------------------------------------------------------------------------------- 1 | # Non-goals of this RFC 2 | 3 | The following are non-goals of this RFC. These may be met in future RFCs but are explicitly not part of this RFC. 4 | 5 | Non-goal #1: *Laying out the complete policies and procedures of the Council*. While the RFC lays out and bounds the structure of the Council, the Council's full policies and procedures will be created by the Council itself. It is also expected that the Council will change and adapt to meet the needs of the Rust Project as it evolves. 6 | 7 | Non-goal #2: *Addressing all governance and potential governance concerns*. One of the Council's responsibilities will be to identify and reflect on the issues present in governance, but we see the formation of the Council as part of a continuous process of improving Rust's leadership and how it meets the needs of the Project. 8 | 9 | Non-goal #3: *Forming additional teams*. The focus of this RFC is to form the Council and does not include the creation of additional teams, subteams, or groups of any kind. 10 | 11 | We recognize the importance of having additional teams, but see this as outside of the scope of this RFC. Instead, it will be the responsibility of the Council to investigate and understand such needs and then create additional teams to ultimately handle these issues. 12 | 13 | This has one exception, other than the Council itself: the "launching pad" top-level team, which provides a temporary grouping of teams not yet attached to any existing top-level team either directly or indirectly. 14 | 15 | Non-goal #4: *Altering the charters or purviews of existing teams*. While this RFC does discuss membership in the Council, it does not extend beyond this to update the charter or purview of any existing team. Existing teams continue to follow their existing charters and purviews. 16 | 17 | This has two exceptions: 18 | 19 | - the core team: As part of this RFC, all of the capabilities and responsibilities of the core team move to the Council and are then clarified, modified, and constrained by the rest of this RFC. 20 | - the moderation team: As this RFC covers topics like conflict resolution and Council oversight, it does define additional capabilities for the moderation team, as well as additional checks and balances providing bidirectional oversight between the moderation team and the Council. 21 | 22 | Non-goal #5: *Establishing completely immutable properties of the Council*. Any aspect established in this RFC can be modified in the future, via the public policy decision-making process, with oversight provided by that process. This RFC lays out policies for making such changes, and the processes of changing such policies must follow the existing policies. 23 | -------------------------------------------------------------------------------- /text/0049-match-arm-attributes.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-03-20 2 | - RFC PR: [rust-lang/rfcs#49](https://github.com/rust-lang/rfcs/pull/49) 3 | - Rust Issue: [rust-lang/rust#12812](https://github.com/rust-lang/rust/issues/12812) 4 | 5 | ## Summary 6 | 7 | Allow attributes on match arms. 8 | 9 | ## Motivation 10 | 11 | One sometimes wishes to annotate the arms of match statements with 12 | attributes, for example with conditional compilation `#[cfg]`s or 13 | with branch weights (the latter is the most important use). 14 | 15 | For the conditional compilation, the work-around is duplicating the 16 | whole containing function with a `#[cfg]`. A case study is 17 | [sfackler's bindings to OpenSSL](https://github.com/sfackler/rust-openssl), 18 | where many distributions remove SSLv2 support, and so that portion of 19 | Rust bindings needs to be conditionally disabled. The obvious way to 20 | support the various different SSL versions is an enum 21 | 22 | ```rust 23 | pub enum SslMethod { 24 | #[cfg(sslv2)] 25 | /// Only support the SSLv2 protocol 26 | Sslv2, 27 | /// Only support the SSLv3 protocol 28 | Sslv3, 29 | /// Only support the TLSv1 protocol 30 | Tlsv1, 31 | /// Support the SSLv2, SSLv3 and TLSv1 protocols 32 | Sslv23, 33 | } 34 | ``` 35 | 36 | However, all `match`s can only mention `Sslv2` when the `cfg` is 37 | active, i.e. the following is invalid: 38 | 39 | ```rust 40 | fn name(method: SslMethod) -> &'static str { 41 | match method { 42 | Sslv2 => "SSLv2", 43 | Sslv3 => "SSLv3", 44 | _ => "..." 45 | } 46 | } 47 | ``` 48 | 49 | A valid method would be to have two definitions: `#[cfg(sslv2)] fn 50 | name(...)` and `#[cfg(not(sslv2)] fn name(...)`. The former has the 51 | `Sslv2` arm, the latter does not. Clearly, this explodes exponentially 52 | for each additional `cfg`'d variant in an enum. 53 | 54 | Branch weights would allow the careful micro-optimiser to inform the 55 | compiler that, for example, a certain match arm is rarely taken: 56 | 57 | ```rust 58 | match foo { 59 | Common => {} 60 | #[cold] 61 | Rare => {} 62 | } 63 | ``` 64 | 65 | 66 | ## Detailed design 67 | 68 | Normal attribute syntax, applied to a whole match arm. 69 | 70 | ```rust 71 | match x { 72 | #[attr] 73 | Thing => {} 74 | 75 | #[attr] 76 | Foo | Bar => {} 77 | 78 | #[attr] 79 | _ => {} 80 | } 81 | ``` 82 | 83 | ## Alternatives 84 | 85 | There aren't really any general alternatives; one could probably hack 86 | around matching on conditional enum variants with some macros and 87 | helper functions to share as much code as possible; but in general 88 | this won't work. 89 | 90 | ## Unresolved questions 91 | 92 | Nothing particularly. 93 | -------------------------------------------------------------------------------- /text/1152-slice-string-symmetry.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `slice_string_symmetry` 2 | - Start Date: 2015-06-06 3 | - RFC PR: [rust-lang/rfcs#1152](https://github.com/rust-lang/rfcs/pull/1152) 4 | - Rust Issue: [rust-lang/rust#26697](https://github.com/rust-lang/rust/issues/26697) 5 | 6 | ## Summary 7 | 8 | Add some methods that already exist on slices to strings. Specifically, the 9 | following methods should be added: 10 | 11 | - `str::into_string` 12 | - `String::into_boxed_str` 13 | 14 | ## Motivation 15 | 16 | Conceptually, strings and slices are similar types. Many methods are already 17 | shared between the two types due to their similarity. However, not all methods 18 | are shared between the types, even though many could be. This is a little 19 | unexpected and inconsistent. Because of that, this RFC proposes to remedy this 20 | by adding a few methods to strings to even out these two types’ available 21 | methods. 22 | 23 | Specifically, it is currently very difficult to construct a `Box`, while it 24 | is fairly simple to make a `Box<[T]>` by using `Vec::into_boxed_slice`. This RFC 25 | proposes a means of creating a `Box` by converting a `String`. 26 | 27 | ## Detailed design 28 | 29 | Add the following method to `str`, presumably as an inherent method: 30 | 31 | - `into_string(self: Box) -> String`: Returns `self` as a `String`. This is 32 | equivalent to `[T]`’s `into_vec`. 33 | 34 | Add the following method to `String` as an inherent method: 35 | 36 | - `into_boxed_str(self) -> Box`: Returns `self` as a `Box`, 37 | reallocating to cut off any excess capacity if needed. This is required to 38 | provide a safe means of creating `Box`. This is equivalent to `Vec`’s 39 | `into_boxed_slice`. 40 | 41 | 42 | ## Drawbacks 43 | 44 | None, yet. 45 | 46 | ## Alternatives 47 | 48 | - The original version of this RFC had a few extra methods: 49 | - `str::chunks(&self, n: usize) -> Chunks`: Returns an iterator that yields 50 | the *characters* (not bytes) of the string in groups of `n` at a time. 51 | Iterator element type: `&str`. 52 | 53 | - `str::windows(&self, n: usize) -> Windows`: Returns an iterator over all 54 | contiguous windows of character length `n`. Iterator element type: `&str`. 55 | 56 | This and `str::chunks` aren’t really useful without proper treatment of 57 | graphemes, so they were removed from the RFC. 58 | 59 | - `<[T]>::subslice_offset(&self, inner: &[T]) -> usize`: Returns the offset 60 | (in elements) of an inner slice relative to an outer slice. Panics of 61 | `inner` is not contained within `self`. 62 | 63 | `str::subslice_offset` isn’t yet stable and its usefulness is dubious, so 64 | this method was removed from the RFC. 65 | 66 | 67 | ## Unresolved questions 68 | 69 | None. 70 | -------------------------------------------------------------------------------- /text/1498-ipv6addr-octets.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `ipaddr_octet_arrays` 2 | - Start Date: 2016-02-12 3 | - RFC PR: [rust-lang/rfcs#1498](https://github.com/rust-lang/rfcs/pull/1498) 4 | - Rust Issue: [rust-lang/rust#32313](https://github.com/rust-lang/rust/issues/32313) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Add constructor and conversion functions for `std::net::Ipv6Addr` and 10 | `std::net::Ipv4Addr` that are oriented around arrays of octets. 11 | 12 | ## Motivation 13 | [motivation]: #motivation 14 | 15 | Currently, the interface for `std::net::Ipv6Addr` is oriented around 16-bit 16 | "segments". The constructor takes eight 16-bit integers as arguments, 17 | and the sole getter function, `segments`, returns an array of eight 18 | 16-bit integers. This interface is unnatural when doing low-level network 19 | programming, where IPv6 addresses are treated as a sequence of 16 octets. 20 | For example, building and parsing IPv6 packets requires doing 21 | bitwise arithmetic with careful attention to byte order in order to convert 22 | between the on-wire format of 16 octets and the eight segments format used 23 | by `std::net::Ipv6Addr`. 24 | 25 | ## Detailed design 26 | [design]: #detailed-design 27 | 28 | The following method would be added to `impl std::net::Ipv6Addr`: 29 | 30 | ``` 31 | pub fn octets(&self) -> [u8; 16] { 32 | self.inner.s6_addr 33 | } 34 | ``` 35 | 36 | The following `From` trait would be implemented: 37 | 38 | ``` 39 | impl From<[u8; 16]> for Ipv6Addr { 40 | fn from(octets: [u8; 16]) -> Ipv6Addr { 41 | let mut addr: c::in6_addr = unsafe { std::mem::zeroed() }; 42 | addr.s6_addr = octets; 43 | Ipv6Addr { inner: addr } 44 | } 45 | } 46 | ``` 47 | 48 | For consistency, the following `From` trait would be 49 | implemented for `Ipv4Addr`: 50 | 51 | ``` 52 | impl From<[u8; 4]> for Ipv4Addr { 53 | fn from(octets: [u8; 4]) -> Ipv4Addr { 54 | Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]) 55 | } 56 | } 57 | ``` 58 | 59 | Note: `Ipv4Addr` already has an `octets` method that returns a `[u8; 4]`. 60 | 61 | ## Drawbacks 62 | [drawbacks]: #drawbacks 63 | 64 | It adds additional functions to the API, which increases cognitive load 65 | and maintenance burden. That said, the functions are conceptually very simple 66 | and their implementations short. 67 | 68 | ## Alternatives 69 | [alternatives]: #alternatives 70 | 71 | Do nothing. The downside is that developers will need to resort to 72 | bitwise arithmetic, which is awkward and error-prone (particularly with 73 | respect to byte ordering) to convert between `Ipv6Addr` and the on-wire 74 | representation of IPv6 addresses. Or they will use their alternative 75 | implementations of `Ipv6Addr`, fragmenting the ecosystem. 76 | 77 | ## Unresolved questions 78 | [unresolved]: #unresolved-questions 79 | 80 | -------------------------------------------------------------------------------- /text/2420-unreserve-proc.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `unreserve_proc` 2 | - Start Date: 2018-04-26 3 | - RFC PR: [rust-lang/rfcs#2420](https://github.com/rust-lang/rfcs/pull/2420) 4 | - Rust Issue: N/A. Already implemented. 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | The keyword `proc` gets unreserved. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | We are currently not using `proc` as a keyword for anything in the language. 15 | Currently, `proc` is a reserved keyword for future use. However, we have 16 | no intention of using the keyword for anything in the future, and as such, 17 | we want to unreserve it so that rustaceans can use it as identifiers. 18 | 19 | In the specific case of `proc`, it is a useful identifier for many things. 20 | In particular, it is useful when dealing with processes, OS internals and 21 | kernel development. 22 | 23 | ## Guide-level explanation 24 | [guide-level-explanation]: #guide-level-explanation 25 | 26 | See the [reference-level-explanation]. 27 | 28 | ## Reference-level explanation 29 | [reference-level-explanation]: #reference-level-explanation 30 | 31 | [list of reserved keywords]: https://doc.rust-lang.org/book/second-edition/appendix-01-keywords.html#keywords-currently-in-use 32 | 33 | The keyword `proc` is removed from the [list of reserved keywords] and is no 34 | longer reserved. This is done immediately and on edition 2015. 35 | 36 | ## Drawbacks 37 | [drawbacks]: #drawbacks 38 | 39 | The only drawback is that we're not able to use `proc` as a keyword in the 40 | future, without a reservation in a new edition, if we realize that we made 41 | a mistake. 42 | 43 | [arrow]: https://downloads.haskell.org/~ghc/7.8.1/docs/html/users_guide/arrow-notation.html 44 | 45 | The keyword `proc` could be used for some [`Arrow` notation][arrow] as used in 46 | Haskell. However, `proc` notation is rarely used in Haskell since `Arrow`s are 47 | not generally understood; and if something is not well understood by one of the 48 | most academically inclined of communities of users, it is doubly a bad fit for 49 | Rust which has a community mixed with users used to FP, systemsy and dynamically 50 | checked programming languages. Moreover, `Arrow`s would most likely require HKTs 51 | which we might not get. 52 | 53 | ## Rationale and alternatives 54 | [alternatives]: #alternatives 55 | 56 | There's only one alternative: Not doing anything. 57 | 58 | Previously, this used to be the keyword used for `move |..| { .. }` closures, 59 | but `proc` is no longer used for anything. 60 | 61 | Not unreserving this keyword would make the word unavailable for use as an 62 | identifier. 63 | 64 | ## Prior art 65 | [prior-art]: #prior-art 66 | 67 | Not applicable. 68 | 69 | ## Unresolved questions 70 | [unresolved]: #unresolved-questions 71 | 72 | There are none. 73 | -------------------------------------------------------------------------------- /text/0115-rm-integer-fallback.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-06-11 2 | - RFC PR: [rust-lang/rfcs#115](https://github.com/rust-lang/rfcs/pull/115) 3 | - Rust Issue: [rust-lang/rust#6023](https://github.com/rust-lang/rust/issues/6023) 4 | 5 | ## Summary 6 | 7 | Currently we use inference to find the current type of 8 | otherwise-unannotated integer literals, and when that fails the type 9 | defaults to `int`. This is often felt to be potentially error-prone 10 | behavior. 11 | 12 | This proposal removes the integer inference fallback and strengthens 13 | the types required for several language features that interact with 14 | integer inference. 15 | 16 | ## Motivation 17 | 18 | With the integer fallback, small changes to code can change the 19 | inferred type in unexpected ways. It's not clear how big a problem 20 | this is, but previous experiments[1] indicate that removing 21 | the fallback has a relatively small impact on existing code, 22 | so it's reasonable to back off of this feature in favor of more 23 | strict typing. 24 | 25 | See also https://github.com/mozilla/rust/issues/6023. 26 | 27 | [1]: https://gist.github.com/nikomatsakis/11179747 28 | 29 | ## Detailed design 30 | 31 | The primary change here is that, when integer type inference fails, 32 | the compiler will emit an error instead of assigning the value the 33 | type `int`. 34 | 35 | This change alone will cause a fair bit of existing code to be 36 | unable to type check because of lack of constraints. To add more 37 | constraints and increase likelihood of unification, we 'tighten' 38 | up what kinds of integers are required in some situations: 39 | 40 | * Array repeat counts must be uint (`[expr, .. count]`) 41 | * << and >> require uint when shifting integral types 42 | 43 | Finally, inference for `as` will be modified to track the types 44 | a value is being cast *to* for cases where the value being cast 45 | is unconstrained, like `0 as u8`. 46 | 47 | Treatment of enum discriminants will need to change: 48 | 49 | ``` 50 | enum Color { Red = 0, Green = 1, Blue = 2 } 51 | ``` 52 | 53 | Currently, an unsuffixed integer defaults to `int`. Instead, we will 54 | only require enum discriminants primitive integers of unspecified 55 | type; assigning an integer to an enum will behave as if casting from 56 | from the type of the integer to an unsigned integer with the size of 57 | the enum discriminant. 58 | 59 | ## Drawbacks 60 | 61 | This will force users to type hint somewhat more often. In particular, 62 | ranges of unsigned ints may need to be type-hinted: 63 | 64 | ``` 65 | for _ in range(0u, 10) { } 66 | ``` 67 | 68 | ## Alternatives 69 | 70 | Do none of this. 71 | 72 | ## Unresolved questions 73 | 74 | * If we're putting new restrictions on shift operators, should we 75 | change the traits, or just make the primitives special? 76 | -------------------------------------------------------------------------------- /text/0184-tuple-accessors.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-07-24 2 | - RFC PR #: https://github.com/rust-lang/rfcs/pull/184 3 | - Rust Issue #: https://github.com/rust-lang/rust/issues/16950 4 | 5 | ## Summary 6 | 7 | Add simple syntax for accessing values within tuples and tuple structs behind a 8 | feature gate. 9 | 10 | ## Motivation 11 | 12 | Right now accessing fields of tuples and tuple structs is incredibly painful—one 13 | must rely on pattern-matching alone to extract values. This became such a 14 | problem that twelve traits were created in the standard library 15 | (`core::tuple::Tuple*`) to make tuple value accesses easier, adding `.valN()`, 16 | `.refN()`, and `.mutN()` methods to help this. But this is not a very nice 17 | solution—it requires the traits to be implemented in the standard library, not 18 | the language, and for those traits to be imported on use. On the whole this is 19 | not a problem, because most of the time `std::prelude::*` is imported, but this 20 | is still a hack which is not a real solution to the problem at hand. It also 21 | only supports tuples of length up to twelve, which is normally not a problem but 22 | emphasises how bad the current situation is. 23 | 24 | ## Detailed design 25 | 26 | Add syntax of the form `.` for accessing values within tuples and 27 | tuple structs. This (and the functionality it provides) would only be allowed 28 | when the feature gate `tuple_indexing` is enabled. This syntax is recognised 29 | wherever an unsuffixed integer literal is found in place of the normal field or 30 | method name expected when accessing fields with `.`. Because the parser would be 31 | expecting an integer, not a float, an expression like `expr.0.1` would be a 32 | syntax error (because `0.1` would be treated as a single token). 33 | 34 | Tuple/tuple struct field access behaves the same way as accessing named fields 35 | on normal structs: 36 | 37 | ```rust 38 | // With tuple struct 39 | struct Foo(int, int); 40 | let mut foo = Foo(3, -15); 41 | foo.0 = 5; 42 | assert_eq!(foo.0, 5); 43 | 44 | // With normal struct 45 | struct Foo2 { _0: int, _1: int } 46 | let mut foo2 = Foo2 { _0: 3, _1: -15 }; 47 | foo2._0 = 5; 48 | assert_eq!(foo2._0, 5); 49 | ``` 50 | 51 | Effectively, a tuple or tuple struct field is just a normal named field with an 52 | integer for a name. 53 | 54 | ## Drawbacks 55 | 56 | This adds more complexity that is not strictly necessary. 57 | 58 | ## Alternatives 59 | 60 | Stay with the status quo. Either recommend using a struct with named fields or 61 | suggest using pattern-matching to extract values. If extracting individual 62 | fields of tuples is really necessary, the `TupleN` traits could be used instead, 63 | and something like `#[deriving(Tuple3)]` could possibly be added for tuple 64 | structs. 65 | 66 | ## Unresolved questions 67 | 68 | None. 69 | -------------------------------------------------------------------------------- /text/0356-no-module-prefixes.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-10-15 2 | - RFC PR: [rust-lang/rfcs#356](https://github.com/rust-lang/rfcs/pull/356) 3 | - Rust Issue: [rust-lang/rust#18073](https://github.com/rust-lang/rust/issues/18073) 4 | 5 | ## Summary 6 | 7 | This is a conventions RFC that proposes that the items exported from a module 8 | should *never* be prefixed with that module name. For example, we should have 9 | `io::Error`, not `io::IoError`. 10 | 11 | (An alternative design is included that special-cases overlap with the 12 | `prelude`.) 13 | 14 | ## Motivation 15 | 16 | Currently there is no clear prohibition around including the module's name as a 17 | prefix on an exported item, and it is sometimes done for type names that are 18 | feared to be "popular" (like `Error` and `Result` being `IoError` and 19 | `IoResult`) for clarity. 20 | 21 | This RFC include two designs: one that entirely rules out such prefixes, and one 22 | that rules it out *except* for names that overlap with the prelude. Pros/cons 23 | are given for each. 24 | 25 | ## Detailed design 26 | 27 | The main rule being proposed is very simple: the items exported from a module 28 | should never be prefixed with the module's name. 29 | 30 | Rationale: 31 | 32 | * Avoids needless stuttering like `io::IoError`. 33 | * Any ambiguity can be worked around: 34 | * Either qualify by the module, i.e. `io::Error`, 35 | * Or rename on import: `use io::Error as IoError`. 36 | * The rule is extremely simple and clear. 37 | 38 | Downsides: 39 | 40 | * The name may already exist in the module wanting to export it. 41 | * If that's due to explicit imports, those imports can be renamed or 42 | module-qualified (see above). 43 | * If that's due to a *prelude* conflict, however, confusion may arise due to 44 | the conventional *global* meaning of identifiers defined in the prelude 45 | (i.e., programmers do not expect prelude imports to be shadowed). 46 | 47 | Overall, the RFC author believes that *if* this convention is adopted, confusion 48 | around redefining prelude names would gradually go away, because (at least for 49 | things like `Result`) we would come to expect it. 50 | 51 | ## Alternative design 52 | 53 | An alternative rule would be to never prefix an exported item with the module's 54 | name, *except* for names that are also defined in the prelude, which *must* be 55 | prefixed by the module's name. 56 | 57 | For example, we would have `io::Error` and `io::IoResult`. 58 | 59 | Rationale: 60 | 61 | * Largely the same as the above, but less decisively. 62 | * Avoids confusion around prelude-defined names. 63 | 64 | Downsides: 65 | 66 | * Retains stuttering for some important cases, e.g. custom `Result` types, which 67 | are likely to be fairly common. 68 | * Makes it even more problematic to expand the prelude in the future. 69 | -------------------------------------------------------------------------------- /text/0221-panic.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-09-23 2 | - RFC PR #: [rust-lang/rfcs#221](https://github.com/rust-lang/rfcs/pull/221) 3 | - Rust Issue #: [rust-lang/rust#17489](https://github.com/rust-lang/rust/issues/17489) 4 | 5 | ## Summary 6 | 7 | Rename "task failure" to "task panic", and `fail!` to `panic!`. 8 | 9 | ## Motivation 10 | 11 | The current terminology of "task failure" often causes problems when 12 | writing or speaking about code. You often want to talk about the 13 | possibility of an operation that returns a `Result` "failing", but 14 | cannot because of the ambiguity with task failure. Instead, you have 15 | to speak of "the failing case" or "when the operation does not 16 | succeed" or other circumlocutions. 17 | 18 | Likewise, we use a "Failure" header in rustdoc to describe when 19 | operations may fail the task, but it would often be helpful to 20 | separate out a section describing the "Err-producing" case. 21 | 22 | We have been steadily moving away from task failure and toward 23 | `Result` as an error-handling mechanism, so we should optimize our 24 | terminology accordingly: `Result`-producing functions should be easy 25 | to describe. 26 | 27 | ## Detailed design 28 | 29 | Not much more to say here than is in the summary: rename "task 30 | failure" to "task panic" in documentation, and `fail!` to `panic!` in 31 | code. 32 | 33 | The choice of `panic` emerged from a 34 | [discuss thread](http://discuss.rust-lang.org/t/renaming-task-failure/310/20) 35 | and 36 | [workweek discussion](https://github.com/rust-lang/meeting-minutes/blob/master/workweek-2014-08-18/error-handling.md). 37 | It has precedent in a language setting in Go, and of course goes back 38 | to Kernel panics. 39 | 40 | With this choice, we can use "failure" to refer to an operation that 41 | produces `Err` or `None`, "panic" for unwinding at the task level, and 42 | "abort" for aborting the entire process. 43 | 44 | The connotations of panic seem fairly accurate: the process is not 45 | immediately ending, but it is rapidly fleeing from some problematic 46 | circumstance (by killing off tasks) until a recovery point. 47 | 48 | ## Drawbacks 49 | 50 | The term "panic" is a bit informal, which some consider a drawback. 51 | 52 | Making this change is likely to be a lot of work. 53 | 54 | ## Alternatives 55 | 56 | Other choices include: 57 | 58 | - `throw!` or `unwind!`. These options reasonably describe the current 59 | behavior of task failure, but "throw" suggests general exception 60 | handling, and both place the emphasis on the mechanism rather than 61 | the policy. We also are considering eventually adding a flag that 62 | allows `fail!` to abort the process, which would make these terms misleading. 63 | 64 | - `abort!`. Ambiguous with process abort. 65 | 66 | - `die!`. A reasonable choice, but it's not immediately obvious what 67 | is being killed. 68 | -------------------------------------------------------------------------------- /text/2509-byte-concat.md: -------------------------------------------------------------------------------- 1 | - Feature Name: concat_bytes 2 | - Start Date: 2018-07-31 3 | - RFC PR: [#2509](https://github.com/rust-lang/rfcs/pull/2509) 4 | - Rust Issue: [#87555](https://github.com/rust-lang/rust/issues/87555) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Add a macro `concat_bytes!()` to join byte sequences onto an `u8` array, 10 | the same way `concat!()` currently supports for `str` literals. 11 | 12 | ## Motivation 13 | [motivation]: #motivation 14 | 15 | `concat!()` is convenient and useful to create compile time `str` literals 16 | from `str`, `bool`, numeric and `char` literals in the code. This RFC adds an 17 | equivalent capability for `[u8]` instead of `str`. 18 | 19 | ## Guide-level explanation 20 | [guide-level-explanation]: #guide-level-explanation 21 | 22 | The `concat_bytes!()` macro concatenates literals into a byte string literal 23 | (an expression of the type `&[u8; N]`). The following literal types are 24 | supported as inputs: 25 | 26 | - byte string literals (`b"..."`) 27 | - byte literals (`b'b'`) 28 | - numeric array literals – if any literal is outside of `u8` range, it will 29 | cause a compile time error: 30 | 31 | ``` 32 | error: cannot concatenate a non-`u8` literal in a byte string literal 33 | --> $FILE:XX:YY 34 | | 35 | XX | concat_bytes!([300, 1, 2, 256], b"val"); 36 | | ^^^ ^^^ this value is larger than `255` 37 | | | 38 | | this value is larger than `255` 39 | ``` 40 | 41 | For example, `concat_bytes!(42, b"va", b'l', [1, 2])` evaluates to 42 | `[42, 118, 97, 108, 1, 2]`. 43 | 44 | ## Drawbacks 45 | [drawbacks]: #drawbacks 46 | 47 | None known. 48 | 49 | ## Rationale and alternatives 50 | [rationale-and-alternatives]: #rationale-and-alternatives 51 | 52 | `concat!` could instead be changed to sometimes produce byte literals instead of 53 | string literals, like a previous revision of this RFC proposed. This would make 54 | it hard to ensure the right output type is produced – users would have to use 55 | hacks like adding a dummy `b""` argument to force a byte literal output. 56 | 57 | An earlier version of this RFC proposed to support integer literals outside of 58 | arrays, but that was rejected since it would make the output of 59 | `byte_concat!(123, b"\n")` inconsistent with the equivalent `concat!` 60 | invocation. 61 | 62 | ## Unresolved questions 63 | [unresolved-questions]: #unresolved-questions 64 | 65 | - Should additional literal types be supported? Byte string literals are 66 | basically the same thing as byte slice references, so it might make sense to 67 | support those as well (support `&[0, 1, 2]` in addition to `[0, 1, 2]`). 68 | - What to do with string and character literals? They could either be supported 69 | with their underlying UTF-8 representation being concatenated, or rejected. 70 | -------------------------------------------------------------------------------- /text/1647-allow-self-in-where-clauses.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `allow_self_in_where_clauses` 2 | - Start Date: 2016-06-13 3 | - RFC PR: [#1647](https://github.com/rust-lang/rfcs/pull/1647) 4 | - Rust Issue: [#38864](https://github.com/rust-lang/rust/issues/38864) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | This RFC proposes allowing the `Self` type to be used in every position in trait 10 | implementations, including where clauses and other parameters to the trait being 11 | implemented. 12 | 13 | ## Motivation 14 | [motivation]: #motivation 15 | 16 | `Self` is a useful tool to have to reduce churn when the type changes for 17 | various reasons. One would expect to be able to write 18 | 19 | ```rust 20 | impl SomeTrait for MySuperLongType where 21 | Self: SomeOtherTrait, 22 | ``` 23 | 24 | but this will fail to compile today, forcing you to repeat the type, and adding 25 | one more place that has to change if the type ever changes. 26 | 27 | By this same logic, we would also like to be able to reference associated types 28 | from the traits being implemented. When dealing with generic code, patterns like 29 | this often emerge: 30 | 31 | ```rust 32 | trait MyTrait { 33 | type MyType: SomeBound; 34 | } 35 | 36 | impl MyTrait for SomeStruct where 37 | SomeOtherStruct: SomeBound, 38 | { 39 | type MyType = SomeOtherStruct; 40 | } 41 | ``` 42 | 43 | the only reason the associated type is repeated at all is to restate the bound 44 | on the associated type. It would be nice to reduce some of that duplication. 45 | 46 | ## Detailed design 47 | [design]: #detailed-design 48 | 49 | Instead of blocking `Self` from being used in the "header" of a trait impl, 50 | it will be understood to be a reference to the implementation type. For example, 51 | all of these would be valid: 52 | 53 | ```rust 54 | impl SomeTrait for SomeType where Self: SomeOtherTrait { } 55 | 56 | impl SomeTrait for SomeType { } 57 | 58 | impl SomeTrait for SomeType where SomeOtherType: SomeTrait { } 59 | 60 | impl SomeTrait for SomeType where Self::AssocType: SomeOtherTrait { 61 | AssocType = SomeOtherType; 62 | } 63 | ``` 64 | 65 | If the `Self` type is parameterized by `Self`, an error that the type definition 66 | is recursive is thrown, rather than not recognizing self. 67 | 68 | ```rust 69 | // The error here is because this would be Vec>, Vec>>, ... 70 | impl SomeTrait for Vec { } 71 | ``` 72 | 73 | ## Drawbacks 74 | [drawbacks]: #drawbacks 75 | 76 | `Self` is always less explicit than the alternative. 77 | 78 | ## Alternatives 79 | [alternatives]: #alternatives 80 | 81 | Not implementing this is an alternative, as is accepting Self only in where clauses 82 | and not other positions in the impl header. 83 | 84 | ## Unresolved questions 85 | [unresolved]: #unresolved-questions 86 | 87 | None 88 | -------------------------------------------------------------------------------- /text/0459-disallow-shadowing.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-11-29 2 | - RFC PR: [rust-lang/rfcs#459](https://github.com/rust-lang/rfcs/pull/459) 3 | - Rust Issue: [rust-lang/rust#19390](https://github.com/rust-lang/rust/issues/19390) 4 | 5 | ## Summary 6 | 7 | Disallow type/lifetime parameter shadowing. 8 | 9 | ## Motivation 10 | 11 | Today we allow type and lifetime parameters to be shadowed. This is a 12 | common source of bugs as well as confusing errors. An example of such a confusing case is: 13 | 14 | ```rust 15 | struct Foo<'a> { 16 | x: &'a int 17 | } 18 | 19 | impl<'a> Foo<'a> { 20 | fn set<'a>(&mut self, v: &'a int) { 21 | self.x = v; 22 | } 23 | } 24 | 25 | fn main() { } 26 | ``` 27 | 28 | In this example, the lifetime parameter `'a` is shadowed on the method, leading to two 29 | logically distinct lifetime parameters with the same name. This then leads to the error 30 | message: 31 | 32 | mismatched types: expected `&'a int`, found `&'a int` (lifetime mismatch) 33 | 34 | which is obviously completely unhelpful. 35 | 36 | Similar errors can occur with type parameters: 37 | 38 | ```rust 39 | struct Foo { 40 | x: T 41 | } 42 | 43 | impl Foo { 44 | fn set(&mut self, v: T) { 45 | self.x = v; 46 | } 47 | } 48 | 49 | fn main() { } 50 | ``` 51 | 52 | Compiling this program yields: 53 | 54 | mismatched types: expected `T`, found `T` (expected type parameter, found a different type parameter) 55 | 56 | Here the error message was improved by [a recent PR][pr], but this is 57 | still a somewhat confusing situation. 58 | 59 | Anecdotally, this kind of accidental shadowing is fairly frequent 60 | occurrence. It recently arose on [this discuss thread][dt], for 61 | example. 62 | 63 | [dt]: http://discuss.rust-lang.org/t/confused-by-lifetime-error-messages-tell-me-about-it/358/41?u=nikomatsakis 64 | [pr]: https://github.com/rust-lang/rust/pull/18264 65 | 66 | ## Detailed design 67 | 68 | Disallow shadowed type/lifetime parameter declarations. An error would 69 | be reported by the resolve/resolve-lifetime passes in the compiler and 70 | hence fairly early in the pipeline. 71 | 72 | ## Drawbacks 73 | 74 | We otherwise allow shadowing, so it is inconsistent. 75 | 76 | ## Alternatives 77 | 78 | We could use a lint instead. However, we'd want to ensure that the 79 | lint error messages were printed *before* type-checking begins. We 80 | could do this, perhaps, by running the lint printing pass multiple 81 | times. This might be useful in any case as the placement of lints in 82 | the compiler pipeline has proven problematic before. 83 | 84 | We could also attempt to improve the error messages. Doing so for 85 | lifetimes is definitely important in any case, but also somewhat 86 | tricky due to the extensive inference. It is usually easier and more 87 | reliable to help avoid the error in the first place. 88 | 89 | ## Unresolved questions 90 | 91 | None. 92 | -------------------------------------------------------------------------------- /text/1014-stdout-existential-crisis.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `stdout_existential_crisis` 2 | - Start Date: 2015-03-25 3 | - RFC PR: [rust-lang/rfcs#1014](https://github.com/rust-lang/rfcs/pull/1014) 4 | - Rust Issue: [rust-lang/rust#25977](https://github.com/rust-lang/rust/issues/25977) 5 | 6 | ## Summary 7 | 8 | When calling `println!` it currently causes a panic if `stdout` does not exist. Change this to ignore this specific error and simply void the output. 9 | 10 | ## Motivation 11 | 12 | On Linux `stdout` almost always exists, so when people write games and turn off the terminal there is still an `stdout` that they write to. Then when getting the code to run on Windows, when the console is disabled, suddenly `stdout` doesn't exist and `println!` panicks. This behavior difference is frustrating to developers trying to move to Windows. 13 | 14 | There is also precedent with C and C++. On both Linux and Windows, if `stdout` is closed or doesn't exist, neither platform will error when attempting to print to the console. 15 | 16 | ## Detailed design 17 | 18 | When using any of the convenience macros that write to either `stdout` or `stderr`, such as `println!` `print!` `panic!` and `assert!`, change the implementation to ignore the specific error of `stdout` or `stderr` not existing. The behavior of all other errors will be unaffected. This can be implemented by redirecting `stdout` and `stderr` to `std::io::sink` if the original handles do not exist. 19 | 20 | Update the methods `std::io::stdin` `std::io::stdout` and `std::io::stderr` as follows: 21 | * If `stdout` or `stderr` does not exist, return the equivalent of `std::io::sink`. 22 | * If `stdin` does not exist, return the equivalent of `std::io::empty`. 23 | * For the raw versions, return a `Result`, and if the respective handle does not exist, return an `Err`. 24 | 25 | ## Drawbacks 26 | 27 | * Hides an error from the user which we may want to expose and may lead to people missing panicks occurring in threads. 28 | * Some languages, such as Ruby and Python, do throw an exception when stdout is missing. 29 | 30 | ## Alternatives 31 | 32 | * Make `println!` `print!` `panic!` `assert!` return errors that the user has to handle. This would lose a large part of the convenience of these macros. 33 | * Continue with the status quo and panic if `stdout` or `stderr` doesn't exist. 34 | * For `std::io::stdin` `std::io::stdout` and `std::io::stderr`, make them return a `Result`. This would be a breaking change to the signature, so if this is desired it should be done immediately before 1.0. 35 | ** Alternatively, make the objects returned by these methods error upon attempting to write to/read from them if their respective handle doesn't exist. 36 | 37 | ## Unresolved questions 38 | 39 | * Which is better? Breaking the signatures of those three methods in `std::io`, making them silently redirect to `empty`/`sink`, or erroring upon attempting to write to/read from the handle? 40 | -------------------------------------------------------------------------------- /text/0063-module-file-system-hierarchy.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-05-02 2 | - RFC PR: [rust-lang/rfcs#63](https://github.com/rust-lang/rfcs/pull/63) 3 | - Rust Issue: [rust-lang/rust#14180](https://github.com/rust-lang/rust/issues/14180) 4 | 5 | ## Summary 6 | 7 | The rules about the places `mod foo;` can be used are tightened to only permit 8 | its use in a crate root and in `mod.rs` files, to ensure a more sane 9 | correspondence between module structure and file system hierarchy. Most 10 | notably, this prevents a common newbie error where a module is loaded multiple 11 | times, leading to surprising incompatibility between them. This proposal does 12 | not take away one's ability to shoot oneself in the foot should one really 13 | desire to; it just removes almost all of the rope, leaving only mixed 14 | metaphors. 15 | 16 | ## Motivation 17 | 18 | It is a common newbie mistake to write things like this: 19 | 20 | `lib.rs`: 21 | 22 | ```rust 23 | mod foo; 24 | pub mod bar; 25 | ``` 26 | 27 | `foo.rs`: 28 | 29 | ```rust 30 | mod baz; 31 | 32 | pub fn foo(_baz: baz::Baz) { } 33 | ``` 34 | 35 | `bar.rs`: 36 | 37 | ```rust 38 | mod baz; 39 | use foo::foo; 40 | 41 | pub fn bar(baz: baz::Baz) { 42 | foo(baz) 43 | } 44 | ``` 45 | 46 | `baz.rs`: 47 | 48 | ```rust 49 | pub struct Baz; 50 | ``` 51 | 52 | This fails to compile because `foo::foo()` wants a `foo::baz::Baz`, while 53 | `bar::bar()` is giving it a `bar::baz::Baz`. 54 | 55 | Such a situation, importing one file multiple times, is exceedingly rarely what 56 | the user actually wanted to do, but the present design allows it to occur 57 | without warning the user. The alterations contained herein ensure that there is 58 | no situation where such double loading can occur without deliberate intent via 59 | `#[path = "….rs"]`. 60 | 61 | ## Drawbacks 62 | 63 | None known. 64 | 65 | ## Detailed design 66 | 67 | When a `mod foo;` statement is used, the compiler attempts to find a suitable 68 | file. At present, it just blindly seeks for `foo.rs` or `foo/mod.rs` (relative 69 | to the file under parsing). 70 | 71 | The new behaviour will only permit `mod foo;` if at least one of the following 72 | conditions hold: 73 | 74 | - The file under parsing is the crate root, or 75 | 76 | - The file under parsing is a `mod.rs`, or 77 | 78 | - `#[path]` is specified, e.g. `#[path = "foo.rs"] mod foo;`. 79 | 80 | In layman's terms, the file under parsing must "own" the directory, so to 81 | speak. 82 | 83 | ## Alternatives 84 | 85 | The rationale is covered in the summary. This is the simplest repair to the 86 | current lack of structure; all alternatives would be more complex and invasive. 87 | 88 | One non-invasive alternative is a lint which would detect double loads. This is 89 | less desirable than the solution discussed in this RFC as it doesn't fix the 90 | underlying problem which can, fortunately, be fairly easily fixed. 91 | 92 | ## Unresolved questions 93 | 94 | None. 95 | -------------------------------------------------------------------------------- /text/2230-bury-description.md: -------------------------------------------------------------------------------- 1 | - Feature Name: optional_error_description 2 | - Start Date: 2017-11-29 3 | - RFC PR: [rust-lang/rfcs#2230](https://github.com/rust-lang/rfcs/pull/2230) 4 | - Rust Issue: (leave this empty) 5 | 6 | ## Default implementation of `Error::description()` 7 | [summary]: #summary 8 | 9 | Provide a default implementation of the `Error` trait's `description()` method to save users trouble of implementing this flawed method. 10 | 11 | ## Motivation 12 | [motivation]: #motivation 13 | 14 | The `description()` method is a waste of time for implementors and users of the `Error` trait. There's high overlap between description and `Display`, which creates redundant implementation work and confusion about relationship of these two ways of displaying the error. 15 | 16 | The `description()` method can't easily return a formatted string with per-instance error description. That's a gotcha for novice users struggling with the borrow checker, and gotcha for users trying to display the error, because the `description()` is going to return a less informative message than the `Display` trait. 17 | 18 | ## Guide-level explanation 19 | [guide-level-explanation]: #guide-level-explanation 20 | 21 | Let's steer users away from the `description()` method. 22 | 23 | 1. Change the `description()` documentation to suggest use of the `Display` trait instead. 24 | 2. Provide a default implementation of the `description()` so that the `Error` trait can be implemented without worrying about this method. 25 | 26 | ## Reference-level explanation 27 | [reference-level-explanation]: #reference-level-explanation 28 | 29 | Users of the `Error` trait can then pretend this method does not exist. 30 | 31 | ## Drawbacks 32 | [drawbacks]: #drawbacks 33 | 34 | When users start omitting bespoke `description()` implementations, code that still uses this method will start getting default strings instead of human-written description. If this becomes a problem, the `description()` method can also be formally deprecated (with the `#[deprecated]` attribute). However, there's no urgency to remove existing implementations of `description()`, so this RFC does not propose formal deprecation at this time to avoid unnecessary warnings during the transition. 35 | 36 | ## Rationale and alternatives 37 | [alternatives]: #alternatives 38 | 39 | - Do nothing, and rely on 3rd party crates to improve usability of errors (e.g. various crates providing `Error`-implementing macros or the `Fail` trait). 40 | - The default message returned by `description` could be different. 41 | - it could be a hardcoded generic string, e.g. `"error"`, 42 | - it could return `core::intrinsics::type_name::()`, 43 | - it could try to be nicer, e.g. use the type's doccomment as the description, or convert type name to a sentence (`FileNotFoundError` -> "error: file not found"). 44 | 45 | ## Unresolved questions 46 | [unresolved]: #unresolved-questions 47 | 48 | None yet. 49 | -------------------------------------------------------------------------------- /text/1434-contains-method-for-ranges.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `contains_method` 2 | - Start Date: 2015-12-28 3 | - RFC PR: [rust-lang/rfcs#1434](https://github.com/rust-lang/rfcs/pull/1434) 4 | - Rust Issue: [rust-lang/rust#32311](https://github.com/rust-lang/rust/issues/32311) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Implement a method, `contains()`, for `Range`, `RangeFrom`, and `RangeTo`, checking if a number is in the range. 10 | 11 | Note that the alternatives are just as important as the main proposal. 12 | 13 | ## Motivation 14 | [motivation]: #motivation 15 | 16 | The motivation behind this is simple: To be able to write simpler and more expressive code. This RFC introduces a "syntactic sugar" without doing so. 17 | 18 | ## Detailed design 19 | [design]: #detailed-design 20 | 21 | Implement a method, `contains()`, for `Range`, `RangeFrom`, and `RangeTo`. This method will check if a number is bound by the range. It will yield a boolean based on the condition defined by the range. 22 | 23 | The implementation is as follows (placed in libcore, and reexported by libstd): 24 | 25 | ```rust 26 | use core::ops::{Range, RangeTo, RangeFrom}; 27 | 28 | impl Range where Idx: PartialOrd { 29 | fn contains(&self, item: Idx) -> bool { 30 | self.start <= item && self.end > item 31 | } 32 | } 33 | 34 | impl RangeTo where Idx: PartialOrd { 35 | fn contains(&self, item: Idx) -> bool { 36 | self.end > item 37 | } 38 | } 39 | 40 | impl RangeFrom where Idx: PartialOrd { 41 | fn contains(&self, item: Idx) -> bool { 42 | self.start <= item 43 | } 44 | } 45 | 46 | ``` 47 | 48 | ## Drawbacks 49 | [drawbacks]: #drawbacks 50 | 51 | Lacks of generics (see Alternatives). 52 | 53 | ## Alternatives 54 | [alternatives]: #alternatives 55 | 56 | ### Add a `Contains` trait 57 | 58 | This trait provides the method `.contains()` and implements it for all the Range types. 59 | 60 | ### Add a `.contains>(i: I)` iterator method 61 | 62 | This method returns a boolean, telling if the iterator contains the item given as parameter. Using method specialization, this can achieve the same performance as the method suggested in this RFC. 63 | 64 | This is more flexible, and provide better performance (due to specialization) than just passing a closure comparing the items to a `any()` method. 65 | 66 | ### Make `.any()` generic over a new trait 67 | 68 | Call this trait, `ItemPattern`. This trait is implemented for `Item` and `FnMut(Item) -> bool`. This is, in a sense, similar to `std::str::pattern::Pattern`. 69 | 70 | Then let `.any()` generic over this trait (`T: ItemPattern`) to allow `any()` taking `Self::Item` searching through the iterator for this particular value. 71 | 72 | This will not achieve the same performance as the other proposals. 73 | 74 | ## Unresolved questions 75 | [unresolved]: #unresolved-questions 76 | 77 | None. 78 | -------------------------------------------------------------------------------- /text/1521-copy-clone-semantics.md: -------------------------------------------------------------------------------- 1 | - Feature Name: N/A 2 | - Start Date: 2016-03-01 3 | - RFC PR: [rust-lang/rfcs#1521](https://github.com/rust-lang/rfcs/pull/1521) 4 | - Rust Issue: [rust-lang/rust#33416](https://github.com/rust-lang/rust/issues/33416) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | With specialization on the way, we need to talk about the semantics of 10 | `::clone() where T: Copy`. 11 | 12 | It's generally been an unspoken rule of Rust that a `clone` of a `Copy` type is 13 | equivalent to a `memcpy` of that type; however, that fact is not documented 14 | anywhere. This fact should be in the documentation for the `Clone` trait, just 15 | like the fact that `T: Eq` should implement `a == b == c == a` rules. 16 | 17 | ## Motivation 18 | [motivation]: #motivation 19 | 20 | Currently, `Vec::clone()` is implemented by creating a new `Vec`, and then 21 | cloning all of the elements from one into the other. This is slow in debug mode, 22 | and may not always be optimized (although it often will be). Specialization 23 | would allow us to simply `memcpy` the values from the old `Vec` to the new 24 | `Vec` in the case of `T: Copy`. However, if we don't specify this, we will not 25 | be able to, and we will be stuck looping over every value. 26 | 27 | It's always been the intention that `Clone::clone == ptr::read for T: Copy`; see 28 | [issue #23790][issue-copy]: "It really makes sense for `Clone` to be a 29 | supertrait of `Copy` -- `Copy` is a refinement of `Clone` where `memcpy` 30 | suffices, basically." This idea was also implicit in accepting 31 | [rfc #0839][rfc-extend] where "[B]ecause Copy: Clone, it would be backwards 32 | compatible to upgrade to Clone in the future if demand is high enough." 33 | 34 | ## Detailed design 35 | [design]: #detailed-design 36 | 37 | Specify that `::clone(t)` shall be equivalent to `ptr::read(t)` 38 | where `T: Copy, t: &T`. An implementation that does not uphold this *shall not* 39 | result in undefined behavior; `Clone` is not an `unsafe trait`. 40 | 41 | Also add something like the following sentence to the documentation for the 42 | `Clone` trait: 43 | 44 | "If `T: Copy`, `x: T`, and `y: &T`, then `let x = y.clone();` is equivalent to 45 | `let x = *y;`. Manual implementations must be careful to uphold this." 46 | 47 | ## Drawbacks 48 | [drawbacks]: #drawbacks 49 | 50 | This is a breaking change, technically, although it breaks code that was 51 | malformed in the first place. 52 | 53 | ## Alternatives 54 | [alternatives]: #alternatives 55 | 56 | The alternative is that, for each type and function we would like to specialize 57 | in this way, we document this separately. This is how we started off with 58 | `clone_from_slice`. 59 | 60 | ## Unresolved questions 61 | [unresolved]: #unresolved-questions 62 | 63 | What the exact wording should be. 64 | 65 | [issue-copy]: https://github.com/rust-lang/rust/issues/23790 66 | [rfc-extend]: https://github.com/rust-lang/rfcs/blob/master/text/0839-embrace-extend-extinguish.md 67 | -------------------------------------------------------------------------------- /text/1983-nursery-deprecation.md: -------------------------------------------------------------------------------- 1 | - Feature Name: N/A 2 | - Start Date: 2017-04-26 3 | - RFC PR: [rust-lang/rfcs#1983](https://github.com/rust-lang/rfcs/pull/1983) 4 | - Rust Issue: N/A 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Amend [RFC 1242] to require an RFC for deprecation of crates from the 10 | rust-lang-nursery. 11 | 12 | [RFC 1242]: https://github.com/rust-lang/rfcs/blob/master/text/1242-rust-lang-crates.md 13 | 14 | ## Motivation 15 | [motivation]: #motivation 16 | 17 | There are currently very ubiquitous crates in the nursery that are being used 18 | by lots and lots of people, as evidenced by the crates.io download numbers (for 19 | lack of a better popularity metric): 20 | 21 | | Nursery crate | Downloads | 22 | | ------------- | --------- | 23 | | bitflags | 3,156k | 24 | | rand | 2,615k | 25 | | log | 2,417k | 26 | | lazy-static | 2,108k | 27 | | tempdir | 934k | 28 | | uuid | 759k | 29 | | glob | 467k | 30 | | net2 | 452k | 31 | | getopts | 452k | 32 | | rustfmt | 80k | 33 | | simd | 14k | 34 | 35 | (numbers as of 2017-04-26) 36 | 37 | [RFC 1242] currently specifies that 38 | 39 | > The libs subteam can deprecate nursery crates at any time 40 | 41 | The libs team can of course be trusted to be judicious in making such 42 | decisions. However, considering that many of the nursery crates are depended on 43 | by big fractions of the Rust ecosystem, suddenly deprecating things without 44 | public discussion seems contrary to Rust's philosophy of stability and 45 | community participation. Involving the Rust community at large in these 46 | decisions offers the benefits of the RFC process such as increased visibility, 47 | differing viewpoints, and transparency. 48 | 49 | ## Detailed design 50 | [design]: #detailed-design 51 | 52 | The exact amendment is included as a change to the RFC in this PR. 53 | [View the amended text](1242-rust-lang-crates.md). 54 | 55 | ## How We Teach This 56 | [how-we-teach-this]: #how-we-teach-this 57 | 58 | N/A 59 | 60 | ## Drawbacks 61 | [drawbacks]: #drawbacks 62 | 63 | Requiring an RFC for deprecation might impose an undue burden on the library 64 | subteam in terms of crate maintenance. However, as [RFC 1242] states, this is 65 | not a major commitment. 66 | 67 | Acceptance into the nursery could be hindered if it is believed it could be 68 | hard to reverse course later due to the required RFC being perceived as an 69 | obstacle. On the other hand, RFCs with broad consensus do not generally impose 70 | a large procedural burden, and if there is no consensus it might be too early 71 | to deprecate a nursery crate anyway. 72 | 73 | ## Alternatives 74 | [alternatives]: #alternatives 75 | 76 | Don't change the process and let the library subteam make deprecation decisions 77 | for nursery crates. 78 | 79 | ## Unresolved questions 80 | [unresolved]: #unresolved-questions 81 | 82 | None as of yet. 83 | -------------------------------------------------------------------------------- /text/0179-and-mut-patterns.md: -------------------------------------------------------------------------------- 1 | - Start Date: 23-07-2014 2 | - RFC PR: [rust-lang/rfcs#179](https://github.com/rust-lang/rfcs/pull/179) 3 | - Rust Issue: [rust-lang/rust#20496](https://github.com/rust-lang/rust/issues/20496) 4 | 5 | ## Summary 6 | 7 | Change pattern matching on an `&mut T` to `&mut `, away from its 8 | current `&` syntax. 9 | 10 | ## Motivation 11 | 12 | Pattern matching mirrors construction for almost all types, *except* 13 | `&mut`, which is constructed with `&mut ` but destructured with 14 | `&`. This is almost certainly an unnecessary inconsistency. 15 | 16 | This can and does lead to confusion, since people expect the pattern 17 | syntax to match construction, but a pattern like `&mut (ref mut x, _)` is 18 | actually currently a parse error: 19 | 20 | ```rust 21 | fn main() { 22 | let &mut (ref mut x, _); 23 | } 24 | ``` 25 | 26 | ``` 27 | and-mut-pat.rs:2:10: 2:13 error: expected identifier, found path 28 | and-mut-pat.rs:2 let &mut (ref mut x, _); 29 | ^~~ 30 | ``` 31 | 32 | 33 | Another (rarer) way it can be confusing is the pattern `&mut x`. It is 34 | expected that this binds `x` to the contents of `&mut T` 35 | pointer... which it does, but as a mutable binding (it is parsed as 36 | `&(mut x)`), meaning something like 37 | 38 | ```rust 39 | for &mut x in some_iterator_over_and_mut { 40 | println!("{}", x) 41 | } 42 | ``` 43 | 44 | gives an unused mutability warning. NB. it's somewhat rare that one 45 | would want to pattern match to directly bind a name to the contents of 46 | a `&mut` (since the normal reason to have a `&mut` is to mutate the 47 | thing it points at, but this pattern is (byte) copying the data out, 48 | both before and after this change), but can occur if a type only 49 | offers a `&mut` iterator, i.e. types for which a `&` one is no more 50 | flexible than the `&mut` one. 51 | 52 | ## Detailed design 53 | 54 | Add ` := &mut ` to the pattern grammar, and require that it is used 55 | when matching on a `&mut T`. 56 | 57 | ## Drawbacks 58 | 59 | It makes matching through a `&mut` more verbose: `for &mut (ref mut x, 60 | p_) in v.mut_iter()` instead of `for &(ref mut x, _) in 61 | v.mut_iter()`. 62 | 63 | Macros wishing to pattern match on either `&` or `&mut` need to handle 64 | each case, rather than performing both with a single `&`. However, 65 | macros handling these types already need special `mut` vs. not 66 | handling if they ever name the types, or if they use `ref` vs. `ref 67 | mut` subpatterns. 68 | 69 | It also makes obtaining the current behaviour (binding by-value the 70 | contents of a reference to a mutable local) slightly harder. For a 71 | `&mut T` the pattern becomes `&mut mut x`, and, at the moment, for a 72 | `&T`, it must be matched with `&x` and then rebound with `let mut x = 73 | x;` (since disambiguating like `&(mut x)` doesn't yet work). However, 74 | based on some loose grepping of the Rust repo, both of these are very 75 | rare. 76 | 77 | ## Alternatives 78 | 79 | None. 80 | 81 | ## Unresolved questions 82 | 83 | None. 84 | -------------------------------------------------------------------------------- /text/0572-rustc-attribute.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-11 2 | - RFC PR: [#572](https://github.com/rust-lang/rfcs/pull/572) 3 | - Rust Issue: [#22203](https://github.com/rust-lang/rust/issues/22203) 4 | 5 | ## Summary 6 | 7 | Feature gate unused attributes for backwards compatibility. 8 | 9 | ## Motivation 10 | 11 | Interpreting the current backwards compatibility rules strictly, it's not possible to add any further 12 | language features that use new attributes. For example, if we wish to add a feature that expands 13 | the attribute `#[awesome_deriving(Encodable)]` into an implementation of `Encodable`, any existing code that 14 | contains uses of the `#[awesome_deriving]` attribute might be broken. While such attributes are useless in release 1.0 code 15 | (since syntax extensions aren't allowed yet), we still have a case of code that stops compiling after an update of a release build. 16 | 17 | 18 | ## Detailed design 19 | 20 | We add a feature gate, `custom_attribute`, that disallows the use of any attributes not defined by the compiler or consumed in any other way. 21 | 22 | This is achieved by elevating the `unused_attribute` lint to a feature gate check (with the gate open, it reverts to being a lint). We'd also need to ensure that it runs after all the other lints (currently it runs as part of the main lint check and might warn about attributes which are actually consumed by other lints later on). 23 | 24 | Eventually, we can try for a namespacing system as described below, however with unused attributes feature gated, we need not worry about it until we start considering stabilizing plugins. 25 | 26 | ## Drawbacks 27 | 28 | I don't see much of a drawback (except that the alternatives below might be more lucrative). This might make it harder for people who wish to use custom attributes for static analysis in 1.0 code. 29 | 30 | ## Alternatives 31 | 32 | ### Forbid `#[rustc_*]` and `#[rustc(...)]` attributes 33 | 34 | (This was the original proposal in the RfC) 35 | 36 | This is less restrictive for the user, but it restricts us to a form of namespacing for any future attributes which we may wish to introduce. This is suboptimal, since by the time plugins stabilize (which is when user-defined attributes become useful for release code) we may add many more attributes to the compiler and they will all have cumbersome names. 37 | 38 | ### Do nothing 39 | 40 | If we do nothing we can still manage to add new attributes, however we will need to invent new syntax for it. This will probably be in the form of basic namespacing support 41 | (`#[rustc::awesome_deriving]`) or arbitrary token tree support (the use case will probably still end up looking something like `#[rustc::awesome_deriving]`) 42 | 43 | This has the drawback that the attribute parsing and representation will need to be overhauled before being able to add any new attributes to the compiler. 44 | 45 | ## Unresolved questions 46 | 47 | Which proposal to use — disallowing `#[rustc_*]` and `#[rustc]` attributes, or just `#[forbid(unused_attribute)]`ing everything. 48 | 49 | The name of the feature gate could perhaps be improved. 50 | -------------------------------------------------------------------------------- /text/1131-likely-intrinsic.md: -------------------------------------------------------------------------------- 1 | - Feature Name: expect_intrinsic 2 | - Start Date: 2015-05-20 3 | - RFC PR: [rust-lang/rfcs#1131](https://github.com/rust-lang/rfcs/pull/1131) 4 | - Rust Issue: [rust-lang/rust#26179](https://github.com/rust-lang/rust/issues/26179) 5 | 6 | ## Summary 7 | 8 | Provide a pair of intrinsic functions for hinting the likelihood of branches being taken. 9 | 10 | ## Motivation 11 | 12 | Branch prediction can have significant effects on the running time of some code. Especially tight 13 | inner loops which may be run millions of times. While in general programmers aren't able to 14 | effectively provide hints to the compiler, there are cases where the likelihood of some branch 15 | being taken can be known. 16 | 17 | For example: in arbitrary-precision arithmetic, operations are often performed in a base that is 18 | equal to `2^word_size`. The most basic division algorithm, "Schoolbook Division", has a step that 19 | will be taken in `2/B` cases (where `B` is the base the numbers are in), given random input. On a 20 | 32-bit processor that is approximately one in two billion cases, for 64-bit it's one in 18 21 | quintillion cases. 22 | 23 | ## Detailed design 24 | 25 | Implement a pair of intrinsics `likely` and `unlikely`, both with signature `fn(bool) -> bool` 26 | which hint at the probability of the passed value being true or false. Specifically, `likely` hints 27 | to the compiler that the passed value is likely to be true, and `unlikely` hints that it is likely 28 | to be false. Both functions simply return the value they are passed. 29 | 30 | The primary reason for this design is that it reflects common usage of this general feature in many 31 | C and C++ projects, most of which define simple `LIKELY` and `UNLIKELY` macros around the gcc 32 | `__builtin_expect` intrinsic. It also provides the most flexibility, allowing branches on any 33 | condition to be hinted at, even if the process that produced the branched-upon value is 34 | complex. For why an equivalent to `__builtin_expect` is not being exposed, see the Alternatives 35 | section. 36 | 37 | There are no observable changes in behaviour from use of these intrinsics. It is valid to implement 38 | these intrinsics simply as the identity function. Though it is expected that the intrinsics provide 39 | information to the optimizer, that information is not guaranteed to change the decisions the 40 | optimiser makes. 41 | 42 | ## Drawbacks 43 | 44 | The intrinsics cannot be used to hint at arms in `match` expressions. However, given that hints 45 | would need to be variants, a simple intrinsic would not be sufficient for those purposes. 46 | 47 | ## Alternatives 48 | 49 | Expose an `expect` intrinsic. This is what gcc/clang does with `__builtin_expect`. However there is 50 | a restriction that the second argument be a constant value, a requirement that is not easily 51 | expressible in Rust code. The split into `likely` and `unlikely` intrinsics reflects the strategy 52 | we have used for similar restrictions like the ordering constraint of the atomic intrinsics. 53 | 54 | ## Unresolved questions 55 | 56 | None. 57 | -------------------------------------------------------------------------------- /text/0378-expr-macros.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-10-09 2 | - RFC PR #: https://github.com/rust-lang/rfcs/pull/378 3 | - Rust Issue #: https://github.com/rust-lang/rust/issues/18635 4 | 5 | ## Summary 6 | 7 | Parse macro invocations with parentheses or square brackets as expressions no 8 | matter the context, and require curly braces or a semicolon following the 9 | invocation to invoke a macro as a statement. 10 | 11 | ## Motivation 12 | 13 | Currently, macros that start a statement want to be a whole statement, and so 14 | expressions such as `foo!().bar` don’t parse if they start a statement. The 15 | reason for this is because sometimes one wants a macro that expands to an item 16 | or statement (for example, `macro_rules!`), and forcing the user to add a 17 | semicolon to the end is annoying and easy to forget for long, multi-line 18 | statements. However, the vast majority of macro invocations are not intended to 19 | expand to an item or statement, leading to frustrating parser errors. 20 | 21 | Unfortunately, this is not as easy to resolve as simply checking for an infix 22 | operator after every statement-like macro invocation, because there exist 23 | operators that are both infix and prefix. For example, consider the following 24 | function: 25 | 26 | ```rust 27 | fn frob(x: int) -> int { 28 | maybe_return!(x) 29 | // Provide a default value 30 | -1 31 | } 32 | ``` 33 | 34 | Today, this parses successfully. However, if a rule were added to the parser 35 | that any macro invocation followed by an infix operator be parsed as a single 36 | expression, this would still parse successfully, but not in the way expected: it 37 | would be parsed as `(maybe_return!(x)) - 1`. This is an example of how it is 38 | impossible to resolve this ambiguity properly without breaking compatibility. 39 | 40 | ## Detailed design 41 | 42 | Treat all macro invocations with parentheses, `()`, or square brackets, `[]`, as 43 | expressions, and never attempt to parse them as statements or items in a block 44 | context unless they are followed directly by a semicolon. Require all 45 | item-position macro invocations to be either invoked with curly braces, `{}`, or 46 | be followed by a semicolon (for consistency). 47 | 48 | This distinction between parentheses and curly braces has precedent in Rust: 49 | tuple structs, which use parentheses, must be followed by a semicolon, while 50 | structs with fields do not need to be followed by a semicolon. Many constructs 51 | like `match` and `if`, which use curly braces, also do not require semicolons 52 | when they begin a statement. 53 | 54 | ## Drawbacks 55 | 56 | - This introduces a difference between different macro invocation delimiters, 57 | where previously there was no difference. 58 | - This requires the use of semicolons in a few places where it was not necessary 59 | before. 60 | 61 | ## Alternatives 62 | 63 | - Require semicolons after all macro invocations that aren’t being used as 64 | expressions. This would have the downside of requiring semicolons after every 65 | `macro_rules!` declaration. 66 | 67 | ## Unresolved questions 68 | 69 | None. 70 | -------------------------------------------------------------------------------- /text/1054-str-words.md: -------------------------------------------------------------------------------- 1 | - Feature Name: str-words 2 | - Start Date: 2015-04-10 3 | - RFC PR: [rust-lang/rfcs#1054](https://github.com/rust-lang/rfcs/pull/1054) 4 | - Rust Issue: [rust-lang/rust#24543](https://github.com/rust-lang/rust/issues/24543) 5 | 6 | ## Summary 7 | 8 | Rename or replace `str::words` to side-step the ambiguity of “a word”. 9 | 10 | 11 | ## Motivation 12 | 13 | The [`str::words`](http://doc.rust-lang.org/std/primitive.str.html#method.words) method 14 | is currently marked `#[unstable(reason = "the precise algorithm to use is unclear")]`. 15 | Indeed, the concept of “a word” is not easy to define in presence of punctuation 16 | or languages with various conventions, including not using spaces at all to separate words. 17 | 18 | [Issue #15628](https://github.com/rust-lang/rust/issues/15628) suggests 19 | changing the algorithm to be based on [the *Word Boundaries* section of 20 | *Unicode Standard Annex #29: Unicode Text Segmentation*](http://www.unicode.org/reports/tr29/#Word_Boundaries). 21 | 22 | While a Rust implementation of UAX#29 would be useful, it belong on crates.io more than in `std`: 23 | 24 | * It carries significant complexity that may be surprising from something that looks as simple 25 | as a parameter-less “words” method in the standard library. 26 | Users may not be aware of how subtle defining “a word” can be. 27 | * It is not a definitive answer. The standard itself notes: 28 | 29 | > It is not possible to provide a uniform set of rules that resolves all issues across languages 30 | > or that handles all ambiguous situations within a given language. 31 | > The goal for the specification presented in this annex is to provide a workable default; 32 | > tailored implementations can be more sophisticated. 33 | 34 | and gives many examples of such ambiguous situations. 35 | 36 | Therefore, `std` would be better off avoiding the question of defining word boundaries entirely. 37 | 38 | 39 | ## Detailed design 40 | 41 | Rename the `words` method to `split_whitespace`, and keep the current behavior unchanged. 42 | (That is, return an iterator equivalent to `s.split(char::is_whitespace).filter(|s| !s.is_empty())`.) 43 | 44 | Rename the return type `std::str::Words` to `std::str::SplitWhitespace`. 45 | 46 | Optionally, keep a `words` wrapper method for a while, both `#[deprecated]` and `#[unstable]`, 47 | with an error message that suggests `split_whitespace` or the chosen alternative. 48 | 49 | 50 | ## Drawbacks 51 | 52 | `split_whitespace` is very similar to the existing `str::split(&self, P)` method, 53 | and having a separate method seems like weak API design. (But see below.) 54 | 55 | 56 | ## Alternatives 57 | 58 | * Replace `str::words` with `struct Whitespace;` with a custom `Pattern` implementation, 59 | which can be used in `str::split`. 60 | However this requires the `Whitespace` symbol to be imported separately. 61 | * Remove `str::words` entirely and tell users to use 62 | `s.split(char::is_whitespace).filter(|s| !s.is_empty())` instead. 63 | 64 | 65 | ## Unresolved questions 66 | 67 | Is there a better alternative? 68 | -------------------------------------------------------------------------------- /text/0446-es6-unicode-escapes.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-11-05 2 | - RFC PR: [rust-lang/rfcs#446](https://github.com/rust-lang/rfcs/pull/446) 3 | - Rust Issue: [rust-lang/rust#19739](https://github.com/rust-lang/rust/issues/19739) 4 | 5 | ## Summary 6 | 7 | Remove `\u203D` and `\U0001F4A9` unicode string escapes, and add 8 | [ECMAScript 6-style](https://mathiasbynens.be/notes/javascript-escapes#unicode-code-point) 9 | `\u{1F4A9}` escapes instead. 10 | 11 | ## Motivation 12 | 13 | The syntax of `\u` followed by four hexadecimal digits dates from when Unicode 14 | was a 16-bit encoding, and only went up to U+FFFF. 15 | `\U` followed by eight hex digits was added as a band-aid 16 | when Unicode was extended to U+10FFFF, 17 | but neither four nor eight digits particularly make sense now. 18 | 19 | Having two different syntaxes with the same meaning but that apply 20 | to different ranges of values is inconsistent and arbitrary. 21 | This proposal unifies them into a single syntax that has a precedent 22 | in ECMAScript a.k.a. JavaScript. 23 | 24 | 25 | ## Detailed design 26 | 27 | In terms of the grammar in [The Rust Reference]( 28 | http://doc.rust-lang.org/reference.html#character-and-string-literals), 29 | replace: 30 | 31 | ``` 32 | unicode_escape : 'u' hex_digit 4 33 | | 'U' hex_digit 8 ; 34 | ``` 35 | 36 | with 37 | 38 | ``` 39 | unicode_escape : 'u' '{' hex_digit+ 6 '}' 40 | ``` 41 | 42 | That is, `\u{` followed by one to six hexadecimal digits, followed by `}`. 43 | 44 | The behavior would otherwise be identical. 45 | 46 | ### Migration strategy 47 | 48 | In order to provide a graceful transition from the old `\uDDDD` and 49 | `\UDDDDDDDD` syntax to the new `\u{DDDDD}` syntax, this feature 50 | should be added in stages: 51 | 52 | * Stage 1: Add support for the new `\u{DDDDD}` syntax, without removing 53 | previous support for `\uDDDD` and `\UDDDDDDDD`. 54 | 55 | * Stage 2: Warn on occurrences of `\uDDDD` and `\UDDDDDDDD`. Convert 56 | all library code to use `\u{DDDDD}` instead of the old syntax. 57 | 58 | * Stage 3: Remove support for the old syntax entirely (preferably 59 | during a separate release from the one that added the warning from 60 | Stage 2). 61 | 62 | ## Drawbacks 63 | 64 | * This is a breaking change and updating code for it manually is annoying. 65 | It is however very mechanical, and we could provide scripts to automate it. 66 | * Formatting templates already use curly braces. 67 | Having multiple curly braces pairs in the same strings that have a very 68 | different meaning can be surprising: 69 | `format!("\u{e8}_{e8}", e8 = "é")` would be `"è_é"`. 70 | However, there is a precedent of overriding characters: 71 | `\` can start an escape sequence both in the Rust lexer for strings 72 | and in regular expressions. 73 | 74 | 75 | ## Alternatives 76 | 77 | * Status quo: don’t change the escaping syntax. 78 | * Add the new `\u{…}` syntax, but also keep the existing `\u` and `\U` syntax. 79 | This is what ES 6 does, but only to keep compatibility with ES 5. 80 | We don’t have that constraint pre-1.0. 81 | 82 | ## Unresolved questions 83 | 84 | None so far. 85 | -------------------------------------------------------------------------------- /text/0558-require-parentheses-for-chained-comparisons.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-07 2 | - RFC PR: [rust-lang/rfcs#558](https://github.com/rust-lang/rfcs/pull/558) 3 | - Rust Issue: [rust-lang/rust#20724](https://github.com/rust-lang/rust/issues/20724) 4 | 5 | ## Summary 6 | 7 | Remove chaining of comparison operators (e.g. `a == b == c`) from the syntax. 8 | Instead, require extra parentheses (`(a == b) == c`). 9 | 10 | ## Motivation 11 | 12 | ```rust 13 | fn f(a: bool, b: bool, c: bool) -> bool { 14 | a == b == c 15 | } 16 | ``` 17 | 18 | This code is currently accepted and is evaluated as `((a == b) == c)`. 19 | This may be confusing to programmers coming from languages like Python, 20 | where chained comparison operators are evaluated as `(a == b && b == c)`. 21 | 22 | In C, the same problem exists (and is exacerbated by implicit conversions). 23 | Styleguides like Misra-C require the use of parentheses in this case. 24 | 25 | By requiring the use of parentheses, we avoid potential confusion now, 26 | and open up the possibility for python-like chained comparisons post-1.0. 27 | 28 | Additionally, making the chain `f < b > (c)` invalid allows us to easily produce 29 | a diagnostic message: "Use `::<` instead of `<` if you meant to specify type arguments.", 30 | which would be a vast improvement over the current diagnostics for this mistake. 31 | 32 | ## Detailed design 33 | 34 | Emit a syntax error when a comparison operator appears as an operand of another comparison operator 35 | (without being surrounded by parentheses). 36 | The comparison operators are `<` `>` `<=` `>=` `==` and `!=`. 37 | 38 | This is easily implemented directly in the parser. 39 | 40 | Note that this restriction on accepted syntax will effectively merge the precedence level 4 (`<` `>` `<=` `>=`) with level 3 (`==` `!=`). 41 | 42 | ## Drawbacks 43 | 44 | It's a breaking change. 45 | 46 | In particular, code that currently uses the difference between precedence level 3 and 4 breaks 47 | and will require the use of parentheses: 48 | 49 | ```rust 50 | if a < 0 == b < 0 { /* both negative or both non-negative */ } 51 | ``` 52 | 53 | However, I don't think this kind of code sees much use. 54 | The rustc codebase doesn't seem to have any occurrences of chained comparisons. 55 | 56 | ## Alternatives 57 | 58 | As this RFC just makes the chained comparison syntax available for post-1.0 language features, 59 | pretty much every alternative (including returning to the status quo) can still be implemented later. 60 | 61 | If this RFC is not accepted, it will be impossible to add python-style chained comparison operators later. 62 | 63 | A variation on this RFC would be to keep the separation between precedence level 3 and 4, and only reject programs 64 | where a comparison operator appears as an operand of another comparison operator of the same precedence level. 65 | This minimizes the breaking changes, but does not allow full python-style chained comparison operators in the future 66 | (although a more limited form of them would still be possible). 67 | 68 | ## Unresolved questions 69 | 70 | Is there real code that would get broken by this change? 71 | So far, I've been unable to find any. 72 | -------------------------------------------------------------------------------- /text/0574-drain-range.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-12 2 | - RFC PR #: https://github.com/rust-lang/rfcs/pull/574 3 | - Rust Issue #: https://github.com/rust-lang/rust/issues/23055 4 | 5 | ## Summary 6 | 7 | Replace `Vec::drain` by a method that accepts a range parameter. Add 8 | `String::drain` with similar functionality. 9 | 10 | ## Motivation 11 | 12 | Allowing a range parameter is strictly more powerful than the current version. 13 | E.g., see the following implementations of some `Vec` methods via the hypothetical 14 | `drain_range` method: 15 | 16 | ```rust 17 | fn truncate(x: &mut Vec, len: usize) { 18 | if len <= x.len() { 19 | x.drain_range(len..); 20 | } 21 | } 22 | 23 | fn remove(x: &mut Vec, index: usize) -> u8 { 24 | x.drain_range(index).next().unwrap() 25 | } 26 | 27 | fn pop(x: &mut Vec) -> Option { 28 | match x.len() { 29 | 0 => None, 30 | n => x.drain_range(n-1).next() 31 | } 32 | } 33 | 34 | fn drain(x: &mut Vec) -> DrainRange { 35 | x.drain_range(0..) 36 | } 37 | 38 | fn clear(x: &mut Vec) { 39 | x.drain_range(0..); 40 | } 41 | ``` 42 | 43 | With optimization enabled, those methods will produce code that runs as fast 44 | as the current versions. (They should not be implemented this way.) 45 | 46 | In particular, this method allows the user to remove a slice from a vector in 47 | `O(Vec::len)` instead of `O(Slice::len * Vec::len)`. 48 | 49 | ## Detailed design 50 | 51 | Remove `Vec::drain` and add the following method: 52 | 53 | ```rust 54 | /// Creates a draining iterator that clears the specified range in the Vec and 55 | /// iterates over the removed items from start to end. 56 | /// 57 | /// # Panics 58 | /// 59 | /// Panics if the range is decreasing or if the upper bound is larger than the 60 | /// length of the vector. 61 | pub fn drain(&mut self, range: T) -> /* ... */; 62 | ``` 63 | 64 | Where `Trait` is some trait that is implemented for at least `Range`, 65 | `RangeTo`, `RangeFrom`, `FullRange`, and `usize`. 66 | 67 | The precise nature of the return value is to be determined during implementation 68 | and may or may not depend on `T`. 69 | 70 | Add `String::drain`: 71 | 72 | ```rust 73 | /// Creates a draining iterator that clears the specified range in the String 74 | /// and iterates over the characters contained in the range. 75 | /// 76 | /// # Panics 77 | /// 78 | /// Panics if the range is decreasing, if the upper bound is larger than the 79 | /// length of the String, or if the start and the end of the range don't lie on 80 | /// character boundaries. 81 | pub fn drain(&mut self, range: T) -> /* ... */; 82 | ``` 83 | 84 | Where `Trait` and the return value are as above but need not be the same. 85 | 86 | ## Drawbacks 87 | 88 | - The function signature differs from other collections. 89 | - It's not clear from the signature that `..` can be used to get the old behavior. 90 | - The trait documentation will link to the `std::ops` module. It's not immediately apparent how the types in there are related to the `N..M` syntax. 91 | - Some of these problems can be mitigated by solid documentation of the function itself. 92 | -------------------------------------------------------------------------------- /text/0563-remove-ndebug.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-01-08 2 | - RFC PR: [rust-lang/rfcs#563](https://github.com/rust-lang/rfcs/pull/563) 3 | - Rust Issue: [rust-lang/rust#22492](https://github.com/rust-lang/rust/issues/22492) 4 | 5 | ## Summary 6 | 7 | Remove official support for the `ndebug` config variable, replace the current usage of it with a 8 | more appropriate `debug_assertions` compiler-provided config variable. 9 | 10 | ## Motivation 11 | 12 | The usage of 'ndebug' to indicate a release build is a strange holdover from C/C++. It is not used 13 | much and is easy to forget about. Since it used like any other value passed to the `cfg` flag, it 14 | does not interact with other flags such as `-g` or `-O`. 15 | 16 | The only current users of `ndebug` are the implementations of the `debug_assert!` macro. At the 17 | time of this writing integer overflow checking is will also be controlled by this variable. Since 18 | the optimisation setting does not influence `ndebug`, this means that code that the user expects to 19 | be optimised will still contain the overflow checking logic. Similarly, `debug_assert!` invocations 20 | are not removed, contrary to what intuition should expect. Enabling optimisations should been seen 21 | as a request to make the user's code faster, removing `debug_assert!` and other checks seems like 22 | a natural consequence. 23 | 24 | ## Detailed design 25 | 26 | The `debug_assertions` configuration variable, the replacement for the `ndebug` variable, will be 27 | compiler provided based on the value of the `opt-level` codegen flag, including the implied value 28 | from `-O`. Any value higher than 0 will disable the variable. 29 | 30 | Another codegen flag `debug-assertions` will override this, forcing it on or off based on the value 31 | passed to it. 32 | 33 | ## Drawbacks 34 | 35 | Technically backwards incompatible change. However the only usage of the `ndebug` variable in the 36 | rust tree is in the implementation of `debug_assert!`, so it's unlikely that any external code is 37 | using it. 38 | 39 | ## Alternatives 40 | 41 | No real alternatives beyond different names and defaults. 42 | 43 | ## Unresolved questions 44 | 45 | From the RFC discussion there remain some unresolved details: 46 | 47 | * brson 48 | [writes](https://github.com/rust-lang/rfcs/pull/563#issuecomment-72549694), 49 | "I have a minor concern that `-C debug-assertions` might not be the 50 | right place for this command line flag - it doesn't really affect 51 | code generation, at least in the current codebase (also `--cfg 52 | debug_assertions` has the same effect).". 53 | * huonw 54 | [writes](https://github.com/rust-lang/rfcs/pull/563#issuecomment-72550619), 55 | "It seems like the flag could be more than just a boolean, but 56 | rather take a list of what to enable to allow fine-grained control, 57 | e.g. none, overflow-checks, debug_cfg,overflow-checks, all. (Where 58 | -C debug-assertions=debug_cfg acts like --cfg debug.)". 59 | * huonw 60 | [writes](https://github.com/rust-lang/rfcs/pull/563#issuecomment-74762795), 61 | "if we want this to apply to more than just debug_assert do we want 62 | to use a name other than -C debug-assertions?". 63 | 64 | -------------------------------------------------------------------------------- /text/1640-duration-checked-sub.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `duration_checked` 2 | - Start Date: 2016-06-04 3 | - RFC PR: [rust-lang/rfcs#1640](https://github.com/rust-lang/rfcs/pull/1640) 4 | - Rust Issue: [rust-lang/rust#35774](https://github.com/rust-lang/rust/issues/35774) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | This RFC adds the `checked_*` methods already known from primitives like 10 | `usize` to `Duration`. 11 | 12 | ## Motivation 13 | [motivation]: #motivation 14 | 15 | Generally this helps when subtracting `Duration`s which can be the case quite 16 | often. 17 | 18 | One abstract example would be executing a specific piece of code repeatedly 19 | after a constant amount of time. 20 | 21 | Specific examples would be a network service or a rendering process emitting a 22 | constant amount of frames per second. 23 | 24 | Example code would be as follows: 25 | 26 | ```rust 27 | 28 | // This function is called repeatedly 29 | fn render() { 30 | // 10ms delay results in 100 frames per second 31 | let wait_time = Duration::from_millis(10); 32 | 33 | // `Instant` for elapsed time 34 | let start = Instant::now(); 35 | 36 | // execute code here 37 | render_and_output_frame(); 38 | 39 | // there are no negative `Duration`s so this does nothing if the elapsed 40 | // time is longer than the defined `wait_time` 41 | start.elapsed().checked_sub(wait_time).and_then(std::thread::sleep); 42 | } 43 | ``` 44 | 45 | Of course it is also suitable to not introduce `panic!()`s when adding 46 | `Duration`s. 47 | 48 | ## Detailed design 49 | [design]: #detailed-design 50 | 51 | The detailed design would be exactly as the current `sub()` method, just 52 | returning an `Option` and passing possible `None` values from the 53 | underlying primitive types: 54 | 55 | ```rust 56 | impl Duration { 57 | fn checked_sub(self, rhs: Duration) -> Option { 58 | if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { 59 | let nanos = if self.nanos >= rhs.nanos { 60 | self.nanos - rhs.nanos 61 | } else { 62 | if let Some(secs) = secs.checked_sub(1) { 63 | self.nanos + NANOS_PER_SEC - rhs.nanos 64 | } 65 | else { 66 | return None; 67 | } 68 | }; 69 | debug_assert!(nanos < NANOS_PER_SEC); 70 | Some(Duration { secs: secs, nanos: nanos }) 71 | } 72 | else { 73 | None 74 | } 75 | } 76 | } 77 | ``` 78 | 79 | The same accounts for all other added methods, namely: 80 | 81 | - `checked_add()` 82 | - `checked_sub()` 83 | - `checked_mul()` 84 | - `checked_div()` 85 | 86 | ## Drawbacks 87 | [drawbacks]: #drawbacks 88 | 89 | `None`. 90 | 91 | ## Alternatives 92 | [alternatives]: #alternatives 93 | 94 | The alternatives are simply not doing this and forcing the programmer to code 95 | the check on their behalf. 96 | This is not what you want. 97 | 98 | ## Unresolved questions 99 | [unresolved]: #unresolved-questions 100 | 101 | `None`. 102 | 103 | -------------------------------------------------------------------------------- /text/2832-core-net-types.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `core_net_types` 2 | - Start Date: 2019-12-06 3 | - RFC PR: [rust-lang/rfcs#2832](https://github.com/rust-lang/rfcs/pull/2832) 4 | - Rust Issue: [rust-lang/rust#108443](https://github.com/rust-lang/rust/issues/108443) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Make the `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, 10 | `SocketAddrV6`, `Ipv6MulticastScope` and `AddrParseError` types available in `no_std` 11 | contexts by moving them into a `core::net` module. 12 | 13 | ## Motivation 14 | [motivation]: #motivation 15 | 16 | The motivation here is to provide common types for both `no_std` and `std` 17 | targets which in turn will ease the creation of libraries based around IP 18 | addresses. Embedded IoT development is one area where this will be beneficial. 19 | IP addresses are portable across all platforms and have no external 20 | dependencies which is in line with the definition of the core library. 21 | 22 | ## Guide-level explanation 23 | [guide-level-explanation]: #guide-level-explanation 24 | 25 | The `core::net::IpAddr`, `core::net::Ipv4Addr`, `core::net::Ipv6Addr`, 26 | `core::net::SocketAddr`, `core::net::SocketAddrV4`, `core::net::SocketAddrV6`, 27 | `core::net::Ipv6MulticastScope` and `core::net::AddrParseError` types are 28 | available in `no_std` contexts. 29 | 30 | Library developers should use `core::net` to implement abstractions in order 31 | for them to work in `no_std` contexts as well. 32 | 33 | ## Reference-level explanation 34 | [reference-level-explanation]: #reference-level-explanation 35 | 36 | Since https://github.com/rust-lang/rust/pull/78802 has been merged, IP and 37 | socket address types are implemented in ideal Rust layout instead of wrapping 38 | their corresponding `libc` representation. 39 | 40 | Formatting for these types has also been adjusted in 41 | https://github.com/rust-lang/rust/pull/100625 and 42 | https://github.com/rust-lang/rust/pull/100640 in order to remove the dependency 43 | on `std::io::Write`. 44 | 45 | This means the types are now platform-agnostic, allowing them to be moved from 46 | `std::net` into `core::net`. 47 | 48 | ## Drawbacks 49 | [drawbacks]: #drawbacks 50 | 51 | Moving the `std::net` types to `core::net` makes the core library less *minimal*. 52 | 53 | ## Rationale and alternatives 54 | [rationale-and-alternatives]: #rationale-and-alternatives 55 | 56 | - Eliminates the need to use different abstractions for `no_std` and `std`. 57 | 58 | - Alternatively, move these types into a library other than `core`, so they 59 | can be used without `std`, and re-export them in `std`. 60 | 61 | ## Prior art 62 | [prior-art]: #prior-art 63 | 64 | There was a prior discussion at 65 | 66 | https://internals.rust-lang.org/t/std-ipv4addr-in-core/11247/15 67 | 68 | and an experimental branch from [@Nemo157](https://github.com/Nemo157) at 69 | 70 | https://github.com/Nemo157/rust/tree/core-ip 71 | 72 | ## Unresolved questions 73 | [unresolved-questions]: #unresolved-questions 74 | 75 | None. 76 | 77 | ## Future possibilities 78 | [future-possibilities]: #future-possibilities 79 | 80 | Move the `ToSocketAddrs` trait to `core::net` as well. This depends on having `core::io::Result`. 81 | -------------------------------------------------------------------------------- /text/0735-allow-inherent-impls-anywhere.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2015-02-19 2 | - RFC PR: [rust-lang/rfcs#735](https://github.com/rust-lang/rfcs/pull/735) 3 | - Rust Issue: [rust-lang/rust#22563](https://github.com/rust-lang/rust/issues/22563) 4 | 5 | ## Summary 6 | 7 | Allow inherent implementations on types outside of the module they are defined in, 8 | effectively reverting [RFC PR 155](https://github.com/rust-lang/rfcs/pull/155). 9 | 10 | ## Motivation 11 | 12 | The main motivation for disallowing such `impl` bodies was the implementation 13 | detail of fake modules being created to allow resolving `Type::method`, which 14 | only worked correctly for `impl Type {...}` if a `struct Type` or `enum Type` 15 | were defined in the same module. The old mechanism was obsoleted by UFCS, 16 | which desugars `Type::method` to `::method` and performs a type-based 17 | method lookup instead, with path resolution having no knowledge of inherent 18 | `impl`s - and all of that was implemented by [rust-lang/rust#22172](https://github.com/rust-lang/rust/pull/22172). 19 | 20 | Aside from invalidating the previous RFC's motivation, there is something to be 21 | said about dealing with restricted inherent `impl`s: it leads to non-DRY single 22 | use extension traits, the worst offender being `AstBuilder` in libsyntax, with 23 | almost 300 lines of redundant method definitions. 24 | 25 | ## Detailed design 26 | 27 | Remove the existing limitation, and only require that the `Self` type of the 28 | `impl` is defined in the same crate. This allows moving methods to other modules: 29 | ```rust 30 | struct Player; 31 | 32 | mod achievements { 33 | struct Achievement; 34 | impl Player { 35 | fn achieve(&mut self, _: Achievement) {} 36 | } 37 | } 38 | ``` 39 | 40 | ## Drawbacks 41 | 42 | Consistency and ease of finding method definitions by looking at the module the 43 | type is defined in, has been mentioned as an advantage of this limitation. 44 | However, trait `impl`s already have that problem and single use extension traits 45 | could arguably be worse. 46 | 47 | ## Alternatives 48 | 49 | - Leave it as it is. Seems unsatisfactory given that we're no longer limited 50 | by implementation details. 51 | 52 | - We could go further and allow adding inherent methods to any type that could 53 | implement a trait outside the crate: 54 | ```rust 55 | struct Point { x: T, y: T } 56 | impl (Vec>, T) { 57 | fn foo(&mut self) -> T { ... } 58 | } 59 | ``` 60 | 61 | The implementation would reuse the same coherence rules as for trait `impl`s, 62 | and, for looking up methods, the "type definition to impl" map would be replaced 63 | with a map from method name to a set of `impl`s containing that method. 64 | 65 | *Technically*, I am not aware of any formulation that limits inherent methods 66 | to user-defined types in the same crate, and this extra support could turn out 67 | to have a straight-forward implementation with no complications, but I'm trying 68 | to present the whole situation to avoid issues in the future - even though I'm 69 | not aware of backwards compatibility ones or any related to compiler internals. 70 | 71 | ## Unresolved questions 72 | 73 | None. 74 | -------------------------------------------------------------------------------- /text/0888-compiler-fence-intrinsics.md: -------------------------------------------------------------------------------- 1 | - Feature Name: compiler_fence_intrinsics 2 | - Start Date: 2015-02-19 3 | - RFC PR: [rust-lang/rfcs#888](https://github.com/rust-lang/rfcs/pull/888) 4 | - Rust Issue: [rust-lang/rust#24118](https://github.com/rust-lang/rust/issues/24118) 5 | 6 | ## Summary 7 | 8 | Add intrinsics for single-threaded memory fences. 9 | 10 | ## Motivation 11 | 12 | Rust currently supports memory barriers through a set of intrinsics, 13 | `atomic_fence` and its variants, which generate machine instructions and are 14 | suitable as cross-processor fences. However, there is currently no compiler 15 | support for single-threaded fences which do not emit machine instructions. 16 | 17 | Certain use cases require that the compiler not reorder loads or stores across a 18 | given barrier but do not require a corresponding hardware guarantee, such as 19 | when a thread interacts with a signal handler which will run on the same thread. 20 | By omitting a fence instruction, relatively costly machine operations can be 21 | avoided. 22 | 23 | The C++ equivalent of this feature is `std::atomic_signal_fence`. 24 | 25 | ## Detailed design 26 | 27 | Add four language intrinsics for single-threaded fences: 28 | 29 | * `atomic_compilerfence` 30 | * `atomic_compilerfence_acq` 31 | * `atomic_compilerfence_rel` 32 | * `atomic_compilerfence_acqrel` 33 | 34 | These have the same semantics as the existing `atomic_fence` intrinsics but only 35 | constrain memory reordering by the compiler, not by hardware. 36 | 37 | The existing fence intrinsics are exported in libstd with safe wrappers, but 38 | this design does not export safe wrappers for the new intrinsics. The existing 39 | fence functions will still perform correctly if used where a single-threaded 40 | fence is called for, but with a slight reduction in efficiency. Not exposing 41 | these new intrinsics through a safe wrapper reduces the possibility for 42 | confusion on which fences are appropriate in a given situation, while still 43 | providing the capability for users to opt in to a single-threaded fence when 44 | appropriate. 45 | 46 | ## Alternatives 47 | 48 | * Do nothing. The existing fence intrinsics support all use cases, but with a 49 | negative impact on performance in some situations where a compiler-only fence 50 | is appropriate. 51 | 52 | * Recommend inline assembly to get a similar effect, such as `asm!("" ::: 53 | "memory" : "volatile")`. LLVM provides an IR item specifically for this case 54 | (`fence singlethread`), so I believe taking advantage of that feature in LLVM is 55 | most appropriate, since its semantics are more rigorously defined and less 56 | likely to yield unexpected (but not necessarily wrong) behavior. 57 | 58 | ## Unresolved questions 59 | 60 | These intrinsics may be better represented with a different name, such as 61 | `atomic_signal_fence` or `atomic_singlethread_fence`. The existing 62 | implementation of atomic intrinsics in the compiler precludes the use of 63 | underscores in their names and I believe it is clearer to refer to this 64 | construct as a "compiler fence" rather than a "signal fence" because not all use 65 | cases necessarily involve signal handlers, hence the current choice of name. 66 | -------------------------------------------------------------------------------- /text/0438-precedence-of-plus.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-11-18 2 | - RFC PR: [rust-lang/rfcs#438](https://github.com/rust-lang/rfcs/pull/438) 3 | - Rust Issue: [rust-lang/rust#19092](https://github.com/rust-lang/rust/issues/19092) 4 | 5 | ## Summary 6 | 7 | Change the precedence of `+` (object bounds) in type grammar so that 8 | it is similar to the precedence in the expression grammars. 9 | 10 | ## Motivation 11 | 12 | Currently `+` in types has a much higher precedence than it does in expressions. 13 | This means that for example one can write a type like the following: 14 | 15 | ``` 16 | &Object+Send 17 | ``` 18 | 19 | Whereas if that were an expression, parentheses would be required: 20 | 21 | ```rust 22 | &(Object+Send) 23 | ```` 24 | 25 | Besides being confusing in its own right, this loose approach with 26 | regard to precedence yields ambiguities with unboxed closure bounds: 27 | 28 | ```rust 29 | fn foo(f: F) 30 | where F: FnOnce(&int) -> &Object + Send 31 | { } 32 | ``` 33 | 34 | In this example, it is unclear whether `F` returns an object which is 35 | `Send`, or whether `F` itself is `Send`. 36 | 37 | ## Detailed design 38 | 39 | This RFC proposes that the precedence of `+` be made lower than unary 40 | type operators. In addition, the grammar is segregated such that in 41 | "open-ended" contexts (e.g., after `->`), parentheses are required to 42 | use a `+`, whereas in others (e.g., inside `<>`), parentheses are not. 43 | Here are some examples: 44 | 45 | ```rust 46 | // Before After Note 47 | // ~~~~~~ ~~~~~ ~~~~ 48 | &Object+Send &(Object+Send) 49 | &'a Object+'a &'a (Object+'a) 50 | Box Box 51 | foo::(...) foo::(...) 52 | Fn() -> Object+Send Fn() -> (Object+Send) // (*) 53 | Fn() -> &Object+Send Fn() -> &(Object+Send) 54 | 55 | // (*) Must yield a type error, as return type must be `Sized`. 56 | ``` 57 | 58 | More fully, the type grammar is as follows (EBNF notation): 59 | 60 | TYPE = PATH 61 | | '&' [LIFETIME] TYPE 62 | | '&' [LIFETIME] 'mut' TYPE 63 | | '*' 'const' TYPE 64 | | '*' 'mut' TYPE 65 | | ... 66 | | '(' SUM ')' 67 | SUM = TYPE { '+' TYPE } 68 | PATH = IDS '<' SUM { ',' SUM } '>' 69 | | IDS '(' SUM { ',' SUM } ')' '->' TYPE 70 | IDS = ['::'] ID { '::' ID } 71 | 72 | Where clauses would use the following grammar: 73 | 74 | WHERE_CLAUSE = PATH { '+' PATH } 75 | 76 | One property of this grammar is that the `TYPE` nonterminal does not 77 | require a terminator as it has no "open-ended" expansions. `SUM`, in 78 | contrast, can be extended any number of times via the `+` token. Hence 79 | is why `SUM` must be enclosed in parens to make it into a `TYPE`. 80 | 81 | ## Drawbacks 82 | 83 | Common types like `&'a Foo+'a` become slightly longer (`&'a (Foo+'a)`). 84 | 85 | ## Alternatives 86 | 87 | We could live with the inconsistency between the type/expression 88 | grammars and disambiguate where clauses in an ad-hoc way. 89 | 90 | ## Unresolved questions 91 | 92 | None. 93 | -------------------------------------------------------------------------------- /text/0214-while-let.md: -------------------------------------------------------------------------------- 1 | - Start Date: 2014-08-27 2 | - RFC PR: [rust-lang/rfcs#214](https://github.com/rust-lang/rfcs/pull/214) 3 | - Rust Issue: [rust-lang/rust#17687](https://github.com/rust-lang/rust/issues/17687) 4 | 5 | ## Summary 6 | 7 | Introduce a new `while let PAT = EXPR { BODY }` construct. This allows for using a refutable pattern 8 | match (with optional variable binding) as the condition of a loop. 9 | 10 | ## Motivation 11 | 12 | Just as `if let` was inspired by Swift, it turns out Swift supports `while let` as well. This was 13 | not discovered until much too late to include it in the `if let` RFC. It turns out that this sort of 14 | looping is actually useful on occasion. For example, the desugaring `for` loop is actually a variant 15 | on this; if `while let` existed it could have been implemented to map `for PAT in EXPR { BODY }` to 16 | 17 | ```rust 18 | // the match here is so `for` can accept an rvalue for the iterator, 19 | // and was used in the "real" desugaring version. 20 | match &mut EXPR { 21 | i => { 22 | while let Some(PAT) = i.next() { 23 | BODY 24 | } 25 | } 26 | } 27 | ``` 28 | 29 | (note that the non-desugared form of `for` is no longer equivalent). 30 | 31 | More generally, this construct can be used any time looping + pattern-matching is desired. 32 | 33 | This also makes the language a bit more consistent; right now, any condition that can be used with 34 | `if` can be used with `while`. The new `if let` adds a form of `if` that doesn't map to `while`. 35 | Supporting `while let` restores the equivalence of these two control-flow constructs. 36 | 37 | ## Detailed design 38 | 39 | `while let` operates similarly to `if let`, in that it desugars to existing syntax. Specifically, 40 | the syntax 41 | 42 | ```rust 43 | ['ident:] while let PAT = EXPR { 44 | BODY 45 | } 46 | ``` 47 | 48 | desugars to 49 | 50 | ```rust 51 | ['ident:] loop { 52 | match EXPR { 53 | PAT => BODY, 54 | _ => break 55 | } 56 | } 57 | ``` 58 | 59 | Just as with `if let`, an irrefutable pattern given to `while let` is considered an error. This is 60 | largely an artifact of the fact that the desugared `match` ends up with an unreachable pattern, 61 | and is not actually a goal of this syntax. The error may be suppressed in the future, which would be 62 | a backwards-compatible change. 63 | 64 | Just as with `if let`, `while let` will be introduced under a feature gate (named `while_let`). 65 | 66 | ## Drawbacks 67 | 68 | Yet another addition to the grammar. Unlike `if let`, it's not obvious how useful this syntax will 69 | be. 70 | 71 | ## Alternatives 72 | 73 | As with `if let`, this could plausibly be done with a macro, but it would be ugly and produce bad 74 | error messages. 75 | 76 | `while let` could be extended to support alternative patterns, just as match arms do. This is not 77 | part of the main proposal for the same reason it was left out of `if let`, which is that a) it looks 78 | weird, and b) it's a bit of an odd coupling with the `let` keyword as alternatives like this aren't 79 | going to be introducing variable bindings. However, it would make `while let` more general and able 80 | to replace more instances of `loop { match { ... } }` than is possible with the main design. 81 | 82 | ## Unresolved questions 83 | 84 | None. 85 | -------------------------------------------------------------------------------- /text/1552-contains-method-for-various-collections.md: -------------------------------------------------------------------------------- 1 | - Feature Name: `contains_method_for_various_collections` 2 | - Start Date: 2016-03-16 3 | - RFC PR: [rust-lang/rfcs#1552](https://github.com/rust-lang/rfcs/pull/1552) 4 | - Rust Issue: [rust-lang/rust#32630](https://github.com/rust-lang/rust/issues/32630) 5 | 6 | ## Summary 7 | [summary]: #summary 8 | 9 | Add a `contains` method to `VecDeque` and `LinkedList` that checks if the 10 | collection contains a given item. 11 | 12 | ## Motivation 13 | [motivation]: #motivation 14 | 15 | A `contains` method exists for the slice type `[T]` and for `Vec` through 16 | `Deref`, but there is no easy way to check if a `VecDeque` or `LinkedList` 17 | contains a specific item. Currently, the shortest way to do it is something 18 | like: 19 | 20 | ```rust 21 | vec_deque.iter().any(|e| e == item) 22 | ``` 23 | 24 | While this is not insanely verbose, a `contains` method has the following 25 | advantages: 26 | 27 | - the name `contains` expresses the programmer's intent... 28 | - ... and thus is more idiomatic 29 | - it's as short as it can get 30 | - programmers that are used to call `contains` on a `Vec` are confused by the 31 | non-existence of the method for `VecDeque` or `LinkedList` 32 | 33 | ## Detailed design 34 | [design]: #detailed-design 35 | 36 | Add the following method to `std::collections::VecDeque`: 37 | 38 | ```rust 39 | impl VecDeque { 40 | /// Returns `true` if the `VecDeque` contains an element equal to the 41 | /// given value. 42 | pub fn contains(&self, x: &T) -> bool 43 | where T: PartialEq 44 | { 45 | // implementation with a result equivalent to the result 46 | // of `self.iter().any(|e| e == x)` 47 | } 48 | } 49 | ``` 50 | 51 | Add the following method to `std::collections::LinkedList`: 52 | 53 | ```rust 54 | impl LinkedList { 55 | /// Returns `true` if the `LinkedList` contains an element equal to the 56 | /// given value. 57 | pub fn contains(&self, x: &T) -> bool 58 | where T: PartialEq 59 | { 60 | // implementation with a result equivalent to the result 61 | // of `self.iter().any(|e| e == x)` 62 | } 63 | } 64 | ``` 65 | 66 | The new methods should probably be marked as unstable initially and be 67 | stabilized later. 68 | 69 | ## Drawbacks 70 | [drawbacks]: #drawbacks 71 | 72 | Obviously more methods increase the complexity of the standard library, but in 73 | case of this RFC the increase is rather tiny. 74 | 75 | While `VecDeque::contains` should be (nearly) as fast as `[T]::contains`, 76 | `LinkedList::contains` will probably be much slower due to the cache 77 | inefficient nature of a linked list. Offering a method that is short to 78 | write and convenient to use could lead to excessive use of said method 79 | without knowing about the problems mentioned above. 80 | 81 | ## Alternatives 82 | [alternatives]: #alternatives 83 | 84 | There are a few alternatives: 85 | 86 | - add `VecDeque::contains` only and do not add `LinkedList::contains` 87 | - do nothing, because -- technically -- the same functionality is offered 88 | through iterators 89 | - also add `BinaryHeap::contains`, since it could be convenient for some use 90 | cases, too 91 | 92 | ## Unresolved questions 93 | [unresolved]: #unresolved-questions 94 | 95 | None so far. 96 | --------------------------------------------------------------------------------