# Design of `Neglect` parameter How do we represent combinations of transmutation options? ## Const Parameter Make `Neglect` a const parameter: ```rust unsafe trait AlwaysTransmuteFrom<Src, const NEGLECT: ???> { ... } unsafe trait UnstableTransmuteFrom<Src, Scope, const NEGLECT: ???> { ... } ``` *What do we replace "`???`" with?* ### `const NEGLECT: Neglect` Surface syntax: ```rust fn example<Src, Dst>() where /* not neglecting any static checks */ Dst: AlwaysTransmuteFrom<Src, {Neglect::NOTHING}>, /* neglecting just validity */ Dst: AlwaysTransmuteFrom<Src, {Neglect {validity: true, ..Neglect::NOTHING}}>, /* neglecting validity and alignment */ Dst: AlwaysTransmuteFrom<Src, {Neglect {alignment: true, validity: true, ..Neglect::NOTHING}}>, {} ``` [Behind the scenes.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=3033bac864e22c2fe1c6a4acb84ca559) Pros: - ordering and multiplicity of options doesn't matter! Cons: - `NEGLECT` cannot be defaulted; common case of *neglect nothing* thus isn't syntactically free - depends on const_generics ### `const NEGLECT: &'static [Neglect]` Surface syntax: ```rust fn example<Src, Dst>() where /* not neglecting any static checks */ Dst: AlwaysTransmuteFrom<Src, {&[]}>, /* neglecting just validity */ Dst: AlwaysTransmuteFrom<Src, {&[Neglect::Validity]}>, /* neglecting validity and alignment */ Dst: AlwaysTransmuteFrom<Src, {&[Neglect::Validity, Neglect::Alignment]}>, /* or, equivalently: */ Dst: AlwaysTransmuteFrom<Src, {&[Neglect::Alignment, Neglect::Validity]}>, {} ``` [Behind the scenes.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=bf7a2165f2219e552c4e4755b8797dcf) Pros: - array syntax is familiar Cons: - `NEGLECT` cannot be defaulted; common case of *neglect nothing* thus isn't syntactically free - ordering and multiplicity of options *shouldn't* matter, but it does; `[Neglect::Validity, Neglect::Alignment]` and `[Neglect::Alignment, Neglect::Validity]` are distinct types. - depends on const_generics ## Type Parameter ```rust unsafe trait AlwaysTransmuteFrom<Src, Neglect> where Neglect: TransmuteOptions { ... } unsafe trait UnstableTransmuteFrom<Src, Neglect> where Neglect: TransmuteOptions { ... } ``` This time, we don't need to settle what the exact type of `Neglect` ought to be. ### `(Option, ...)` Surface syntax: ```rust fn example<Src, Dst>() where /* not neglecting any static checks */ Dst: AlwaysTransmuteFrom<Src>, /* neglecting just validity */ Dst: AlwaysTransmuteFrom<Src, Neglect::Validity>, /* neglecting validity and alignment */ Dst: AlwaysTransmuteFrom<Src, (Neglect::Validity, Neglect::Alignment)>, /* or, equivalently: */ Dst: AlwaysTransmuteFrom<Src, (Neglect::Alignment, Neglect::Validity)>, {} ``` Pros: - `Neglect` can be defaulted; common case of *neglect nothing* therefore requires no additional typing - availability of methods can depend on how `Neglect` is instantiated. - works on stable rust - tuple syntax is familiar Cons: - ordering and multiplicity of options *shouldn't* matter, but it does; `(Neglect::Validity, Neglect::Alignment)` and `(Neglect::Alignment, Neglect::Validity)` are distinct types. ### `Option + Option` Surface syntax: ```rust fn example<Src, Dst>() where /* not neglecting any static checks */ Dst: AlwaysTransmuteFrom<Src>, /* neglecting just validity */ Dst: AlwaysTransmuteFrom<Src, NeglectValidity>, /* neglecting validity and alignment */ Dst: AlwaysTransmuteFrom<Src, NeglectValidity + NeglectAlignment>, {} ``` [Behind the scenes.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=536c6498c1088279a03cdc9afc3c00fa) Pros: - `Neglect` can be defaulted; common case of *neglect nothing* therefore requires no additional typing - availability of methods can depend on how `Neglect` is instantiated. - works on stable rust - not sensitive to reorderings or duplications of options! Cons: - `bare_trait_objects` are deprecated. could we squash that lint for these particular types?