From ef4e911fb39740192c7aff162e2e337068f85651 Mon Sep 17 00:00:00 2001 From: Havvy Date: Tue, 18 Apr 2017 00:14:02 -0700 Subject: [PATCH 1/4] Use Declarations in Implementations and Match Exprs --- text/0000-use-in-impl-and-match.md | 111 +++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 text/0000-use-in-impl-and-match.md diff --git a/text/0000-use-in-impl-and-match.md b/text/0000-use-in-impl-and-match.md new file mode 100644 index 00000000000..06f93a82082 --- /dev/null +++ b/text/0000-use-in-impl-and-match.md @@ -0,0 +1,111 @@ +- Feature Name: use-in-impl-and-match +- Start Date: 2017-04-17 +- RFC PR: +- Rust Issue: + +# Summary +[summary]: #summary + +Allow the usage of `use` inside `impl` blocks and `match` blocks. + +# Motivation +[motivation]: #motivation + +Some of us want to scope `use declaration` aliases as close to the code that +uses them. + +This also increases ergonomics and readability ever so slightly because there +would be less scrolling since the declaration would be closer to the use site. + +# Detailed design +[design]: #detailed-design + +Allow `use declarations` to be inside of `implementations`. The bindings that +the `use declaration` creates would be scoped to the implementation. + +Also `use declarations` to be inside of `match expressions` where `match arms` +are allowed. The bindings that the `use declaration` creates would be +scoped to all `match arms` and other `use declarations` + +These `use declarations` would allow the `pub` modifier. It would do nothing, +just like it currently does in block expressions. + +## Example + +This example uses `use` in both the `impl` and the `match`. + +Note that this `impl` could be written without the full match, but it's close +enough to actual examples. + +```rust +struct ReverseCompare(i32); + +impl std::cmp::PartialOrd for ReverseCompare { + use std::cmp::Ordering + + fn partial_cmp(&self, other: &ReverseCompare) -> Ordering { + match (self.0).partial_cmp(other.0) { + use Ordering::*; + + None => unreachable!(), + Some(Greater) => Some(Lesser), + Some(Less) => Some(Greater), + Some(Eq) => Some(Eq) + } + } +} +``` + +# How We Teach This +[how-we-teach-this]: #how-we-teach-this + +This is a continuation of current Rust concepts. No new termionlogy needs to +be taught. That said, if the "use in match" part is accepted, it would be +useful to coin a new term for the two things that can show up where `match +arms` currently are in `match expressions`. + +_The Rust Reference_ would need to be updated. Specifically the +`Use Declarations` section would need to be say that it can also be used in +the new locations. Relatedly, the `Use Delcarations` section should also be +updated to say the scope of the bindings it creates. Right now only the +`Block Expression` section discusses the scope of `use declarations` which +feels like the wrong place. + +_The Rust Grammar Reference_ would need to be updated in the `Implementations` +and `Match Expressions` sections. Although there's currently no +`Implementations` section at all right now. + +Looking at the new _The Rust Programming Language_, there's no discussion on +where `use declarations` are valid currently, so unless that gets added, +there's no reason to mention the changes in here explicitly. Except perhaps +that the allowance where `match arms` could be mentioned in the place where +`match expressions` are discussed. + +_Rust by Example_'s "The use declaration" section could have examples added +for `use declarations` in `implementations` and `match expressions`. + +# Drawbacks +[drawbacks]: #drawbacks + +For `use in match`, this means that we can allow things other than +pattern => expr that are separated by semicolons and not commas. + +# Alternatives +[alternatives]: #alternatives + +Only allow `use` in one of `impl` or `match`. Or do nothing. This is +purely an ergonomics improvement and doesn't make anything impossible +possible. + +The idea of using `_::Greater` to elide the enum name in match arms would +reduce the added ergonomics of `use declarations` in `match expressions`. + +Make `pub use` a hard error in `implementations` and `match expressions`. The +allowance already exists for block expressions where the `pub` is ignored. +Macro authors have suggested that allowing it there like that makes it +easier to write macros with use declarations. + +# Unresolved questions +[unresolved]: #unresolved-questions + +None From 338b9c0b40652d8aa215c9e2d5f28af6e6e184ff Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 1 May 2017 22:48:25 -0700 Subject: [PATCH 2/4] Remove `use in match`, add `use in trait`; Add grammar Remove `use` in `match`. Should be as own RFC, and not willing to defend it personally. Likewise, removed parts in the how we teach and drawbacks, making those sections less "if"fy. Added `trait`, as that's analogous to `impl` and I feel stupid for not doing that initially. Added grammar changes. Not sure if they're the right changes, but at least they exist. --- ...match.md => 0000-use-in-trait-and-impl.md} | 77 +++++++++++-------- 1 file changed, 47 insertions(+), 30 deletions(-) rename text/{0000-use-in-impl-and-match.md => 0000-use-in-trait-and-impl.md} (57%) diff --git a/text/0000-use-in-impl-and-match.md b/text/0000-use-in-trait-and-impl.md similarity index 57% rename from text/0000-use-in-impl-and-match.md rename to text/0000-use-in-trait-and-impl.md index 06f93a82082..9fab3ae9f4f 100644 --- a/text/0000-use-in-impl-and-match.md +++ b/text/0000-use-in-trait-and-impl.md @@ -1,4 +1,4 @@ -- Feature Name: use-in-impl-and-match +- Feature Name: use-in-trait-and-impl - Start Date: 2017-04-17 - RFC PR: - Rust Issue: @@ -6,7 +6,7 @@ # Summary [summary]: #summary -Allow the usage of `use` inside `impl` blocks and `match` blocks. +Allow the usage of `use` inside `trait` and `impl` blocks. # Motivation [motivation]: #motivation @@ -20,32 +20,32 @@ would be less scrolling since the declaration would be closer to the use site. # Detailed design [design]: #detailed-design +Allow `use declarations` to be inside of `traits`. The bindings that +the `use declaration` creates would be scoped to the trait block. + Allow `use declarations` to be inside of `implementations`. The bindings that the `use declaration` creates would be scoped to the implementation. -Also `use declarations` to be inside of `match expressions` where `match arms` -are allowed. The bindings that the `use declaration` creates would be -scoped to all `match arms` and other `use declarations` - These `use declarations` would allow the `pub` modifier. It would do nothing, just like it currently does in block expressions. -## Example +## Example - use in impl -This example uses `use` in both the `impl` and the `match`. +This example uses `use` in the implementation block to put Ordering and its +enum variant constructors into scope. -Note that this `impl` could be written without the full match, but it's close -enough to actual examples. +Note that this `impl` could be written without the full match, using only the +not operator, but it's representativge of real usage. ```rust struct ReverseCompare(i32); impl std::cmp::PartialOrd for ReverseCompare { use std::cmp::Ordering + use std::cmp::Ordering::*; fn partial_cmp(&self, other: &ReverseCompare) -> Ordering { match (self.0).partial_cmp(other.0) { - use Ordering::*; None => unreachable!(), Some(Greater) => Some(Lesser), @@ -54,15 +54,36 @@ impl std::cmp::PartialOrd for ReverseCompare { } } } + +``` + +## Grammar Changes + +In `trait_item`, add a variant `trait_use`. + +Define `trait_use` as + +``` +trait_use +: visibility use_item +; +``` + +In `impl_item`, add a variant `impl_use`. + +Define `impl_use` as + +``` +impl_use +: visibility use_item +; ``` # How We Teach This [how-we-teach-this]: #how-we-teach-this This is a continuation of current Rust concepts. No new termionlogy needs to -be taught. That said, if the "use in match" part is accepted, it would be -useful to coin a new term for the two things that can show up where `match -arms` currently are in `match expressions`. +be taught. _The Rust Reference_ would need to be updated. Specifically the `Use Declarations` section would need to be say that it can also be used in @@ -71,40 +92,36 @@ updated to say the scope of the bindings it creates. Right now only the `Block Expression` section discusses the scope of `use declarations` which feels like the wrong place. -_The Rust Grammar Reference_ would need to be updated in the `Implementations` -and `Match Expressions` sections. Although there's currently no -`Implementations` section at all right now. +_The Rust Grammar Reference_ would need to be updated in the `Traits` and +`Implementations` sections. Although, currently, both of those sections +are completely empty and would have to be written. Looking at the new _The Rust Programming Language_, there's no discussion on where `use declarations` are valid currently, so unless that gets added, -there's no reason to mention the changes in here explicitly. Except perhaps -that the allowance where `match arms` could be mentioned in the place where -`match expressions` are discussed. +there's no reason to mention the changes in here explicitly. _Rust by Example_'s "The use declaration" section could have examples added -for `use declarations` in `implementations` and `match expressions`. +for `use declarations` in `implementations`. Probably also true for `traits`. # Drawbacks [drawbacks]: #drawbacks -For `use in match`, this means that we can allow things other than -pattern => expr that are separated by semicolons and not commas. +None. # Alternatives [alternatives]: #alternatives -Only allow `use` in one of `impl` or `match`. Or do nothing. This is -purely an ergonomics improvement and doesn't make anything impossible -possible. +Do nothing. This is purely an ergonomics improvement and doesn't make anything +currently impossible actually possible. -The idea of using `_::Greater` to elide the enum name in match arms would -reduce the added ergonomics of `use declarations` in `match expressions`. - -Make `pub use` a hard error in `implementations` and `match expressions`. The +Make `pub use` a hard error in `implementations`. The allowance already exists for block expressions where the `pub` is ignored. Macro authors have suggested that allowing it there like that makes it easier to write macros with use declarations. +Add a `use Path in Item/Expr` construct. This could also be done, but there's +no reason not to allow `use` as is in more places. + # Unresolved questions [unresolved]: #unresolved-questions From 32d0c3f9564d8dd300e6c90d60dc049bcf3cf0ff Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 15 May 2017 21:41:34 -0700 Subject: [PATCH 3/4] Disallow `pub use` in these new areas. There's RFCs for having `pub use` in traits work as aliases, and allowing `pub use` would be a back-compat hazard for these RFCs. Sorry trait authors. --- text/0000-use-in-trait-and-impl.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/text/0000-use-in-trait-and-impl.md b/text/0000-use-in-trait-and-impl.md index 9fab3ae9f4f..804a32aaabb 100644 --- a/text/0000-use-in-trait-and-impl.md +++ b/text/0000-use-in-trait-and-impl.md @@ -26,8 +26,7 @@ the `use declaration` creates would be scoped to the trait block. Allow `use declarations` to be inside of `implementations`. The bindings that the `use declaration` creates would be scoped to the implementation. -These `use declarations` would allow the `pub` modifier. It would do nothing, -just like it currently does in block expressions. +These `use declarations` would not allow the `pub` visibility modifier. ## Example - use in impl @@ -65,7 +64,7 @@ Define `trait_use` as ``` trait_use -: visibility use_item +: use_item ; ``` @@ -75,7 +74,7 @@ Define `impl_use` as ``` impl_use -: visibility use_item +: use_item ; ``` @@ -114,10 +113,10 @@ None. Do nothing. This is purely an ergonomics improvement and doesn't make anything currently impossible actually possible. -Make `pub use` a hard error in `implementations`. The -allowance already exists for block expressions where the `pub` is ignored. -Macro authors have suggested that allowing it there like that makes it -easier to write macros with use declarations. +Allow `pub` in use declarations, just like in blocks. A previous version of +this RFC allowed that, but there have been RFCs for attributing meaning to +`pub use` in traits and having it do nothing for now would be a back-compat +hazard. Add a `use Path in Item/Expr` construct. This could also be done, but there's no reason not to allow `use` as is in more places. From eecab3d0b7f58cbe653e90c3b682b39ab3e4cb20 Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 15 May 2017 21:50:42 -0700 Subject: [PATCH 4/4] Add non-public item in trait drawback --- text/0000-use-in-trait-and-impl.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/0000-use-in-trait-and-impl.md b/text/0000-use-in-trait-and-impl.md index 804a32aaabb..de0713c4b3a 100644 --- a/text/0000-use-in-trait-and-impl.md +++ b/text/0000-use-in-trait-and-impl.md @@ -105,7 +105,9 @@ for `use declarations` in `implementations`. Probably also true for `traits`. # Drawbacks [drawbacks]: #drawbacks -None. +All other items in a trait or implementation are public by default and don't +even allow a visiblity modifier. This would be the first item that would not +be public. # Alternatives [alternatives]: #alternatives