From b02107a3ad2c9d7e9bd3da164f51530e133ecdd4 Mon Sep 17 00:00:00 2001 From: tommit Date: Thu, 24 Apr 2014 13:18:00 +0300 Subject: [PATCH 1/3] Create 0000-private-trait-items.md --- active/0000-private-trait-items.md | 68 ++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 active/0000-private-trait-items.md diff --git a/active/0000-private-trait-items.md b/active/0000-private-trait-items.md new file mode 100644 index 00000000000..09eed295be0 --- /dev/null +++ b/active/0000-private-trait-items.md @@ -0,0 +1,68 @@ +- Start Date: 2014-04-18 +- RFC PR #: +- Rust Issue #: + +# Summary + +I propose the ability to set trait items (i.e. just methods currently) private as well as public in order to expand the scope of possible use cases of provided methods (i.e. default trait method implementations). I also propose that trait items should be private by default. + +# Motivation + +Sometimes a trait may be able to provide a default implementation for a method iff it can use a certain method which only the type that implements the trait is in a position to provide a definition for. Often times such a feedback method is supposed to be only a tool for the trait to be able to define provided methods with, and as such, not supposed to become a part of the public interface of the trait or any type which implements the trait. Therefore such a feedback method should be made private. Trait items should be private by default so that we don't have the need to reintroduce the 'priv' keyword. If in future we get the ability to specify that a certain provided method in a trait is 'final' (i.e. not overridable by the type which implements the trait), then, together with private trait methods, we can use the Non-Virtual Interface (NVI) idiom coined and described here by Herb Sutter: http://www.gotw.ca/publications/mill18.htm + +# Detailed design + +One way of looking at private trait methods (or any private trait items) is to see them as private dialog between a trait and a type which implements the trait. This view could lead to a design where no-one else except the trait and the type which implements it is allowed access to such private feedback item. But given how Rust privacy rules work at module boundaries (and also extend access to submodules), it would make sense that access to a private trait item extended from just the trait or the type which implements it to the enclosing module and its submodules. By this logic I suggest the following privacy rules for private trait items: + +Given that: +1) A trait ```Tr``` specifies a private item ```priv_item``` and is defined in module ```mod_tr``` +3) A type ```Foo``` implements ```Tr``` and is defined in module ```mod_foo``` +3) A type ```Bar``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` +4) A type ```Baz``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` + +It follows that: +1) ```priv_item``` is accessible from ```mod_tr``` and all its submodules. +2) ```priv_item``` is accessible from ```mod_foo``` and all its submodules iff it is certain at compile-time that it refers to the ```Foo```'s implementation ```priv_item``` +3) ```priv_item``` is accessible from ```mod_bar_and_baz``` and all its submodules iff it is certain at compile-time that it refers to either the ```Bar```'s or ```Baz```'s implementation of ```priv_item``` + +And ```priv_item``` is not accessible from anywhere else. + +Example: +``` +// in mod_tr.rs +pub trait Tr { + priv fn priv_item(&self); + + pub fn do_stuff(&self) { + self.priv_item(); // OK + } +} + +pub fn do_other_stuff(a: &A) { + a.priv_item(); // OK +} + +// in mod_foo.rs +use mod_tr::Tr; + +pub struct Foo; + +impl Tr for Foo { + priv fn priv_item(&self) {} +} + +pub fn do_foo_stuff(foo: &Foo) { + foo.priv_item(); // OK +} + +pub fn do_incorrect_stuff(a: &A) { + a.priv_item(); // ERROR: "A private trait item Tr::priv_item not accessible from mod_foo" +} +``` + +# Alternatives + + + +# Unresolved questions + From 92277797ce3935d18658463ba569fce2bd2ce894 Mon Sep 17 00:00:00 2001 From: tommit Date: Wed, 21 May 2014 15:25:17 +0300 Subject: [PATCH 2/3] Space-optimize `Option` for integral enum `T` --- ...integral-enum-option-space-optimization.md | 27 ++++++++ active/0000-private-trait-items.md | 68 ------------------- 2 files changed, 27 insertions(+), 68 deletions(-) create mode 100644 active/0000-integral-enum-option-space-optimization.md delete mode 100644 active/0000-private-trait-items.md diff --git a/active/0000-integral-enum-option-space-optimization.md b/active/0000-integral-enum-option-space-optimization.md new file mode 100644 index 00000000000..4955e65b0cb --- /dev/null +++ b/active/0000-integral-enum-option-space-optimization.md @@ -0,0 +1,27 @@ +- Start Date: 2014-05-21 +- RFC PR #: +- Rust Issue #: + +# Summary + +Space optimization for variables of type ```Option``` when ```E``` is an integral enum type. + +# Motivation + +There's no need to waste memory for storing a separate tag in variables of type ```Option``` if ```E``` is an integral enum type and the set of valid values of ```E``` does not cover all possible bit patterns. Any ```E``` size bit pattern that doesn't represent a valid value of type ```E``` could be used by the compiler to represent a ```None``` value of type ```Option```. + +# Detailed design + +Given an integral enum type ```E```, the compiler should check if some bit pattern exists which does not represent a valid value of ```E``` as determined by the enumerators of type ```E```. If such a bit pattern is found, the compiler should use it to represent a ```None``` value of type ```Option``` and omit storing the tag in variables of type ```Option```. If more than one such "invalid" bit pattern exists, the compiler should be free to choose any one of those. + +# Drawbacks + +Any serialization format that wants to stay backward compatible should take into consideration that if an enumerator is added after some ```Option``` values have been serialized to disk, the new enumerator might have the same bit pattern as what was earlier used for a ```None``` value. + +# Alternatives + +- + +# Unresolved questions + +There are a lot of types ```T``` for which ```Option``` could be space-optimized. But this proposal does not attempt to cover any of those other cases. diff --git a/active/0000-private-trait-items.md b/active/0000-private-trait-items.md deleted file mode 100644 index 09eed295be0..00000000000 --- a/active/0000-private-trait-items.md +++ /dev/null @@ -1,68 +0,0 @@ -- Start Date: 2014-04-18 -- RFC PR #: -- Rust Issue #: - -# Summary - -I propose the ability to set trait items (i.e. just methods currently) private as well as public in order to expand the scope of possible use cases of provided methods (i.e. default trait method implementations). I also propose that trait items should be private by default. - -# Motivation - -Sometimes a trait may be able to provide a default implementation for a method iff it can use a certain method which only the type that implements the trait is in a position to provide a definition for. Often times such a feedback method is supposed to be only a tool for the trait to be able to define provided methods with, and as such, not supposed to become a part of the public interface of the trait or any type which implements the trait. Therefore such a feedback method should be made private. Trait items should be private by default so that we don't have the need to reintroduce the 'priv' keyword. If in future we get the ability to specify that a certain provided method in a trait is 'final' (i.e. not overridable by the type which implements the trait), then, together with private trait methods, we can use the Non-Virtual Interface (NVI) idiom coined and described here by Herb Sutter: http://www.gotw.ca/publications/mill18.htm - -# Detailed design - -One way of looking at private trait methods (or any private trait items) is to see them as private dialog between a trait and a type which implements the trait. This view could lead to a design where no-one else except the trait and the type which implements it is allowed access to such private feedback item. But given how Rust privacy rules work at module boundaries (and also extend access to submodules), it would make sense that access to a private trait item extended from just the trait or the type which implements it to the enclosing module and its submodules. By this logic I suggest the following privacy rules for private trait items: - -Given that: -1) A trait ```Tr``` specifies a private item ```priv_item``` and is defined in module ```mod_tr``` -3) A type ```Foo``` implements ```Tr``` and is defined in module ```mod_foo``` -3) A type ```Bar``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` -4) A type ```Baz``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` - -It follows that: -1) ```priv_item``` is accessible from ```mod_tr``` and all its submodules. -2) ```priv_item``` is accessible from ```mod_foo``` and all its submodules iff it is certain at compile-time that it refers to the ```Foo```'s implementation ```priv_item``` -3) ```priv_item``` is accessible from ```mod_bar_and_baz``` and all its submodules iff it is certain at compile-time that it refers to either the ```Bar```'s or ```Baz```'s implementation of ```priv_item``` - -And ```priv_item``` is not accessible from anywhere else. - -Example: -``` -// in mod_tr.rs -pub trait Tr { - priv fn priv_item(&self); - - pub fn do_stuff(&self) { - self.priv_item(); // OK - } -} - -pub fn do_other_stuff(a: &A) { - a.priv_item(); // OK -} - -// in mod_foo.rs -use mod_tr::Tr; - -pub struct Foo; - -impl Tr for Foo { - priv fn priv_item(&self) {} -} - -pub fn do_foo_stuff(foo: &Foo) { - foo.priv_item(); // OK -} - -pub fn do_incorrect_stuff(a: &A) { - a.priv_item(); // ERROR: "A private trait item Tr::priv_item not accessible from mod_foo" -} -``` - -# Alternatives - - - -# Unresolved questions - From 40d4f7d13a5fe7995630c23f8087631725ef9a79 Mon Sep 17 00:00:00 2001 From: tommit Date: Wed, 21 May 2014 16:21:58 +0300 Subject: [PATCH 3/3] Update 0000-integral-enum-option-space-optimization.md Changed the invalid bit pattern from being implementation defined to being defined by the language. --- active/0000-integral-enum-option-space-optimization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/active/0000-integral-enum-option-space-optimization.md b/active/0000-integral-enum-option-space-optimization.md index 4955e65b0cb..95d81bc166a 100644 --- a/active/0000-integral-enum-option-space-optimization.md +++ b/active/0000-integral-enum-option-space-optimization.md @@ -12,7 +12,7 @@ There's no need to waste memory for storing a separate tag in variables of type # Detailed design -Given an integral enum type ```E```, the compiler should check if some bit pattern exists which does not represent a valid value of ```E``` as determined by the enumerators of type ```E```. If such a bit pattern is found, the compiler should use it to represent a ```None``` value of type ```Option``` and omit storing the tag in variables of type ```Option```. If more than one such "invalid" bit pattern exists, the compiler should be free to choose any one of those. +Given an integral enum type ```E```, the compiler should check if some bit pattern exists which does not represent a valid value of ```E``` as determined by the enumerators of type ```E```. If such a bit pattern is found, the compiler should use it to represent a ```None``` value of type ```Option``` and omit storing the tag in variables of type ```Option```. If more than one such "invalid" bit pattern exists, the compiler should choose the one with the largest binary value. # Drawbacks