profile
viewpoint

rust-lang/cargo 5819

The Rust package manager

rust-lang/book 5619

The Rust Programming Language

rust-lang/crates.io 1673

Source code for crates.io

rust-lang/chalk 912

An implementation and definition of the Rust trait system using a PROLOG-like logic solver

rust-lang/api-guidelines 755

Rust API guidelines

rust-lang/async-book 650

Asynchronous Programming in Rust

rust-lang/datafrog 355

A lightweight Datalog engine in Rust

rust-lang/arewewebyet 321

Are we web yet? A simple reckoning of Rust’s readiness for Web-related things.

rust-lang/crater 245

Run experiments across parts of the Rust ecosystem!

rust-lang/backtrace-rs 232

Backtraces in Rust

push eventrust-lang/docs.rs

Chase Wilson

commit sha acc0f067eb557b0b8c306afa0d0462c32804bffe

Log HTML rewriting errors

view details

push time in a few seconds

PR merged rust-lang/docs.rs

Log HTML rewriting errors A-admin A-backend P-low

Logs any HTML rewriting errors to the console using log::error!() and increments a metric for failed html rewrites. Could be useful to see if we ever reach a point where we need to raise our memory limit

+207 -10

2 comments

4 changed files

Kixiron

pr closed time in a few seconds

issue closedrust-lang/rust

Improve diagnostics for an invalid binding in a tuple struct pattern

This PR can be merged as is, but I think we could also add another branch that detects the case with PatKind::Ident(..) where .. is present and record it with a PartialRes::new(Res::Err), which should eliminate the second unnecessary error that complains about x not being defined. (Haven't looked at this deeply enough to be sure.)

Originally posted by @estebank in https://github.com/rust-lang/rust/pull/74557#discussion_r457614002

Follow-up of #74557

closed time in a few seconds

JohnTitor

issue commentrust-lang/rust

Improve diagnostics for an invalid binding in a tuple struct pattern

I'm going to close this issue as the above PR was reverted. @estebank If you have any ideas for improving the diagnostics introduced by #74963, I'm happy to see another issue pointing it out <3

JohnTitor

comment created time in a few seconds

pull request commentrust-lang/rust

Add `#[cfg(panic = '...')]`

I personally suspect that no matter what we do, adding this basically stabilizes that there's only two panic strategies -- there is all but guaranteed to be downstream breakage in the wild no matter how we go about stabilizing.

I take this point though am not convinced it matches precedent. We already have extensible cfg sets such as target_os or target_arch. Perhaps the only difference here is that users are more likely to assume there are only two panic strategies.

If the concern is that stabilizing this flag allows crates to build "bad habits" regarding panic compatibility, I'm willing to withdraw this PR and work towards other solutions. So far the only motivations that I've seen personally are when trying to write tests. As such we could solve this differently with patches to the test frameworks (as noted e.g. in #74301).

Though others may have legitimate non-test uses. As well as Josh above, @tmandry spoke of Fuschia adding this cfg in via cmdline. Perhaps they are also willing to elaborate?

davidhewitt

comment created time in a minute

Pull request review commentrust-lang/docs.rs

Log HTML rewriting errors

 impl RustdocPage {             .expect("missing TemplateData from the request extensions");          // Build the page of documentation-        let ctx = ctry!(req, tera::Context::from_serialize(self),);+        let ctx = ctry!(req, tera::Context::from_serialize(self));         // Extract the head and body of the rustdoc file so that we can insert it into our own html-        let html = ctry!(-            req,-            utils::rewrite_lol(rustdoc_html, max_parse_memory, ctx, templates)-        );+        // while logging OOM errors from html rewriting+        let html = match utils::rewrite_lol(rustdoc_html, max_parse_memory, ctx, templates) {+            Err(RewritingError::MemoryLimitExceeded(..)) => {+                crate::web::metrics::HTML_REWRITE_OOMS.inc();++                let config = extension!(req, Config);+                let err = failure::err_msg(format!(+                    "Failed to serve the rustdoc file '{}' because rewriting it surpassed the memory limit of {} bytes",+                    file_path, config.max_parse_memory,+                ));++                ctry!(req, Err(err))

Ah right, this is https://github.com/cloudflare/lol-html/issues/54. Don't worry about it then, we can add it later.

Kixiron

comment created time in a minute

PR opened rust-lang/docs.rs

Allow copying title and version from rustdoc pages

Same as https://github.com/rust-lang/docs.rs/pull/619 but for rustdoc pages.

@inikulin does this look like about what you want? I know you mentioned the old icon was not very intuitive, I changed it to 'fa-copy' instead.

/crate: image

rustdoc pages: new-clipboard

+189 -4

0 comment

5 changed files

pr created time in 3 minutes

Pull request review commentrust-lang/rfcs

RFC: Add JSON backend to Rustdoc

+- Feature Name: `rustdoc_json`+- Start Date: 2020-06-26+- RFC PR: [rust-lang/rfcs#2963](https://github.com/rust-lang/rfcs/pull/2963)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)++# Summary+[summary]: #summary++This RFC describes the design of a JSON output for the tool `rustdoc`, to allow tools to+lean on its data collection and refinement but provide a different front-end.++# Motivation+[motivation]: #motivation++The current HTML output of `rustdoc` is often lauded as a key selling point of Rust. It's a+ubiquitous tool, that you can use to easily find nearly anything you need to know about a crate.+However, despite its versatility, its output format has some drawbacks:++- Viewing this output requires a web browser, with (for some features of the output) a JavaScript+  interpreter.+- The HTML output of `rustdoc` is explicitly not stabilized, to allow `rustdoc` developers the+  option to tweak the display of information, add new information, etc. In addition it's not+  generated  with the intent of being scraped by users which makes converting this HTML into a+  different format impractical. People are still able to build [cool stuff](https://crates.io/crates/rocdoc)+  on top of it, but it's unwieldy and limiting to parse the HTML like that. For use cases like+  this, a stable, well documented, easily parsable format with semantic information+  accessible would be far more useful.+- As the HTML is the only available output of `rustdoc`, its integration into centralized,+  multi-language, documentation browsers is difficult.++In addition, `rustdoc` had JSON output in the past, but it failed to keep up with the changing+language and [was taken out][remove-json] in 2016. With `rustdoc` in a more stable position, it's+possible to re-introduce this feature and ensure its stability. This [was brought up in 2018][2018-discussion]+with a positive response and there are [several][2019-interest] [recent][rustdoc-infopages]+discussions indicating that it would be a useful feature.++In [the draft RFC from 2018][previous-rfc] there was some discussion of utilizing `save-analysis`+to provide this information, but with [RLS being replaced by rust-analyzer][RA-RLS] it's possible+that the feature will be eventually removed from the compiler. In addition `save-analysis` output+is just as unstable as the current HTML output of `rustdoc`, so a separate format is preferable.++[remove-json]: https://github.com/rust-lang/rust/pull/32773+[2018-discussion]: https://internals.rust-lang.org/t/design-discussion-json-output-for-rustdoc/8271/6+[2019-interest]: https://github.com/rust-lang/rust/issues/44136#issuecomment-467144974+[rustdoc-infopages]: https://internals.rust-lang.org/t/current-state-of-rustdoc-and-cargo/11721+[previous-rfc]: https://github.com/QuietMisdreavus/rfcs/blob/rustdoc-json/text/0000-rustdoc-json.md#unresolved-questions+[RA-RLS]: https://github.com/rust-lang/rfcs/pull/2912++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++(*Upon successful implementation/stabilization, this documentation should live in The Rustdoc+Book.*)++In addition to generating the regular HTML, `rustdoc` can create a JSON file based on your crate.+These can be used by other tools to take information about your crate and convert it into other+output formats, insert into centralized documentation systems, create language bindings, etc.++To get this output, pass the `--output-format json` flag to `rustdoc`:++```shell+$ rustdoc lib.rs --output-format json+```++This will output a JSON file in the current directory (by default). For example, say you have the+following crate:++```rust+//! Here are some crate-level docs!++/// Here are some docs for `some_fn`!+pub fn some_fn() {}++/// Here are some docs for `SomeStruct`!+pub struct SomeStruct;+```++After running the above command, you should get a `lib.json` file like the following:++```json+{+  "root": "0:0",+  "version": null,+  "includes_private": false,+  "index": {+    "0:3": {+      "crate_num": 0,+      "name": "some_fn",+      "source": {+        "filename": "lib.rs",+        "begin": [4, 0],+        "end": [4, 19]+      },+      "visibility": "public",+      "docs": "Here are some docs for `some_fn`!",+      "attrs": [],+      "kind": "function",+      "inner": {+        "decl": {+          "inputs": [],+          "output": null,+          "c_variadic": false+        },+        "generics": {...},+        "header": "",+        "abi": "\"Rust\""+      }+    },+    "0:4": {+      "crate_num": 0,+      "name": "SomeStruct",+      "source": {+        "filename": "lib.rs",+        "begin": [7, 0],+        "end": [7, 22]+      },+      "visibility": "public",+      "docs": "Here are some docs for `SomeStruct`!",+      "attrs": [],+      "kind": "struct",+      "inner": {+        "struct_type": "unit",+        "generics": {...},+        "fields_stripped": false,+        "fields": [],+        "impls": [...]+      }+    },+    "0:0": {+      "crate_num": 0,+      "name": "lib",+      "source": {+        "filename": "lib.rs",+        "begin": [1, 0],+        "end": [7, 22]+      },+      "visibility": "public",+      "docs": "Here are some crate-level docs!",+      "attrs": [],+      "kind": "module",+      "inner": {+        "is_crate": true,+        "items": [+          "0:4",+          "0:3"+        ]+      }+    }+  },+  "paths": {+    "0:3": {+      "crate_num": 0,+      "path": ["lib", "some_fn"],+      "kind": "function"+    },+    "0:4": {+      "crate_num": 0,+      "path": ["lib", "SomeStruct"],+      "kind": "struct"+    },+    ...+  },+  "extern_crates": {+    "9": {+      "name": "backtrace",+      "html_root_url": "https://docs.rs/backtrace/"+      },+    "2": {+      "name": "core",+      "html_root_url": "https://doc.rust-lang.org/nightly/"+    },+    "1": {+      "name": "std",+      "html_root_url": "https://doc.rust-lang.org/nightly/"+    },+    ...+  }+}+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation++(*Upon successful implementation/stabilization, this documentation should live in The Rustdoc+Book and/or an external crate's Rustdoc.*)++(*Given that the JSON output will be implemented as a set of Rust types with serde serialization,+the most useful docs for them would be the 40 or so types themselves. By writing docs on those+types the Rustdoc page for that module would become a good reference. It may be helpful to provide+some sort of [schema](http://json-schema.org/) for use with other languages*)++When you request JSON output from `rustdoc`, you're getting a version of the Rust abstract syntax+tree (AST), so you could see anything that you could export from a valid Rust crate. The following+types can appear in the output:++## ID++To provide various maps/references to items, the JSON output uses unique strings as IDs for each+item. They happen to be the compiler internal DefId for that item, but in the JSON blob they should+be treated as opaque as they aren't guaranteed to be stable across compiler invocations. IDs are+only valid/consistent within a single JSON blob. They cannot be used to resolve references between+the JSON output of different crates (see [the Resolving IDs section](#resolving-ids)).++## Crate++A Crate is the root of the outputted JSON blob. It contains all doc-relevant information about the+local crate, as well as some information about external items that are referred to locally.++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`name`    | String  | The name of the crate. If `--crate-name` is not given, based on the filename.+`version` | String  | (*Optional*) The version string given to `--crate-version`, if any.+`includes_private`  | bool  | Whether or not the output includes private items.+`root`    | [ID](#ID)      | The ID of the root module Item.+`index`   | Map<[ID](#ID), [Item](#Item)> | A collection of all Items in the crate[\*](#resolving-ids).+`paths`   | Map<[ID](#ID), [ItemSummary](#ItemSummary)> | Maps all IDs (even external ones[\*](#resolving-ids)) to a brief description including their name, crate of origin, and kind.+`extern_crates` | Map<int, [ExternalCrate](#ExternalCrate)> | A map of "crate numbers" to metadata about that crate.++### Resolving IDs++The crate's `index` contains mostly local items, which includes impls of external traits on local+types or local traits on external types. The exception to this is that external trait definitions+and their associated items are also included in the `index` because this information is useful when+generating the comprehensive list of methods for a type.++This means that many IDs aren't included in the `index` (any reference to a struct, macro, etc.+from a different crate). In these cases the fallback is to look up the ID in the crate's `paths`.+That gives [enough information](#ItemSummary) about the item to create cross references or simply+provide a name without copying all of the information about external items into the local+crate's JSON output.++### ExternalCrate++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`name`    | String  | The name of the crate.+`html_root_url` | String  | (*Optional*) The `html_root_url` for that crate if they specify one.++### ItemSummary++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`crate_num` | int   | A number corresponding to the crate this Item is from. Used as an key to the `extern_crates` map in [Crate](#Crate). A value of zero represents an Item from the local crate, any other number means that this Item is external.+`path`    | [String] | The fully qualified path (e.g. `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`) of this Item.+`kind`    | String  | What type of Item this is (see [Item](#Item)).++## Item++An Item represents anything that can hold documentation - modules, structs, enums, functions,+traits, type aliases, and more. The Item data type holds fields that can apply to any of these,+and leaves kind-specific details (like function args or enum variants) to the `inner` field.++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`crate_num` | int   | A number corresponding to the crate this Item is from. Used as an key to the `extern_crates` map in [Crate](#Crate). A value of zero represents an Item from the local crate, any other number means that this Item is external.+`name`    | String  | The name of the Item, if present. Some Items, like impl blocks, do not have names.+`span`    | [Span](#Span) | (*Optional*) The source location of this Item.+`visibility` | String | `"default"`, `"public"`, `"crate"`, or `"restricted"` (`pub(path)`).+`restricted_path` | String | (*Optional*) If `visitility == "restricted"`, this field contains the path that it's restricted to.+`docs`    | String  | The extracted documentation text from the Item.+`attrs`   | [String] | The attributes (other than doc comments) on the Item, rendered as strings.+`deprecation` | [Deprecation](#Deprecation) | (*Optional*) Information about the Item's deprecation, if present.+`kind`    | String  | The kind of Item this is. Determines what fields are in `inner`.+`inner`   | Object  | The type-specific fields describing this Item. Check the `kind` field to determine what's available.++### `kind == "module"`++Name     | Type   | Description+---------|--------|--------------------------------------------------------------------------------+`items`  | [[ID](#ID)] | The list of Items contained within this module. The order of definitions is preserved.++### `kind == "function"`++Name       | Type     | Description+-----------|----------|----------------------------------------------------------------------------+`decl`     | [FnDecl](#FnDecl) | Information about the function signature, or declaration.+`generics` | [Generics](#Generics) | Information about the function's type parameters and `where` clauses.+`header`   | String   | `"const"`, `"async"`, `"unsafe"`, or a space separated combination of those modifiers.+`abi`      | String   | The ABI string on the function. Non-`extern` functions have a `"Rust"` ABI, whereas `extern` functions without an explicit ABI are `"C"`. See [the reference](https://doc.rust-lang.org/reference/items/external-blocks.html#abi) for more details.++### `kind == "struct" || "union"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`struct_type` | String   | Either `"plain"` for braced structs, `"tuple"` for tuple structs, or `"unit"` for unit structs.+`generics`    | [Generics](#Generics) | Information about the struct's type parameters and `where` clauses.+`fields_stripped` | bool | Whether any fields have been removed from the result, due to being private or hidden.+`fields`      | [[ID](#ID)] | The list of fields in the struct. All of the corresponding Items have `kind == "structfield"`.+`impls`       | [[ID](#ID)] | All impls (both trait and inherent) for this type. All of the corresponding Items have `kind = "impl"`++### `kind == "structfield"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`type`        | [Type](#Type) | The type of this field.++### `kind == "enum"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`generics`    | [Generics](#Generics) | Information about the enum's type parameters and `where` clauses.+`fields`      | [[ID](#ID)]     | The list of variants in the enum. All of the corresponding Items have `kind == "variant"`.+`fields_stripped` | bool | Whether any variants have been removed from the result, due to being private or hidden.+`impls`       | [[ID](#ID)] | All impls (both trait and inherent) for this type. All of the corresponding Items have `kind = "impl"`++### `kind == "variant"`++`inner` can be one of the 3 following objects:+- `"plain"` (e.g. `Enum::Variant`)+- `{"tuple": [Type]}` (e.g. `Enum::Variant(u32, String)`)+- `{"struct": Object}` (e.g. `Enum::Variant{foo: u32, bar: String}`) in which case the `Object`+  has a single key `"struct"` with a value that's the same object as `inner` when `kind == "struct"`.++### `kind == "trait"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`is_auto`     | bool     | Whether this trait is an autotrait like `Sync`.+`is_unsafe`   | bool     | Whether this is an `unsafe trait` such as `GlobalAlloc`.+`items`       | [[ID](#ID)] | The list of method, constant, and typedef items contained in this trait definition.+`generics`    | [Generics](#Generics) | Information about the trait's type parameters and `where` clauses.+`bounds`      | [[GenericBound](#GenericBound)] | Trait bounds for this trait definition (e.g.  `trait Foo: Bar<T> + Clone`).++### `kind == "trait_alias"`++An [unstable feature](https://doc.rust-lang.org/beta/unstable-book/language-features/trait-alias.html)+which allows writing aliases like `trait Foo = std::fmt::Debug + Send` and then using `Foo` in+bounds rather than writing out the individual traits.++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`generics`    | [Generics](#Generics) | Any type parameters that the trait alias takes.+`bounds`      | [[GenericBound](#GenericBound)] | The list of traits after the equals.++### `kind == "method"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`decl`        | [FnDecl](#FnDecl) | Information about the method signature, or declaration.+`generics`    | [Generics](#Generics) | Information about the method's type parameters and `where` clauses.+`header`      | String   | `"const"`, `"async"`, `"unsafe"`, or a space separated combination of those modifiers.+`has_body`    | bool     | Whether this is just a method signature (in a trait definition) or a method with an actual body.++### `kind == "assoc_const"`++These items only show up in trait _definitions_. When looking at a trait impl item, the item where the associated constant is defined is a `"constant"` item.++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`type`        | [Type](#Type) | The type of this associated const.+`default`     | String | (*Optional*) The stringified expression for the default value, if provided.++### `kind == "assoc_type"`++These items only show up in trait _definitions_. When looking at a trait impl item, the item where the associated type is defined is a `"typedef"` item.++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`bounds`      | [[GenericBound](#GenericBound)] | The bounds for this associated type.+`default`     | [Type](#Type) | (*Optional*) The default for this type, if provided.++### `kind == "impl"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`is_unsafe`   | bool     | Whether this impl is for an unsafe trait.+`generics`    | [Generics](#Generics) | Information about the impl's type parameters and `where` clauses.+`provided_trait_methods` | [String] | The list of names for all provided methods in this impl block. This is provided for ease of access if you don't need more information from the `items` field.+`trait`       | [Type](#Type) | The trait being implemented or `null` if the impl is "inherent".+`for`         | [Type](#Type) | The type that the impl block is for.+`items`       | [[ID](#ID)] | The list of method, constant, and typedef items contained in this impl block.+`negative`    | bool     | Whether this is a negative impl (e.g. `!Sized` or `!Send`).+`synthetic`   | bool     | Whether this is an impl that's implied by the compiler (for autotraits).+`blanket_impl` | String | (*Optional*) The name of the generic parameter used for the blanket impl, if this impl was produced by one. For example `impl<T, U> Into<U> for T` would result in `blanket_impl == "T"`.++### `kind == "constant"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`type`        | [Type](#Type) | The type of this constant.+`expr`        | String   | The stringified expression of this constant.+`value`       | String   | (*Optional*) The value of the evaluated expression for this constant, which is only computed for numeric types.+`is_literal`  | bool     | Whether this constant is a bool, numeric, string, or char literal.++### `kind == "static"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`type`        | [Type](#Type) | The type of this static.+`expr`        | String   | The stringified expression that this static is assigned to.+`mutable`     | bool     | Whether this static is mutable.++### `kind == "typedef"`++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`type`        | [Type](#Type) | The type on the right hand side of this definition.+`generics`    | [Generics](#Generics) | Any generic parameters on the left hand side of this definition.++### `kind == "opaque_ty"`++Represents [trait aliases](https://doc.rust-lang.org/beta/unstable-book/language-features/trait-alias.html)+of the form:++```rust+type Foo<T> = Clone + std::fmt::Debug + Into<T>;+```++Name          | Type     | Description+--------------|----------|-------------------------------------------------------------------------+`bounds`      | [[GenericBound](#GenericBound)] | The trait bounds on the right hand side.+`generics`    | [Generics](#Generics) | Any generic parameters on the type itself.++### `kind == "foreign_type"`++`inner` contains no fields. This item represents a type declaration in an extern block (see [here](https://github.com/rust-lang/rfcs/blob/master/text/1861-extern-types.md)+for more details):++```rust+extern {+    type Foo;+}+```++### `kind == "extern_crate"`++Name     | Type     | Description+---------|----------|-------------------------------------------------------------------------+`name`   | String   | The name of the extern crate.+`rename` | String   | (*Optional*) The renaming of this crate with `extern crate foo as bar`.++### `kind == "import"`++Name     | Type     | Description+---------|----------|-------------------------------------------------------------------------+`source` | String   | The full path being imported (e.g. `"super::some_mod::other_mod::Struct"`).+`name`   | String   | The name of the imported item (may be different from the last segment of `source` due to import renaming: `use source as name`).+`id`     | [ID](#ID) | (*Optional*) The ID of the item being imported.+`glob`   | bool     | Whether this import ends in a glob: `use source::*`.++### `kind == "macro"`++A `macro_rules!` declarative macro. Contains a single string with the source representation of+the macro with the patterns stripped, for example:++```rust+macro_rules! vec {+    () => { ... };+    ($elem:expr; $n:expr) => { ... };+    ($($x:expr),+ $(,)?) => { ... };+}+```++TODO: proc macros++## Span++Name       | Type     | Description+-----------|----------|----------------------------------------------------------------------------+`filename` | String   | The path to the source file for this span relative to the crate root.+`begin`    | (int, int) | The zero indexed line and column of the first character in this span.+`begin`    | (int, int) | The zero indexed line and column of the last character in this span.++## Deprecation++Name       | Type     | Description+-----------|----------|----------------------------------------------------------------------------+`since`    | String   | (*Optional*) Usually a version number when this Item first became deprecated.+`note`     | String   | (*Optional*) The reason for deprecation and/or what alternatives to use.++## FnDecl++Name       | Type     | Description+-----------|----------|----------------------------------------------------------------------------+`inputs`   | [(String, [Type](#Type))] | A list of parameter names and their types.

+1 to marking the format of the value as unstable and subject to change, but I think we could stabilize its existence and that it's a reasonable thing to put in the docs. (Here and elsewhere)

P1n3appl3

comment created time in 3 minutes

issue commentrust-lang/rust

x.py expects python3.exe on Windows

Very odd; I use "python x.py" on Windows just fine.

Kixiron

comment created time in 5 minutes

startedrust-lang/futures-rs

started time in 6 minutes

Pull request review commentrust-lang/rfcs

RFC: Add JSON backend to Rustdoc

+- Feature Name: `rustdoc_json`+- Start Date: 2020-06-26+- RFC PR: [rust-lang/rfcs#2963](https://github.com/rust-lang/rfcs/pull/2963)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)++# Summary+[summary]: #summary++This RFC describes the design of a JSON output for the tool `rustdoc`, to allow tools to+lean on its data collection and refinement but provide a different front-end.++# Motivation+[motivation]: #motivation++The current HTML output of `rustdoc` is often lauded as a key selling point of Rust. It's a+ubiquitous tool, that you can use to easily find nearly anything you need to know about a crate.+However, despite its versatility, its output format has some drawbacks:++- Viewing this output requires a web browser, with (for some features of the output) a JavaScript+  interpreter.+- The HTML output of `rustdoc` is explicitly not stabilized, to allow `rustdoc` developers the+  option to tweak the display of information, add new information, etc. In addition it's not+  generated  with the intent of being scraped by users which makes converting this HTML into a+  different format impractical. People are still able to build [cool stuff](https://crates.io/crates/rocdoc)+  on top of it, but it's unwieldy and limiting to parse the HTML like that. For use cases like+  this, a stable, well documented, easily parsable format with semantic information+  accessible would be far more useful.+- As the HTML is the only available output of `rustdoc`, its integration into centralized,+  multi-language, documentation browsers is difficult.++In addition, `rustdoc` had JSON output in the past, but it failed to keep up with the changing+language and [was taken out][remove-json] in 2016. With `rustdoc` in a more stable position, it's+possible to re-introduce this feature and ensure its stability. This [was brought up in 2018][2018-discussion]+with a positive response and there are [several][2019-interest] [recent][rustdoc-infopages]+discussions indicating that it would be a useful feature.++In [the draft RFC from 2018][previous-rfc] there was some discussion of utilizing `save-analysis`+to provide this information, but with [RLS being replaced by rust-analyzer][RA-RLS] it's possible+that the feature will be eventually removed from the compiler. In addition `save-analysis` output+is just as unstable as the current HTML output of `rustdoc`, so a separate format is preferable.++[remove-json]: https://github.com/rust-lang/rust/pull/32773+[2018-discussion]: https://internals.rust-lang.org/t/design-discussion-json-output-for-rustdoc/8271/6+[2019-interest]: https://github.com/rust-lang/rust/issues/44136#issuecomment-467144974+[rustdoc-infopages]: https://internals.rust-lang.org/t/current-state-of-rustdoc-and-cargo/11721+[previous-rfc]: https://github.com/QuietMisdreavus/rfcs/blob/rustdoc-json/text/0000-rustdoc-json.md#unresolved-questions+[RA-RLS]: https://github.com/rust-lang/rfcs/pull/2912++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++(*Upon successful implementation/stabilization, this documentation should live in The Rustdoc+Book.*)++In addition to generating the regular HTML, `rustdoc` can create a JSON file based on your crate.+These can be used by other tools to take information about your crate and convert it into other+output formats, insert into centralized documentation systems, create language bindings, etc.++To get this output, pass the `--output-format json` flag to `rustdoc`:++```shell+$ rustdoc lib.rs --output-format json+```++This will output a JSON file in the current directory (by default). For example, say you have the+following crate:++```rust+//! Here are some crate-level docs!++/// Here are some docs for `some_fn`!+pub fn some_fn() {}++/// Here are some docs for `SomeStruct`!+pub struct SomeStruct;+```++After running the above command, you should get a `lib.json` file like the following:++```json+{+  "root": "0:0",+  "version": null,+  "includes_private": false,+  "index": {+    "0:3": {+      "crate_num": 0,+      "name": "some_fn",+      "source": {+        "filename": "lib.rs",+        "begin": [4, 0],+        "end": [4, 19]+      },+      "visibility": "public",+      "docs": "Here are some docs for `some_fn`!",+      "attrs": [],+      "kind": "function",+      "inner": {+        "decl": {+          "inputs": [],+          "output": null,+          "c_variadic": false+        },+        "generics": {...},+        "header": "",+        "abi": "\"Rust\""+      }+    },+    "0:4": {+      "crate_num": 0,+      "name": "SomeStruct",+      "source": {+        "filename": "lib.rs",+        "begin": [7, 0],+        "end": [7, 22]+      },+      "visibility": "public",+      "docs": "Here are some docs for `SomeStruct`!",+      "attrs": [],+      "kind": "struct",+      "inner": {+        "struct_type": "unit",+        "generics": {...},+        "fields_stripped": false,+        "fields": [],+        "impls": [...]+      }+    },+    "0:0": {+      "crate_num": 0,+      "name": "lib",+      "source": {+        "filename": "lib.rs",+        "begin": [1, 0],+        "end": [7, 22]+      },+      "visibility": "public",+      "docs": "Here are some crate-level docs!",+      "attrs": [],+      "kind": "module",+      "inner": {+        "is_crate": true,+        "items": [+          "0:4",+          "0:3"+        ]+      }+    }+  },+  "paths": {+    "0:3": {+      "crate_num": 0,+      "path": ["lib", "some_fn"],+      "kind": "function"+    },+    "0:4": {+      "crate_num": 0,+      "path": ["lib", "SomeStruct"],+      "kind": "struct"+    },+    ...+  },+  "extern_crates": {+    "9": {+      "name": "backtrace",+      "html_root_url": "https://docs.rs/backtrace/"+      },+    "2": {+      "name": "core",+      "html_root_url": "https://doc.rust-lang.org/nightly/"+    },+    "1": {+      "name": "std",+      "html_root_url": "https://doc.rust-lang.org/nightly/"+    },+    ...+  }+}+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation++(*Upon successful implementation/stabilization, this documentation should live in The Rustdoc+Book and/or an external crate's Rustdoc.*)++(*Given that the JSON output will be implemented as a set of Rust types with serde serialization,+the most useful docs for them would be the 40 or so types themselves. By writing docs on those+types the Rustdoc page for that module would become a good reference. It may be helpful to provide+some sort of [schema](http://json-schema.org/) for use with other languages*)++When you request JSON output from `rustdoc`, you're getting a version of the Rust abstract syntax+tree (AST), so you could see anything that you could export from a valid Rust crate. The following+types can appear in the output:++## ID++To provide various maps/references to items, the JSON output uses unique strings as IDs for each+item. They happen to be the compiler internal DefId for that item, but in the JSON blob they should+be treated as opaque as they aren't guaranteed to be stable across compiler invocations. IDs are+only valid/consistent within a single JSON blob. They cannot be used to resolve references between+the JSON output of different crates (see [the Resolving IDs section](#resolving-ids)).++## Crate++A Crate is the root of the outputted JSON blob. It contains all doc-relevant information about the+local crate, as well as some information about external items that are referred to locally.++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`name`    | String  | The name of the crate. If `--crate-name` is not given, based on the filename.+`version` | String  | (*Optional*) The version string given to `--crate-version`, if any.+`includes_private`  | bool  | Whether or not the output includes private items.+`root`    | [ID](#ID)      | The ID of the root module Item.+`index`   | Map<[ID](#ID), [Item](#Item)> | A collection of all Items in the crate[\*](#resolving-ids).+`paths`   | Map<[ID](#ID), [ItemSummary](#ItemSummary)> | Maps all IDs (even external ones[\*](#resolving-ids)) to a brief description including their name, crate of origin, and kind.+`extern_crates` | Map<int, [ExternalCrate](#ExternalCrate)> | A map of "crate numbers" to metadata about that crate.++### Resolving IDs++The crate's `index` contains mostly local items, which includes impls of external traits on local+types or local traits on external types. The exception to this is that external trait definitions+and their associated items are also included in the `index` because this information is useful when+generating the comprehensive list of methods for a type.++This means that many IDs aren't included in the `index` (any reference to a struct, macro, etc.+from a different crate). In these cases the fallback is to look up the ID in the crate's `paths`.+That gives [enough information](#ItemSummary) about the item to create cross references or simply+provide a name without copying all of the information about external items into the local+crate's JSON output.++### ExternalCrate++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`name`    | String  | The name of the crate.+`html_root_url` | String  | (*Optional*) The `html_root_url` for that crate if they specify one.++### ItemSummary++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`crate_num` | int   | A number corresponding to the crate this Item is from. Used as an key to the `extern_crates` map in [Crate](#Crate). A value of zero represents an Item from the local crate, any other number means that this Item is external.+`path`    | [String] | The fully qualified path (e.g. `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`) of this Item.+`kind`    | String  | What type of Item this is (see [Item](#Item)).++## Item++An Item represents anything that can hold documentation - modules, structs, enums, functions,+traits, type aliases, and more. The Item data type holds fields that can apply to any of these,+and leaves kind-specific details (like function args or enum variants) to the `inner` field.++Name      | Type    | Description+----------|---------|------------------------------------------------------------------------------+`crate_num` | int   | A number corresponding to the crate this Item is from. Used as an key to the `extern_crates` map in [Crate](#Crate). A value of zero represents an Item from the local crate, any other number means that this Item is external.+`name`    | String  | The name of the Item, if present. Some Items, like impl blocks, do not have names.+`span`    | [Span](#Span) | (*Optional*) The source location of this Item.+`visibility` | String | `"default"`, `"public"`, `"crate"`, or `"restricted"` (`pub(path)`).+`restricted_path` | String | (*Optional*) If `visitility == "restricted"`, this field contains the path that it's restricted to.+`docs`    | String  | The extracted documentation text from the Item.+`attrs`   | [String] | The attributes (other than doc comments) on the Item, rendered as strings.

The intention of this is to give renderers an "easy path" way to consume this format by giving them a reasonable string of text to present. If we document that the exact format is unstable and subject to change, would that alleviate your concerns @jyn514?

P1n3appl3

comment created time in 7 minutes

pull request commentrust-lang/rfcs

RFC: Placement by return

The RFC mentioned "generator" which yields Layout, then finishes its work. Also the problem with Result<T,E>. It made me think about sufficiency of "generator"s yield: we could yield additional info, like which variant of enum we actually returning: This allows to return things like Result<[u8],str>. We could then build logic, whether we want allocation or not.

PoignardAzur

comment created time in 7 minutes

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)] // declare `Foo` to be *stably* transmutable+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                    ^ there's a padding byte here, between these fields++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!+//                  ^^^^^^^^^^^^^^ provided by the `TransmuteInto` trait++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:15:27+//    |+// 15 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T> {+        data: *const T,+        len: usize,+        lifetime: core::marker::PhantomData<&'a ()>,+    }++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+                lifetime: core::marker::PhantomData,+            }+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```++The above code is "safe" because our simplified definition of constructability fails to recognize this pattern of encapsulation, and because `NeglectStability` is a `SafeTransmutationOption`.++The intent of `NeglectStability` is to permit the safe transmutation of types that predate the stabilization of the stability declaration traits. It also provides a convenient escape-hatch for type authors to neglect the stability of transmutations of their *own* types, without sacrificing safety. `NeglectStability` is a `SafeTransmutationOption` because, in principle, neglecting stability does not diminish safety. Our simplified definition of constructability violates this principle.++By temporarily sacrificing these goals, we may preserve safety solely...++##### ...at the Cost of `NeglectStability`+We may preserve safety by demoting `NeglectStability` to `UnsafeTransmutationOption`-status.++In doing so, a third-party is forced to resort to an `unsafe` transmutation to construct `NonEmptySlice`; e.g.:++```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,+{+    // unsafe because we `NeglectStability`+    unsafe { src.unsafe_transmute_into() }+}+```++Demoting `NeglectStability` to unsafe-status does not stop type authors from opting-in to stable (and thus safe) transmutations; e.g., with `derive(PromiseTransmutableFrom)`:+```rust+pub mod crate_a {++    #[derive(PromiseTransmutableFrom)]+    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[derive(PromiseTransmutableFrom)]+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+In the above example, the type author declares `NonEmptySlice` and `NonEmptySliceInner` to be stably instantiatable via transmutation. Given this, a third-party no longer needs to resort to `unsafe` code to violate the the invariants on `inner`:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```+This safety hazard is not materially different from the one that would be induced if the type author implemented `DerefMut<Target=NonEmptySliceInner>` for `NonEmptySlice`, or made the `private` module `pub`, or otherwise explicitly provided outsiders with unrestricted mutable access to `data`.++##### Recommendation+We recommend that that implementers of this RFC initially simplify constructability by:+ - adopting our simplified definition of constructability+ - demoting `NeglectStability` to unsafe status (i.e., not implementing `SafeTransmuteOptions` for `NeglectStability`; *only* `UnsafeTransmuteOptions`)++If and when the implementation of `TransmuteFrom` encodes our complete definition of constructability, `NeglectStability` shall become a safe transmute option.+++## Dissecting Stability++In this section, we iteratively review the design of the stability declaration traits, starting with a simplest-possible design:+```rust+pub unsafe trait PromiseTransmutableFrom+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+{+    type Archetype;+}+```++### Part 1: Towards Safety++#### Forbidding Archetypes with Nonsense Validity+The simplest definitions of the stability declaration traits *must* be `unsafe` because `Archetype` can be instantiated in ways that undermine soundness; e.g.:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16; // <- Nonsense!+}++unsafe impl PromiseTransmutableFrom for u16 {+    type Archetype = u16;+}+```+These declarations subvert safety! Given these declarations, Rust will accept `u8: TransmuteInto<u16>`. This is problematic: `u8` is smaller than `u16`.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+u8:+    TransmuteInto<&'a Aligned8>+```++First, recall that a `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable into `<Dst as PromiseTransmutableFrom>::Archetype`, notwithstanding stability. The layouts of `Src` and `Dst` themselves are, in theory, immaterial — all that matters are the layouts of their stability archetypes. Formally:+```rust+𝙞𝙛+    <Src as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <Dst as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    Src: TransmuteInto<Dst>+```++We apply this rule to our initial equation:+```rust+𝙞𝙛+    <u8 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <u16 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    u8: TransmuteInto<u16>+```++Next, recall the definitions of `PromiseTransmutableInto` for `u8` and `PromiseTransmutableFrom` for `u16`:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16; // <- Nonsense!+}++unsafe impl PromiseTransmutableFrom for u16 {+    type Archetype = u16;+}+```+We apply these definitions to evaluate `<u8 as PromiseTransmutableInto>::Archetype` and `<u16 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    u16:+        TransmuteInto<+            u16,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    u8: TransmuteInto<u16>+```+Since `u16` can be safely transmuted into `u16`, the compiler accepts the transmutation of `u8` into `u16`!++</details>++---++We can prevent  nonsense archetypes by demanding that `Archetype` is transmutable into `Self` (notwithstanding stability):+```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+{+    type Archetype;+}+```++Our previous attempt to skirt soundness now produces a compile error:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16;+                  // ^^^ the trait `TransmuteInto<u8, _>` is not implemented for `u16`+}+```++#### Forbidding Archetypes with Nonsense Alignment+Unfortunately, the above definition is still flawed. Consider these stability declarations:++```rust+#[derive(PromiseTransmutableFrom)]+#[repr(C)]+pub struct Aligned1;++#[derive(PromiseTransmutableInto)]+#[repr(C, align(8))]+pub struct Aligned8;++unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```++These declarations subvert safety! Given these declarations, Rust would accept the bound `&Aligned1: TransmuteInto<&Aligned8>`. This is problematic: `Aligned8` has *stricter* alignment requirements than `Aligned1`.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+for<'a> &'a Aligned1:+        TransmuteInto<&'a Aligned8>+```++As before, we first apply the stability rule to our equation:+```rust+𝙞𝙛+    <&'a Aligned1 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <&'a Aligned8 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```++Next, recall the definitions of `PromiseTransmutableInto` and `PromiseTransmutableFrom` for `&T`:+```rust+unsafe impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a T::Archetype;+}++unsafe impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+We apply these definitions to evaluate `<&_ as PromiseTransmutableInto>::Archetype` and `<&_ as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    &'a <Aligned1 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            &'a <Aligned8 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```++Finally, recall the definitions of `PromiseTransmutableInto` for `Aligned1` and `PromiseTransmutableFrom` for `Aligned8`:+```rust+unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```+We apply these definitions to evaluate `<Aligned1 as PromiseTransmutableInto>::Archetype` and `<Aligned8 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    &'a Aligned8:+        TransmuteInto<+            &'a Aligned1,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```+Since `&'a Aligned8` can be safely transmuted into `&'a Aligned1`, the compiler accepts the transmutation of `&'a Aligned1` into `&'a Aligned1`!++</details>++---++This safety hazard can be prevented by rewriting our `where` bound like so: +```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>+{+    type Archetype;+}+```++Our previous attempt to skirt safety now produces a compiler error:+```rust+unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+                  // ^^^^^^^^ the trait `TransmuteFrom<&'_ Aligned1, NeglectStability>` is not implemented for `&'_ Aligned8`+}+```+++#### Forbidding Archetypes with Nonsense Validity Under Mutate-able Reference Transmutation+Unfortunately, the above definition is still flawed. Consider these stability declarations:+```rust+#[repr(u8)]+enum Boolean {+    False = 0,+    True = 1,+}++unsafe impl PromiseTransmutableInto for Boolean {+    type Type = u8;+}+```++Given these declarations, Rust would accept the bound `&mut Boolean: TransmuteInto<&mut u8>`. This is problematic: transmutations involving mutate-able references must not expand bit-validity.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Why would this transmutation be accepted? Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+for<'a> &'a mut Boolean:+        TransmuteInto<&'a mut u8>+```++As before, we first apply the stability rule to our equation:+```rust+𝙞𝙛+    for<'a> <&'a mut Boolean as PromiseTransmutableInto>::Archetype:+            TransmuteInto<+                <&'a mut u8 as PromiseTransmutableFrom>::Archetype,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```++Next, recall the definitions of `PromiseTransmutableInto` and `PromiseTransmutableFrom` for `&mut T`:+```rust+unsafe impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a T::Archetype;+}++unsafe impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+We apply these definitions to evaluate `<& mut _ as PromiseTransmutableInto>::Archetype` and `<& mut _ as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    for<'a> &'a mut <Boolean as PromiseTransmutableInto>::Archetype:+            TransmuteInto<+                &'a mut <u8 as PromiseTransmutableFrom>::Archetype,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```++Finally, recall the definitions of `PromiseTransmutableInto` for `Boolean` and `PromiseTransmutableFrom` for `u8`:+```rust+unsafe impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+}++unsafe impl PromiseTransmutableFrom for u8 {+    type Archetype = Self;+}+```+We apply these definitions to evaluate `<Boolean as PromiseTransmutableInto>::Archetype` and `<u8 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    for<'a> &'a mut u8:+            TransmuteInto<+                &'a mut u8,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```+Since `&'a mut u8` can be safely transmuted into `&'a mut u8`, the compiler accepts the transmutation of `&mut Boolean` into `&mut u8`.++</details>++---++This safety hazard can be prevented by rewriting our `where` bounds like so: +```rust+pub trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>,+    for<'a> &'a mut Self::Archetype: TransmuteInto<&'a mut Self, NeglectStability>+{+    type Archetype;+}++pub trait PromiseTransmutableInto+where+    Self::Archetype: TransmutFrom<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>,+    for<'a> &'a mut Self::Archetype: TransmuteFrom<&'a mut Self, NeglectStability>+{+    type Archetype;+}+```++Our previous attempt to skirt safety now produces a compiler error:+```rust+impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+                  // ^^ the trait `TransmuteFrom<&'_ mut u8, NeglectStability>` is not implemented for `&'_ mut Boolean`+}+```++### Part 2: Towards Flexibility+In the previous two sections, we bypassed the safety effects of the `PromiseTransmutable{From,Into}` traits' `where` bounds by defining archetypes whose quirks were only apparent under a *more* restrictive transmutation than that enforced by the `where` bound.++We cannot play the same trick to bypass safety with our latest `where` bound. Between transmutations involving values, shared references and unique references, the rules governing transmutations involving unique references are the most restrictive.++However, this safety comes at the expense of flexibility. Recall our last 'dangerous' archetype:+```rust+impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+                  // ^^ the trait `TransmuteFrom<&'_ mut u8, NeglectStability>` is not implemented for `&'_ mut Boolean`+}+```+This archetype is sensible in the context of value transmutations. It's sensible in the context of immutable reference transmutations. The *only* context in which it is *not* sensible are mutate-able reference transmutations! Our changes achieved safety at the significant expense of flexibility.++In this section, we begin at our previous value-safe definition of the stability declaration traits:+```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+{+    type Archetype;+}+```+...and solve its reference-unsafety in a manner that preserves flexibility.++#### Compartmentalizing Shared Reference Transmutation Stability+Reconsider these stability declarations:+```rust+#[derive(PromiseTransmutableFrom)]+#[repr(C)]+pub struct Aligned1;++#[derive(PromiseTransmutableInto)]+#[repr(C, align(8))]+pub struct Aligned8;++unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```++Given these declarations, Rust would accept the bound `&Aligned1: TransmuteInto<&Aligned8>`. This is problematic: `Aligned8` has *stricter* alignment requirements than `Aligned1`.++In our derivation of why the compiler accepted this transmutation, we referred to the stability declarations of `&T`:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom,+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+Rather than change the `where` bound of the *definitions* of `PromiseTransmutableFrom` and `PromiseTransmutableInto`, we can simply change the `where` bound of those two *implementations* of the traits:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}+```++#### Compartmentalizing Unique Reference Transmutation Stability+Likewise, for unique references, we go from this:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a mut T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a mut T::Archetype;+}+```+...to this:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom,+    for<'a> &'a mut Self::Archetype: TransmuteInto<&'a mut Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto,+    for<'a> &'a mut Self::Archetype: TransmuteFrom<&'a mut Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}+```++### Part 3: Towards Sensibility++In the previous two parts, we developed safe-and-flexible stability declaration traits. While we cannot make unsafe archetype choices, we can still make *silly* archetype choices. For instance, we can declare the stability of our types in terms of types that are *not* stable:++```rust+#[repr(u8)]+pub struct Foo { ... }++#[repr(u8)]+pub struct Bar { ... }++impl PromiseTransmutableInto for Foo {+    type Archetype = Bar;+}+```++We can prevent these sorts of silly archetypes by requiring that `Archetype` itself is stable, and that its stability archetype is not transitively defined:++```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++# Drawbacks+[drawbacks]: #drawbacks++## No Notion of Platform Stability+The stability declaration traits communicate library layout stability, but not *platform* layout stability. A transmutation is platform-stable if it compiling one one platform implies it will compile on all other platforms. Unfortunately, platform-unstable types are common;  e.g.:++- All pointer-related primitive types (`usize`, `isize`, `*const T`, `*mut T`, `&T`, `&mut T`) possess platform-dependent layouts; their sizes and alignments are well-defined, but vary between platforms. Concretely, whether `usize` is `TransmuteInto<[u8; 4]>` or `TransmuteInto<[u8; 8]>` will depend on  the platform.+- The very existence of some types depends on platform, too; e.g., the contents of [`core::arch`](https://doc.rust-lang.org/stable/core/arch/), [`std::os`](https://doc.rust-lang.org/stable/std/os/), and [`core::sync::atomic`](https://doc.rust-lang.org/stable/std/sync/atomic/) all depend on platform.++Expanding this RFC to address such types would introduce considerable additional complexity:+<ol>+<li>++**Cognitive Complexity:** For types whose layout varies between platforms, the [stability] declaration traits could, *perhaps*, be adapted to encode platform-related guarantees. We anticipate this would contribute substantial cognitive complexity. Type authors, even those with no interest in cross-platform stability, would nonetheless need to reason about the layout properties of their types on platforms that might not yet exist.+</li>+<li>++**Ergonomic Complexity:** Platform instabilities are contagious: a type that *contains* a platform-unstable type is, itself, platform-unstable. Due to the sheer virulence of types with platform-dependent layouts, an explicit '`NeglectPlatformStability`' option would need to be used for *many* simple transmutations. The ergonomic cost of this would also be substantial.++</li>+<li>++**Implementation Complexity:** The mechanisms proposed by this RFC are, fundamentally, applications of and additions to Rust's type system (i.e., they're traits). Mechanisms that impact platform stability, namely `#[cfg(...)]` annotations, long precede type-resolution and layout computation in the compilation process. For instance, it's possible to define types with impossible layouts:    +```rust+#[cfg(any())]+struct Recursive(Recursive);+```+This program compiles successfully on all platforms because, from the perspective of later compilation stages, `Recursive` may as well not exist.++</li>+</ol>++The issues of platform layout stability exposed by this RFC are not fundamentally different from the challenges of platform API stability. These challenges are already competently addressed by the mechanisms proposed in [RFC1868](https://github.com/rust-lang/rfcs/pull/1868). For this reason, and for the aforementioned concerns of additional complexity, we argue that communicating and enforcing platform layout stability must remain outside the scope of this RFC.++## Stability of *Unsafe* Transmutations+[drawback-unsafe-stability]: #Stability-of-Unsafe-Transmutations++The model of stability proposed by this RFC frames stability as a quality of *safe* transmutations. A type author cannot specify stability archetypes for *unsafe* transmutations, and it is reasonable to want to do so.++To accomodate this, we may modify the definitions of `PromiseTransmutableFrom` and `PromiseTransmutableInto` to consume an optional `Neglect` parameter, to allow for stability declarations for unsafe transmutations:+```rust+pub trait PromiseTransmutableFrom<Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions+{+    type Archetype+        : TransmuteInto<Self, Sum<Neglect, NeglectStability>>+        + PromiseTransmutableInto<Sum<Neglect, NeglectStability>>;+}++pub trait PromiseTransmutableInto<Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions+{+    type Archetype+        : TransmuteFrom<Self, Sum<Neglect, NeglectStability>>+        + PromiseTransmutableInto<Sum<Neglect, NeglectStability>>;+}+```+Implementations of these traits for a given `Neglect` declares that a transmutation which is accepted while neglecting a particular set of checks (namely the set encoded by `Neglect`) will *continue* to be possible.++We omit these definition from this RFC's recommendations because they are not completely satisfying. For instance, `Neglect` is a *logically* unordered set of options, but is encoded as a tuple (which *is* ordered). To declare a transmutation that requires neglecting validity and alignment checks as stable, only *one* of these impls ought to be necessary:++```rust+impl PromiseTransmutableFrom<(NeglectAlignment, NeglectValidity)> for Foo+{+    ...+}++impl PromiseTransmutableFrom<(NeglectValidity, NeglectAlignment)> for Foo+{+    ...+}+```+Writing *both* impls (as we do above) is logically nonsense, but is nonetheless supported by Rust's coherence rules.+++# Rationale and alternatives+[rationale-and-alternatives]: #rationale-and-alternatives++## Case Studies++### Case Study: Making Unsafe Rust Safer+[case-study-safer-unsafe]: #Case-Study-Making-Unsafe-Rust-Safer++This RFC proposes mechanisms for safe transmutation and safer *unsafe* transmutation. How might [Kelley's motivating example][motivation-safer-unsafe] change in light of these mechanisms?++#### Safer Unsafe+For the compiler to accept a use of `unsafe_transmute`, we must:+   - use `unsafe_transmute` with the `NeglectAlignment` option+   - annotate `Foo` with `#[repr(C)]` so its layout is defined+   - annotate `Foo` with `#[derive(PromiseTransmutableFrom,PromiseTransmutableInto)]` to indicate its layout is library-stable (alternatively, we could also use the  `NeglectStability` option)++The sum of these changes:+```rust+use core::transmute::{+    unsafe_transmute,+    options::NeglectAlignment,+    stability::FixedLayout,+};+++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    let mut array: [u8; 1024] = [1; 1024];++    let mut foo = unsafe {+        // check alignment ourselves+        assert_eq!((src as *const u8 as usize) % align_of::<Foo>(), 0);++        // transmute `&mut array` to `&mut Foo`+        // permitted becasue we promise to check the alignment ourselves+        let foo = unsafe_transmute::<&mut [u8; 1024], &mut Foo, NeglectAlignment>(&mut array);+    };++    foo.a += 1;+}+```++#### No Unsafe Needed!+Better yet, we may use a completely *safe* transmute if we statically align the byte array:++```rust+use core::transmute::{+    TransmuteInto,+    options::NeglectAlignment,+    stability::FixedLayout,+};+++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+struct Foo {+    a: i32,+    b: i32,+}++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C, align(4)]+struct Aligned([u8; 1024]);++fn main() {+    let mut array: Aligned = Aligned([1; 1024]);++    let foo : &mut Foo = (&mut array[0]).transmute_into();++    foo.a += 1;+}+```++### Case Study: Abstractions for Packet Parsing+***TODO: josh***++### Case Study: Abstractions for Pointer Bitpacking+[case-study-alignment]: #case-study-abstractions-for-pointer-bitpacking++A [previous motivating example](#expressing-layout-requirements) involved a generic abstraction only usable with types meeting certain layout requirements: pointer bitpacking. Using this RFC's mechanisms, we can require that a reference to a generic type `T` has alignment of at least a given value (e.g., `8`) by first defining a ZST with that alignment:+```rust+#[derive(PromiseTransmutableFrom)]+#[repr(align(8)]+struct Aligned8;+```+and then using this `where` bound:+```rust+where+    &T: TransmuteInto<&Aligned8>+```++## Rationale: `TransmuteFrom`/`TransmuteInto`++### Why support arbitrary transmutation?+Some [prior art][prior-art], especially in the crate ecosystem, provides an API that [only supports transmutations involving particular types](#Source-and-Destination-Types-Supported) (e.g., from/into bytes). As we discuss in the [prior art][prior-art] section, we believe that the inflexibility of such approaches make them a poor basis of a language proposal. In particular, these restrictive approaches don't leave room to grow: supporting additional transmutations requires additional traits.++The API advocated by this proposal is unopinionated about what transmutations users might wish to do, and what transmutations the compiler is able to reason about. The implementation of this RFC may be initially very simple (and perhaps support no more than the restrictive approaches allow for), but then subsequently grow in sophistication—*without* necessitating public API changes.++### Why *two* traits?+If `TransmuteInto` is implemented in terms of `TransmuteFrom`, why provide it at all? We do so for consistency with libcore's [`From`/`Into`](https://doc.rust-lang.org/stable/rust-by-example/conversion/from_into.html) traits, and because directionality conveys intent: `TransmuteFrom` connotes *conversion*, whereas `TransmuteInto` connotes initialization. We believe that the supporting code examples of this RFC demonstrate the explanatory benefits of providing *both* traits.++## Rationale: Transmutation Options++### Granularity+Although the focus of our API is statically-correct, infalible transmutations, the ability to opt-out of particular static checks is essential for building safer *fallible* mechanisms, such as alignment-fallible [reference casting][ext-ref-casting], or validity-fallible transmutations (e.g., `bool` to `u8`).++### Representation+Although transmutations options exist at a type-level, they're represented as type-level tuples, whose familiar syntax is identical to value-level tuples. An empty tuple seems like the natural choice for encoding *don't neglect anything*.++We could not identify any advantages to representing options with const-generics. There is no clear syntactic advantage: tuples remain the most natural way to encode ad-hoc products of items. The comparative lack of default values for const-generic parameters poses an ergonomic *disadvantage*.+++## Rationale: Stability+### Distinguishing Stability from Possibility+[Prior art][mechanism-manual] which requires an author's manual implementation of conversion traits conflates stability with possibility; i.e., there may be types for which a transmutation is known to be valid for which the authors do not implement the required traits for safe transmutation. For such types, transmuters must fall all the way back to the *wildly* unsafe `mem::transmute`; there is no middle-ground where transmuters can retain all static guarantees *besides* stability. By distinguishing possibility from stability, our proposal provides this middle ground.++### Distinguishing Stability from `#[repr(C)]`+In our proposal, `#[repr(C)]` does not connote any promises of layout stability for SemVer purposes. It's [been suggested](https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/RFC.3A.20Stability.20Declaration.20Traits/near/204011238) that the presence of `#[repr(C)]` *already* connotes total layout stability; if so, explicit stability declaration traits are superfluous. However, we are unaware of any documentation indicating that `#[repr(C)]` carries this implication. (It's also [been suggested](https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165897) that `#[repr(C)]` should *not* connote stability, because that would pose a stability hazard. We agree with this assessment.)++### Permitting Granular Stability Declarations+The [stability declaration traits][stability] permit granular and incomplete promises of layout stability (e.g., guaranteeing the size and validity qualities of a type, but *not* its alignment. An alternative formulation of stability might be all-or-nothing (i.e., equivalent to only being able to write `Archetype = Self`). However, members of the safe-transmute working group have [expressed](https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/Transmutability.20Intrinsic/near/202712834) an interest in granular stability declarations.++Our proposed API supports complex, granular stability declarations, all-the-while retaining simplicity in simple use-cases (namely, one can simply the stability declaration traits). +++## Alternative: Implementing this RFC in a Crate++This RFC builds on ample [prior art][prior-art] in the crate ecosystem, but these efforts strain against the fundamental limitations of crates. Fundamentally, safe transmutation efforts use traits to expose layout information to the type system. The burden of ensuring safety [is usually either placed entirely on the end-user, or assumed by complex, incomplete proc-macro `derives`][mechanism-manual].++An exception to this rule is the [typic][crate-typic] crate, which complex, type-level programming to emulate a compiler-supported, "smart" `TransmuteFrom` trait (like the one proposed in this RFC). Nonetheless, [typic][crate-typic] is fundamentally limited: since Rust does not provide a type-level mechanism for reflecting over the structure of arbitrary types, even [typic][crate-typic] cannot judge the safety of a transmutation without special user-added annotations on type definitions. Although [typic][crate-typic] succeeds as a proof-of-concept, its maintainability is questionable, and the error messages it produces are [lovecraftian](https://en.wikipedia.org/wiki/Lovecraftian_horror).

Missing word: Perhaps, 'which utilizes complex, type-level programming'?

jswrenn

comment created time in 8 minutes

issue closedrust-lang/rust

ICE with the `@ ..` binding pattern

<!-- Thank you for finding an Internal Compiler Error! 🧊 If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples.

http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/

-->

Code

pub enum Operands {
	Zero,
	One(u8),
	Two(u8, u8),
}

pub fn main() {
	use Operands::*;

	let operands = Zero;

	match operands {
		Zero => println!("Nothing"),
		One(operand) => println!("{:x}", operand),
		Two(operands @ ..) => println!("({:x}, {:x})", operands.0, operands.1),
	};
}

Meta

<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. -->

The bug exists in the beta,

rustup run beta rustc --version --verbose

rustc 1.46.0-beta.1 (e51b714db 2020-07-15)
binary: rustc
commit-hash: e51b714db8ff82ac38ea7c6742d6f5480e2e77bd
commit-date: 2020-07-15
host: x86_64-unknown-linux-gnu
release: 1.46.0-beta.1
LLVM version: 10.0

nightly,

rustup run nightly rustc --version --verbose

rustc 1.46.0-nightly (346aec9b0 2020-07-11)
binary: rustc
commit-hash: 346aec9b02f3c74f3fce97fd6bda24709d220e49
commit-date: 2020-07-11
host: x86_64-unknown-linux-gnu
release: 1.46.0-nightly
LLVM version: 10.0

and stable build channels.

rustc --version --verbose:

rustc 1.45.0 (5c1f21c3b 2020-07-13)
binary: rustc
commit-hash: 5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2
commit-date: 2020-07-13
host: x86_64-unknown-linux-gnu
release: 1.45.0
LLVM version: 10.0

The error and the backtrace provided are produced by the stable build.

Error output

error: `operands @` is not allowed in a tuple struct
  --> ./a.rs:15:7
   |
15 |         Two(operands @ ..) => println!("({:x}, {:x})", operands.0, operands.1),
   |             ^^^^^^^^^^^^^ this is only allowed in slice patterns
   |
   = help: remove this and bind each tuple field independently
help: if you don't need to use the contents of operands, discard the tuple's remaining fields
   |
15 |         Two(..) => println!("({:x}, {:x})", operands.0, operands.1),
   |             ^^

error: internal compiler error: src/librustc_typeck/check/mod.rs:3023: no type for local variable unknown node (hir_id=HirId { owner: DefId(0:13 ~ a[317d]::main[0]), local_id: 9 })
  --> ./a.rs:15:50
   |
15 |         Two(operands @ ..) => println!("({:x}, {:x})", operands.0, operands.1),
   |                                                        ^^^^^^^^

thread 'rustc' panicked at 'Box<Any>', /rustc/5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2/src/libstd/macros.rs:13:23
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

<!-- Include a backtrace in the code block by setting RUST_BACKTRACE=1 in your environment. E.g. RUST_BACKTRACE=1 cargo build. --> <details><summary><strong>Backtrace</strong></summary> <p>

thread 'rustc' panicked at 'Box<Any>', /rustc/5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2/src/libstd/macros.rs:13:23
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:490
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::span_bug
  14: rustc_errors::Handler::span_bug
  15: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc_middle::ty::context::tls::with_opt::{{closure}}
  17: rustc_middle::ty::context::tls::with_opt
  18: rustc_middle::util::bug::opt_span_bug_fmt
  19: rustc_middle::util::bug::span_bug_fmt
  20: rustc_typeck::check::FnCtxt::local_ty::{{closure}}
  21: rustc_typeck::check::FnCtxt::local_ty
  22: rustc_typeck::check::FnCtxt::instantiate_value_path
  23: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  24: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  25: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  26: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  27: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  28: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  29: <smallvec::SmallVec<A> as core::iter::traits::collect::Extend<<A as smallvec::Array>::Item>>::extend
  30: <T as rustc_middle::ty::context::InternIteratorElement<T,R>>::intern_with
  31: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  32: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  33: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt>::check_match
  34: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  35: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  36: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  37: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  38: rustc_typeck::check::FnCtxt::check_argument_types
  39: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::confirm_builtin_call
  40: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::check_call
  41: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  42: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  43: rustc_typeck::check::FnCtxt::check_argument_types
  44: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::confirm_builtin_call
  45: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::check_call
  46: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  47: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  48: rustc_typeck::check::FnCtxt::check_stmt
  49: rustc_typeck::check::FnCtxt::check_block_with_expected
  50: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  51: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  52: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt>::check_match
  53: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  54: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  55: rustc_typeck::check::FnCtxt::check_stmt
  56: rustc_typeck::check::FnCtxt::check_block_with_expected
  57: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  58: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  59: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_return_expr
  60: rustc_typeck::check::check_fn
  61: rustc_middle::ty::context::GlobalCtxt::enter_local
  62: rustc_typeck::check::typeck_tables_of
  63: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::typeck_tables_of>::compute
  64: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  65: rustc_query_system::query::plumbing::get_query_impl
  66: rustc_query_system::query::plumbing::ensure_query_impl
  67: rustc_typeck::check::typeck_item_bodies
  68: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::typeck_item_bodies>::compute
  69: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  70: rustc_query_system::query::plumbing::get_query_impl
  71: rustc_typeck::check_crate
  72: rustc_interface::passes::analysis
  73: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::analysis>::compute
  74: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  75: rustc_query_system::query::plumbing::get_query_impl
  76: rustc_middle::ty::context::tls::enter_global
  77: rustc_interface::interface::run_compiler_in_existing_thread_pool
  78: rustc_ast::attr::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

</p> </details>

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START --> This issue has been assigned to @jakubadamw via this comment. <!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"jakubadamw"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END --> <!-- TRIAGEBOT_END -->

closed time in 10 minutes

r1fl

issue commentrust-lang/rust

ICE with the `@ ..` binding pattern

We don't backport the fix in favor of this comment: https://github.com/rust-lang/rust/pull/74557#issuecomment-668660597 So I'm just going to close this as fixed.

r1fl

comment created time in 10 minutes

pull request commentrust-lang/rust

Completes support for coverage in external crates

Random infra failure? Otherwise, I don't see any relevant error messages.

richkadel

comment created time in 12 minutes

push eventrust-lang/crates.io-index

bors

commit sha cc997c9254e05c18df444aea3c2b39ed0f6fb799

Updating crate `mlc#0.13.4`

view details

push time in 12 minutes

push eventrust-lang/crates.io-index

bors

commit sha ff345c1daf572878b1ab0605be77e17a87bf8dc6

Updating crate `bitcoin-spv#4.0.1`

view details

push time in 12 minutes

issue closedrust-lang/rust

Pattern matching regression 1.45.0 -> 1.45.1 (+nightly)

<!-- Thank you for filing a bug report! 🐛 Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. -->

I tried this code:

fn main() {
    if let Some([b'@', filename @ ..]) = Some(b"@abc123") {
        println!("filename {:?}", filename);
    }
}

I expected this to compile and print

filename [97, 98, 99, 49, 50, 51]

which it does with 1.45.0

Instead, it failed to compile on both 1.45.1 and nightly:

error[E0425]: cannot find value `filename` in this scope
 --> src/main.rs:3:35
  |
3 |         println!("filename {:?}", filename);
  |                                   ^^^^^^^^ not found in this scope

error: aborting due to previous error

Playground link

Meta

<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. -->

rustc --version --verbose:

rustc 1.45.1 (c367798cf 2020-07-26)
binary: rustc
commit-hash: c367798cfd3817ca6ae908ce675d1d99242af148
commit-date: 2020-07-26
host: x86_64-unknown-linux-gnu
release: 1.45.1
LLVM version: 10.0

</p> </details>

closed time in 13 minutes

jsgf

issue commentrust-lang/rust

Pattern matching regression 1.45.0 -> 1.45.1 (+nightly)

So, the failure has been "fixed" in the both versions, I'm going to close this. If I have missed something, please re-open it :)

jsgf

comment created time in 13 minutes

startedrust-lang/rustlings

started time in 16 minutes

PR opened rust-lang/regex

typo: enabld -> enabled
+1 -1

0 comment

1 changed file

pr created time in 16 minutes

fork aviau/regex

An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs.

https://docs.rs/regex

fork in 16 minutes

pull request commentrust-lang/rust

Replace `Memoryblock` with `NonNull<[u8]>`

The job i686-gnu of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

<details><summary><i>Click to expand the log.</i></summary>


</details><p></p>

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @rust-lang/infra. (Feature Requests)

TimDiekmann

comment created time in 17 minutes

pull request commentrust-lang/rust

Upgrade to LLVM 11 (rc1)

Yeah, seems to work fine locally with GCC 10.

cuviper

comment created time in 19 minutes

startedrust-lang/project-safe-transmute

started time in 19 minutes

pull request commentrust-lang/rust

Forbid non-derefable types explicitly in unsizing casts

Beta-nominating with this reason: https://github.com/rust-lang/rust/pull/75136#issuecomment-668774651

JohnTitor

comment created time in 20 minutes

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*

@rylev https://github.com/rust-lang/project-safe-transmute/pull/5/commits/a5122b2cd80d86b4c7cd7b552519fa5fe8ebb8a1 adds additional explanatory comments to this example, including one that calls attention to TransmuteInto

I'm going to mark this as resolved, but feel free to un-resolve if need be.

jswrenn

comment created time in 21 minutes

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

:hourglass: Testing commit 18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f with merge c70a4d6c76d010b569fa4d16b2ffb7eced04bc52... <!-- homu: {"type":"BuildStarted","head_sha":"18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f","merge_sha":"c70a4d6c76d010b569fa4d16b2ffb7eced04bc52"} -->

eggyal

comment created time in 21 minutes

issue openedrust-lang/futures-rs

select!{} documentation has truncated paragraph

The second paragraph of the select!{} docs reads,

If an expression which yields a Future is passed to select! (e.g. an async fn call) instead of a Future by name the Unpin requirement is relaxed, since the macro will pin the resulting Future on the stack. However the Future returned by the expression must still implement FusedFuture. This difference is presented

(emphasis mine)

It is not clear how the difference is presented. It seems that this paragraph has been accidentally truncated.

created time in 21 minutes

pull request commentrust-lang/rust

Replace `Memoryblock` with `NonNull<[u8]>`

:broken_heart: Test failed - checks-actions <!-- homu: {"type":"BuildFailed","builder_url":"https://github.com/rust-lang-ci/rust/runs/946842420","builder_name":"checks-actions"} -->

TimDiekmann

comment created time in 21 minutes

pull request commentrust-lang/rust

forbid `#[track_caller]` on main

The job i686-gnu-nopt of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

<details><summary><i>Click to expand the log.</i></summary>


</details><p></p>

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @rust-lang/infra. (Feature Requests)

lcnr

comment created time in 24 minutes

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`

Attempt to improve https://github.com/rust-lang/project-safe-transmute/pull/5#discussion_r464500451

use core::transmute::{
    TransmuteInto,
    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},
};

#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)] // declare `Foo` to be *stably* transmutable
#[repr(C)]
pub struct Foo(pub u8, pub u16);
//                    ^ there's a padding byte here, between these fields

// Transmute fearlessly!
let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!
//                  ^^^^^^^^^^^^^^ provided by the `TransmuteInto` trait

let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!

// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied
//   --> src/demo.rs:15:27
//    |
// 15 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!
//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`
//    |
//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`
jswrenn

comment created time in 24 minutes

startedrust-lang/rustlings

started time in 25 minutes

PR opened rust-lang/docs.rs

Cleanup from LOL HTML rewrite
  • Add missing index.js
  • Add missing CSS files
  • Add Cargo.lock

r? @Kixiron

I don't know how Cargo.lock slipped though, that seems like a regression from #883.

+179 -0

0 comment

3 changed files

pr created time in 27 minutes

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

@bors retry

eggyal

comment created time in 27 minutes

pull request commentrust-lang/rust

Replace `Memoryblock` with `NonNull<[u8]>`

:hourglass: Testing commit 93d98328d161bcdf002f9d2f7f916f01c6fce3b1 with merge 8d188d8fa7066ffe69511440d73ea6099eaefaf4... <!-- homu: {"type":"BuildStarted","head_sha":"93d98328d161bcdf002f9d2f7f916f01c6fce3b1","merge_sha":"8d188d8fa7066ffe69511440d73ea6099eaefaf4"} -->

TimDiekmann

comment created time in 27 minutes

pull request commentrust-lang/rust

forbid `#[track_caller]` on main

:broken_heart: Test failed - checks-actions <!-- homu: {"type":"BuildFailed","builder_url":"https://github.com/rust-lang-ci/rust/runs/946827023","builder_name":"checks-actions"} -->

lcnr

comment created time in 27 minutes

pull request commentrust-lang/rust

Completes support for coverage in external crates

The job i686-gnu of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

<details><summary><i>Click to expand the log.</i></summary>


</details><p></p>

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @rust-lang/infra. (Feature Requests)

richkadel

comment created time in 29 minutes

startedrust-lang/rfcs

started time in 29 minutes

startedrust-lang/blog.rust-lang.org

started time in 29 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+use crate::utils::span_lint_and_help;+use if_chain::if_chain;+use rustc_ast::ast::{Param, TyKind};+use rustc_lint::{EarlyContext, EarlyLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly+    /// specify the `Self`-type explicitly+    /// **Why is this bad?** Increases the amount and decreases the readability of code+    ///+    /// **Known problems:** None+    ///+    /// **Example:**+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self: Self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    ///+    /// Could be rewritten as+    ///+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    pub NEEDLESS_FN_SELF_TYPE,+    style,+    "type of `self` parameter is already by default `Self`"+}++declare_lint_pass!(NeedlessFnSelfType => [NEEDLESS_FN_SELF_TYPE]);++impl EarlyLintPass for NeedlessFnSelfType {+    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {+        if_chain! {+            if p.is_self();+            if let TyKind::Path(None, path) = &p.ty.kind;+            if let Some(segment) = path.segments.first();

We should check also that there's only 1 path segment.

wiomoc

comment created time in 32 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+#![warn(clippy::style, clippy::needless_fn_self_type)]

clippy::style is not necessary here

wiomoc

comment created time in 32 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+#![warn(clippy::style, clippy::needless_fn_self_type)]++pub enum ValType {+    I32,+    I64,+    F32,+    F64,+}++impl ValType {

we should include a test for mut self: Self

wiomoc

comment created time in 33 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+use crate::utils::span_lint_and_help;+use if_chain::if_chain;+use rustc_ast::ast::{Param, TyKind};+use rustc_lint::{EarlyContext, EarlyLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly+    /// specify the `Self`-type explicitly+    /// **Why is this bad?** Increases the amount and decreases the readability of code+    ///+    /// **Known problems:** None+    ///+    /// **Example:**+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self: Self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    ///+    /// Could be rewritten as+    ///+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    pub NEEDLESS_FN_SELF_TYPE,+    style,

category should be complexity

wiomoc

comment created time in 41 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+use crate::utils::span_lint_and_help;+use if_chain::if_chain;+use rustc_ast::ast::{Param, TyKind};+use rustc_lint::{EarlyContext, EarlyLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly+    /// specify the `Self`-type explicitly+    /// **Why is this bad?** Increases the amount and decreases the readability of code+    ///+    /// **Known problems:** None+    ///+    /// **Example:**+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self: Self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    ///+    /// Could be rewritten as+    ///+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    pub NEEDLESS_FN_SELF_TYPE,+    style,+    "type of `self` parameter is already by default `Self`"+}++declare_lint_pass!(NeedlessFnSelfType => [NEEDLESS_FN_SELF_TYPE]);++impl EarlyLintPass for NeedlessFnSelfType {+    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {+        if_chain! {+            if p.is_self();+            if let TyKind::Path(None, path) = &p.ty.kind;+            if let Some(segment) = path.segments.first();+            if segment.ident.as_str() == sym!(Self).as_str();+            then {+                span_lint_and_help(

It would be nice to provide an auto-applicable suggestion that removed the explicit type.

wiomoc

comment created time in 34 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+use crate::utils::span_lint_and_help;+use if_chain::if_chain;+use rustc_ast::ast::{Param, TyKind};+use rustc_lint::{EarlyContext, EarlyLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly+    /// specify the `Self`-type explicitly+    /// **Why is this bad?** Increases the amount and decreases the readability of code+    ///+    /// **Known problems:** None+    ///+    /// **Example:**+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self: Self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    ///+    /// Could be rewritten as+    ///+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    pub NEEDLESS_FN_SELF_TYPE,+    style,+    "type of `self` parameter is already by default `Self`"+}++declare_lint_pass!(NeedlessFnSelfType => [NEEDLESS_FN_SELF_TYPE]);++impl EarlyLintPass for NeedlessFnSelfType {+    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {+        if_chain! {+            if p.is_self();+            if let TyKind::Path(None, path) = &p.ty.kind;+            if let Some(segment) = path.segments.first();+            if segment.ident.as_str() == sym!(Self).as_str();

We should also lint self: &Self and self: &mut Self by suggesting &self and &mut self respectively.

wiomoc

comment created time in 38 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+use crate::utils::span_lint_and_help;+use if_chain::if_chain;+use rustc_ast::ast::{Param, TyKind};+use rustc_lint::{EarlyContext, EarlyLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly+    /// specify the `Self`-type explicitly
    /// **What it does:** The lint checks for `self` in fn parameters that
    /// specify the `Self`-type explicitly
wiomoc

comment created time in 43 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

+use crate::utils::span_lint_and_help;+use if_chain::if_chain;+use rustc_ast::ast::{Param, TyKind};+use rustc_lint::{EarlyContext, EarlyLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly+    /// specify the `Self`-type explicitly+    /// **Why is this bad?** Increases the amount and decreases the readability of code+    ///+    /// **Known problems:** None+    ///+    /// **Example:**+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self: Self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    ///+    /// Could be rewritten as+    ///+    /// ```rust+    /// enum ValType {+    ///     I32,+    ///     I64,+    ///     F32,+    ///     F64,+    /// }+    ///+    /// impl ValType {+    ///     pub fn bytes(self) -> usize {+    ///         match self {+    ///             Self::I32 | Self::F32 => 4,+    ///             Self::I64 | Self::F64 => 8,+    ///         }+    ///     }+    /// }+    /// ```+    pub NEEDLESS_FN_SELF_TYPE,+    style,+    "type of `self` parameter is already by default `Self`"+}++declare_lint_pass!(NeedlessFnSelfType => [NEEDLESS_FN_SELF_TYPE]);++impl EarlyLintPass for NeedlessFnSelfType {+    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {+        if_chain! {+            if p.is_self();+            if let TyKind::Path(None, path) = &p.ty.kind;+            if let Some(segment) = path.segments.first();+            if segment.ident.as_str() == sym!(Self).as_str();

Could be simplified to:

            if segment.ident.name == kw::SelfUpper;

It will need this import:

use rustc_span::symbol::kw;
wiomoc

comment created time in 40 minutes

Pull request review commentrust-lang/rust-clippy

New lint against `Self` as an arbitrary self type

 Released 2018-09-13 [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect [`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue [`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main+[`needless_fn_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_fn_self_type

I would suggest needless_arbitrary_self_type as that's how the feature was named.

wiomoc

comment created time in 44 minutes

push eventrust-lang/crates.io-index

bors

commit sha 60a0755351b807f3bdb97d5610c09a6020fa50aa

Updating crate `check-if-email-exists#0.8.13`

view details

push time in 32 minutes

startedrust-lang/rustlings

started time in 32 minutes

pull request commentrust-lang/rust

forbid `#[track_caller]` on main

:hourglass: Testing commit 9127e27cec22cb130d0a96094196995d72b19030 with merge 30e5c68e6961f49f14deb5e53d3d3a5d8e500842... <!-- homu: {"type":"BuildStarted","head_sha":"9127e27cec22cb130d0a96094196995d72b19030","merge_sha":"30e5c68e6961f49f14deb5e53d3d3a5d8e500842"} -->

lcnr

comment created time in 33 minutes

push eventrust-lang/crates.io-index

bors

commit sha b70f42f44dd17443a5abff14211ca71358705504

Updating crate `imgthin#0.1.1`

view details

push time in 33 minutes

pull request commentrust-lang/rust

Completes support for coverage in external crates

:broken_heart: Test failed - checks-actions <!-- homu: {"type":"BuildFailed","builder_url":"https://github.com/rust-lang-ci/rust/runs/946810107","builder_name":"checks-actions"} -->

richkadel

comment created time in 33 minutes

issue commentrust-lang/rust

ICE: eval_const_to_op: Unexpected ConstKind

So we probably fail here because we call const_eval_resolve with a ConstKind::Infer which get's canonicalized to a ConstKind::Bound.

All of that seems correct to me :thinking: Is it possible that we should treat ConstKind::Bound similar to ConstKind::Param and "just" return TooGeneric here?

steffahn

comment created time in 34 minutes

startedrust-lang/rust

started time in 35 minutes

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

The job i686-gnu of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

<details><summary><i>Click to expand the log.</i></summary>


</details><p></p>

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @rust-lang/infra. (Feature Requests)

eggyal

comment created time in 35 minutes

startedrust-lang/rustlings

started time in 36 minutes

pull request commentrust-lang/rust

Refractor ty.kind -> ty.kind()

I do feel like that's appropriate, I can file one

LeSeulArtichaut

comment created time in 37 minutes

pull request commentrust-lang/rust

Refractor ty.kind -> ty.kind()

Thanks @LeSeulArtichaut ! For some reason, I thought we had an MCP for this change, but I guess we don't.

LeSeulArtichaut

comment created time in 37 minutes

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

spurious network error

eggyal

comment created time in 37 minutes

push eventrust-lang/crates.io-index

bors

commit sha 1e2af0df26cd993752362fc34c47337154b7919a

Updating crate `bitcoin-spv#4.0.0`

view details

push time in 37 minutes

pull request commentrust-lang/rust

Completes support for coverage in external crates

:hourglass: Testing commit e0dc8dec273b4cba44a91c1b4433e3dcd117919f with merge 118a0185f14f7936c3edb16044cf2b903dce4963... <!-- homu: {"type":"BuildStarted","head_sha":"e0dc8dec273b4cba44a91c1b4433e3dcd117919f","merge_sha":"118a0185f14f7936c3edb16044cf2b903dce4963"} -->

richkadel

comment created time in 38 minutes

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

:broken_heart: Test failed - checks-actions <!-- homu: {"type":"BuildFailed","builder_url":"https://github.com/rust-lang-ci/rust/runs/946796061","builder_name":"checks-actions"} -->

eggyal

comment created time in 38 minutes

pull request commentrust-lang/rust

Add `#[cfg(panic = '...')]`

I guess a reasonable question then is whether we can address known use cases another way and/or how much we care about that.

Another question:

One could imagine exposing the "panic strategy" as something that can be dynamically tested (perhaps with a #[non_exhaustive] enum), which might allow us to (e.g.) have compile-test skip tests or do something intelligent for when running with panic=abort (e.g., spawn a new process for tests, or at least for #[should_panic] tests).

davidhewitt

comment created time in 41 minutes

Pull request review commentrust-lang/docs.rs

Split up the about page

+{% extends "base.html" %}+{% block header %}+<div class="cratesfyi-package-container">+<div class="container about">+	<h3 id="crate-title">Docs.rs documentation</h3>+	<div class="pure-menu pure-menu-horizontal">+	<ul class="pure-menu-list">+		{{ macros::active_link(expected="index", href="/about", text="About") }}+		{{ macros::active_link(expected="badges", href="/about/badges", text="Badges") }}+		{{ macros::active_link(expected="builds", href="/about/builds", text="Builds") }}+		{{ macros::active_link(expected="metadata", href="/about/metadata", text="Metadata") }}+		{{ macros::active_link(expected="redirections", href="/about/redirections", text="Redirections") }}+	</ul>+	</div>+</div>+</div>+{% endblock %}

To be honest I still like the indentation more. It does make the lines longer but I think that's a fine price to pay for what's in my opinion better readability and clearer intent

jyn514

comment created time in 41 minutes

push eventrust-lang/crates.io-index

bors

commit sha deb2ba71777ae9a0d4de457d124e02a67ef68081

Updating crate `zdump#1.2.1`

view details

push time in 41 minutes

pull request commentrust-lang/rust

Upgrade to LLVM 11 (rc1)

:hourglass: Trying commit 632ce974857d7f93c0b658282a9ba9d3da1d06bc with merge d76f848d4c1ae4a85aa13749907856758b9ae769... <!-- homu: {"type":"TryBuildStarted","head_sha":"632ce974857d7f93c0b658282a9ba9d3da1d06bc","merge_sha":"d76f848d4c1ae4a85aa13749907856758b9ae769"} -->

cuviper

comment created time in 42 minutes

pull request commentrust-lang/rust

Upgrade to LLVM 11 (rc1)

OK, let's see how that goes...

@bors try

cuviper

comment created time in 42 minutes

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T> {+        data: *const T,+        len: usize,+        lifetime: core::marker::PhantomData<&'a ()>,+    }++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+                lifetime: core::marker::PhantomData,+            }+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```++The above code is "safe" because our simplified definition of constructability fails to recognize this pattern of encapsulation, and because `NeglectStability` is a `SafeTransmutationOption`.++The intent of `NeglectStability` is to permit the safe transmutation of types that predate the stabilization of the stability declaration traits. It also provides a convenient escape-hatch for type authors to neglect the stability of transmutations of their *own* types, without sacrificing safety. `NeglectStability` is a `SafeTransmutationOption` because, in principle, neglecting stability does not diminish safety. Our simplified definition of constructability violates this principle.++By temporarily sacrificing these goals, we may preserve safety solely...++##### ...at the Cost of `NeglectStability`+We may preserve safety by demoting `NeglectStability` to `UnsafeTransmutationOption`-status.++In doing so, a third-party is forced to resort to an `unsafe` transmutation to construct `NonEmptySlice`; e.g.:++```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,+{+    // unsafe because we `NeglectStability`+    unsafe { src.unsafe_transmute_into() }+}+```++Demoting `NeglectStability` to unsafe-status does not stop type authors from opting-in to stable (and thus safe) transmutations; e.g., with `derive(PromiseTransmutableFrom)`:+```rust+pub mod crate_a {++    #[derive(PromiseTransmutableFrom)]+    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[derive(PromiseTransmutableFrom)]+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+In the above example, the type author declares `NonEmptySlice` and `NonEmptySliceInner` to be stably instantiatable via transmutation. Given this, a third-party no longer needs to resort to `unsafe` code to violate the the invariants on `inner`:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```+This safety hazard is not materially different from the one that would be induced if the type author implemented `DerefMut<Target=NonEmptySliceInner>` for `NonEmptySlice`, or made the `private` module `pub`, or otherwise explicitly provided outsiders with unrestricted mutable access to `data`.++##### Recommendation+We recommend that that implementers of this RFC initially simplify constructability by:+ - adopting our simplified definition of constructability+ - demoting `NeglectStability` to unsafe status (i.e., not implementing `SafeTransmuteOptions` for `NeglectStability`; *only* `UnsafeTransmuteOptions`)++If and when the implementation of `TransmuteFrom` encodes our complete definition of constructability, `NeglectStability` shall become a safe transmute option.+++## Dissecting Stability++In this section, we iteratively review the design of the stability declaration traits, starting with a simplest-possible design:+```rust+pub unsafe trait PromiseTransmutableFrom+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+{+    type Archetype;+}+```++### Part 1: Towards Safety++#### Forbidding Archetypes with Nonsense Validity+The simplest definitions of the stability declaration traits *must* be `unsafe` because `Archetype` can be instantiated in ways that undermine soundness; e.g.:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16; // <- Nonsense!+}++unsafe impl PromiseTransmutableFrom for u16 {+    type Archetype = u16;+}+```+These declarations subvert safety! Given these declarations, Rust will accept `u8: TransmuteInto<u16>`. This is problematic: `u8` is smaller than `u16`.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+u8:+    TransmuteInto<&'a Aligned8>+```++First, recall that a `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable into `<Dst as PromiseTransmutableFrom>::Archetype`, notwithstanding stability. The layouts of `Src` and `Dst` themselves are, in theory, immaterial — all that matters are the layouts of their stability archetypes. Formally:+```rust+𝙞𝙛+    <Src as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <Dst as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    Src: TransmuteInto<Dst>+```++We apply this rule to our initial equation:+```rust+𝙞𝙛+    <u8 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <u16 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    u8: TransmuteInto<u16>+```++Next, recall the definitions of `PromiseTransmutableInto` for `u8` and `PromiseTransmutableFrom` for `u16`:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16; // <- Nonsense!+}++unsafe impl PromiseTransmutableFrom for u16 {+    type Archetype = u16;+}+```+We apply these definitions to evaluate `<u8 as PromiseTransmutableInto>::Archetype` and `<u16 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    u16:+        TransmuteInto<+            u16,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    u8: TransmuteInto<u16>+```+Since `u16` can be safely transmuted into `u16`, the compiler accepts the transmutation of `u8` into `u16`!++</details>++---++We can prevent  nonsense archetypes by demanding that `Archetype` is transmutable into `Self` (notwithstanding stability):+```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+{+    type Archetype;+}+```++Our previous attempt to skirt soundness now produces a compile error:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16;+                  // ^^^ the trait `TransmuteInto<u8, _>` is not implemented for `u16`+}+```++#### Forbidding Archetypes with Nonsense Alignment+Unfortunately, the above definition is still flawed. Consider these stability declarations:++```rust+#[derive(PromiseTransmutableFrom)]+#[repr(C)]+pub struct Aligned1;++#[derive(PromiseTransmutableInto)]+#[repr(C, align(8))]+pub struct Aligned8;++unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```++These declarations subvert safety! Given these declarations, Rust would accept the bound `&Aligned1: TransmuteInto<&Aligned8>`. This is problematic: `Aligned8` has *stricter* alignment requirements than `Aligned1`.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+for<'a> &'a Aligned1:+        TransmuteInto<&'a Aligned8>+```++As before, we first apply the stability rule to our equation:+```rust+𝙞𝙛+    <&'a Aligned1 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <&'a Aligned8 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```++Next, recall the definitions of `PromiseTransmutableInto` and `PromiseTransmutableFrom` for `&T`:+```rust+unsafe impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a T::Archetype;+}++unsafe impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+We apply these definitions to evaluate `<&_ as PromiseTransmutableInto>::Archetype` and `<&_ as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    &'a <Aligned1 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            &'a <Aligned8 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```++Finally, recall the definitions of `PromiseTransmutableInto` for `Aligned1` and `PromiseTransmutableFrom` for `Aligned8`:+```rust+unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```+We apply these definitions to evaluate `<Aligned1 as PromiseTransmutableInto>::Archetype` and `<Aligned8 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    &'a Aligned8:+        TransmuteInto<+            &'a Aligned1,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```+Since `&'a Aligned8` can be safely transmuted into `&'a Aligned1`, the compiler accepts the transmutation of `&'a Aligned1` into `&'a Aligned1`!++</details>++---++This safety hazard can be prevented by rewriting our `where` bound like so: +```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>+{+    type Archetype;+}+```++Our previous attempt to skirt safety now produces a compiler error:+```rust+unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+                  // ^^^^^^^^ the trait `TransmuteFrom<&'_ Aligned1, NeglectStability>` is not implemented for `&'_ Aligned8`+}+```+++#### Forbidding Archetypes with Nonsense Validity Under Mutate-able Reference Transmutation+Unfortunately, the above definition is still flawed. Consider these stability declarations:+```rust+#[repr(u8)]+enum Boolean {+    False = 0,+    True = 1,+}++unsafe impl PromiseTransmutableInto for Boolean {+    type Type = u8;+}+```++Given these declarations, Rust would accept the bound `&mut Boolean: TransmuteInto<&mut u8>`. This is problematic: transmutations involving mutate-able references must not expand bit-validity.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Why would this transmutation be accepted? Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+for<'a> &'a mut Boolean:+        TransmuteInto<&'a mut u8>+```++As before, we first apply the stability rule to our equation:+```rust+𝙞𝙛+    for<'a> <&'a mut Boolean as PromiseTransmutableInto>::Archetype:+            TransmuteInto<+                <&'a mut u8 as PromiseTransmutableFrom>::Archetype,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```++Next, recall the definitions of `PromiseTransmutableInto` and `PromiseTransmutableFrom` for `&mut T`:+```rust+unsafe impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a T::Archetype;+}++unsafe impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+We apply these definitions to evaluate `<& mut _ as PromiseTransmutableInto>::Archetype` and `<& mut _ as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    for<'a> &'a mut <Boolean as PromiseTransmutableInto>::Archetype:+            TransmuteInto<+                &'a mut <u8 as PromiseTransmutableFrom>::Archetype,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```++Finally, recall the definitions of `PromiseTransmutableInto` for `Boolean` and `PromiseTransmutableFrom` for `u8`:+```rust+unsafe impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+}++unsafe impl PromiseTransmutableFrom for u8 {+    type Archetype = Self;+}+```+We apply these definitions to evaluate `<Boolean as PromiseTransmutableInto>::Archetype` and `<u8 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    for<'a> &'a mut u8:+            TransmuteInto<+                &'a mut u8,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```+Since `&'a mut u8` can be safely transmuted into `&'a mut u8`, the compiler accepts the transmutation of `&mut Boolean` into `&mut u8`.++</details>++---++This safety hazard can be prevented by rewriting our `where` bounds like so: +```rust+pub trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>,+    for<'a> &'a mut Self::Archetype: TransmuteInto<&'a mut Self, NeglectStability>+{+    type Archetype;+}++pub trait PromiseTransmutableInto+where+    Self::Archetype: TransmutFrom<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>,+    for<'a> &'a mut Self::Archetype: TransmuteFrom<&'a mut Self, NeglectStability>+{+    type Archetype;+}+```++Our previous attempt to skirt safety now produces a compiler error:+```rust+impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+                  // ^^ the trait `TransmuteFrom<&'_ mut u8, NeglectStability>` is not implemented for `&'_ mut Boolean`+}+```++### Part 2: Towards Flexibility+In the previous two sections, we bypassed the safety effects of the `PromiseTransmutable{From,Into}` traits' `where` bounds by defining archetypes whose quirks were only apparent under a *more* restrictive transmutation than that enforced by the `where` bound.++We cannot play the same trick to bypass safety with our latest `where` bound. Between transmutations involving values, shared references and unique references, the rules governing transmutations involving unique references are the most restrictive.++However, this safety comes at the expense of flexibility. Recall our last 'dangerous' archetype:+```rust+impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+                  // ^^ the trait `TransmuteFrom<&'_ mut u8, NeglectStability>` is not implemented for `&'_ mut Boolean`+}+```+This archetype is sensible in the context of value transmutations. It's sensible in the context of immutable reference transmutations. The *only* context in which it is *not* sensible are mutate-able reference transmutations! Our changes achieved safety at the significant expense of flexibility.++In this section, we begin at our previous value-safe definition of the stability declaration traits:+```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+{+    type Archetype;+}+```+...and solve its reference-unsafety in a manner that preserves flexibility.++#### Compartmentalizing Shared Reference Transmutation Stability+Reconsider these stability declarations:+```rust+#[derive(PromiseTransmutableFrom)]+#[repr(C)]+pub struct Aligned1;++#[derive(PromiseTransmutableInto)]+#[repr(C, align(8))]+pub struct Aligned8;++unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```++Given these declarations, Rust would accept the bound `&Aligned1: TransmuteInto<&Aligned8>`. This is problematic: `Aligned8` has *stricter* alignment requirements than `Aligned1`.++In our derivation of why the compiler accepted this transmutation, we referred to the stability declarations of `&T`:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom,+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+Rather than change the `where` bound of the *definitions* of `PromiseTransmutableFrom` and `PromiseTransmutableInto`, we can simply change the `where` bound of those two *implementations* of the traits:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}+```++#### Compartmentalizing Unique Reference Transmutation Stability+Likewise, for unique references, we go from this:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a mut T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a mut T::Archetype;+}+```+...to this:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom,+    for<'a> &'a mut Self::Archetype: TransmuteInto<&'a mut Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto,+    for<'a> &'a mut Self::Archetype: TransmuteFrom<&'a mut Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}+```++### Part 3: Towards Sensibility++In the previous two parts, we developed safe-and-flexible stability declaration traits. While we cannot make unsafe archetype choices, we can still make *silly* archetype choices. For instance, we can declare the stability of our types in terms of types that are *not* stable:++```rust+#[repr(u8)]+pub struct Foo { ... }++#[repr(u8)]+pub struct Bar { ... }++impl PromiseTransmutableInto for Foo {+    type Archetype = Bar;+}+```++We can prevent these sorts of silly archetypes by requiring that `Archetype` itself is stable, and that its stability archetype is not transitively defined:++```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++# Drawbacks+[drawbacks]: #drawbacks++## No Notion of Platform Stability+The stability declaration traits communicate library layout stability, but not *platform* layout stability. A transmutation is platform-stable if it compiling one one platform implies it will compile on all other platforms. Unfortunately, platform-unstable types are common;  e.g.:++- All pointer-related primitive types (`usize`, `isize`, `*const T`, `*mut T`, `&T`, `&mut T`) possess platform-dependent layouts; their sizes and alignments are well-defined, but vary between platforms. Concretely, whether `usize` is `TransmuteInto<[u8; 4]>` or `TransmuteInto<[u8; 8]>` will depend on  the platform.+- The very existence of some types depends on platform, too; e.g., the contents of [`core::arch`](https://doc.rust-lang.org/stable/core/arch/), [`std::os`](https://doc.rust-lang.org/stable/std/os/), and [`core::sync::atomic`](https://doc.rust-lang.org/stable/std/sync/atomic/) all depend on platform.++Expanding this RFC to address such types would introduce considerable additional complexity:+<ol>+<li>++**Cognitive Complexity:** For types whose layout varies between platforms, the [stability] declaration traits could, *perhaps*, be adapted to encode platform-related guarantees. We anticipate this would contribute substantial cognitive complexity. Type authors, even those with no interest in cross-platform stability, would nonetheless need to reason about the layout properties of their types on platforms that might not yet exist.+</li>+<li>++**Ergonomic Complexity:** Platform instabilities are contagious: a type that *contains* a platform-unstable type is, itself, platform-unstable. Due to the sheer virulence of types with platform-dependent layouts, an explicit '`NeglectPlatformStability`' option would need to be used for *many* simple transmutations. The ergonomic cost of this would also be substantial.++</li>+<li>++**Implementation Complexity:** The mechanisms proposed by this RFC are, fundamentally, applications of and additions to Rust's type system (i.e., they're traits). Mechanisms that impact platform stability, namely `#[cfg(...)]` annotations, long precede type-resolution and layout computation in the compilation process. For instance, it's possible to define types with impossible layouts:    +```rust+#[cfg(any())]+struct Recursive(Recursive);+```+This program compiles successfully on all platforms because, from the perspective of later compilation stages, `Recursive` may as well not exist.++</li>+</ol>++The issues of platform layout stability exposed by this RFC are not fundamentally different from the challenges of platform API stability. These challenges are already competently addressed by the mechanisms proposed in [RFC1868](https://github.com/rust-lang/rfcs/pull/1868). For this reason, and for the aforementioned concerns of additional complexity, we argue that communicating and enforcing platform layout stability must remain outside the scope of this RFC.++## Stability of *Unsafe* Transmutations+[drawback-unsafe-stability]: #Stability-of-Unsafe-Transmutations++The model of stability proposed by this RFC frames stability as a quality of *safe* transmutations. A type author cannot specify stability archetypes for *unsafe* transmutations, and it is reasonable to want to do so.++To accomodate this, we may modify the definitions of `PromiseTransmutableFrom` and `PromiseTransmutableInto` to consume an optional `Neglect` parameter, to allow for stability declarations for unsafe transmutations:+```rust+pub trait PromiseTransmutableFrom<Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions+{+    type Archetype+        : TransmuteInto<Self, Sum<Neglect, NeglectStability>>+        + PromiseTransmutableInto<Sum<Neglect, NeglectStability>>;+}++pub trait PromiseTransmutableInto<Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions+{+    type Archetype+        : TransmuteFrom<Self, Sum<Neglect, NeglectStability>>+        + PromiseTransmutableInto<Sum<Neglect, NeglectStability>>;+}+```+Implementations of these traits for a given `Neglect` declares that a transmutation which is accepted while neglecting a particular set of checks (namely the set encoded by `Neglect`) will *continue* to be possible.++We omit these definition from this RFC's recommendations because they are not completely satisfying. For instance, `Neglect` is a *logically* unordered set of options, but is encoded as a tuple (which *is* ordered). To declare a transmutation that requires neglecting validity and alignment checks as stable, only *one* of these impls ought to be necessary:++```rust+impl PromiseTransmutableFrom<(NeglectAlignment, NeglectValidity)> for Foo+{+    ...+}++impl PromiseTransmutableFrom<(NeglectValidity, NeglectAlignment)> for Foo+{+    ...+}+```+Writing *both* impls (as we do above) is logically nonsense, but is nonetheless supported by Rust's coherence rules.+++# Rationale and alternatives+[rationale-and-alternatives]: #rationale-and-alternatives++## Case Studies++### Case Study: Making Unsafe Rust Safer+[case-study-safer-unsafe]: #Case-Study-Making-Unsafe-Rust-Safer++This RFC proposes mechanisms for safe transmutation and safer *unsafe* transmutation. How might [Kelley's motivating example][motivation-safer-unsafe] change in light of these mechanisms?++#### Safer Unsafe+For the compiler to accept a use of `unsafe_transmute`, we must:+   - use `unsafe_transmute` with the `NeglectAlignment` option+   - annotate `Foo` with `#[repr(C)]` so its layout is defined+   - annotate `Foo` with `#[derive(PromiseTransmutableFrom,PromiseTransmutableInto)]` to indicate its layout is library-stable (alternatively, we could also use the  `NeglectStability` option)++The sum of these changes:+```rust+use core::transmute::{+    unsafe_transmute,+    options::NeglectAlignment,+    stability::FixedLayout,+};+++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    let mut array: [u8; 1024] = [1; 1024];++    let mut foo = unsafe {+        // check alignment ourselves+        assert_eq!((src as *const u8 as usize) % align_of::<Foo>(), 0);++        // transmute `&mut array` to `&mut Foo`+        // permitted becasue we promise to check the alignment ourselves+        let foo = unsafe_transmute::<&mut [u8; 1024], &mut Foo, NeglectAlignment>(&mut array);+    };++    foo.a += 1;+}+```++#### No Unsafe Needed!+Better yet, we may use a completely *safe* transmute if we statically align the byte array:++```rust+use core::transmute::{+    TransmuteInto,+    options::NeglectAlignment,+    stability::FixedLayout,+};+++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+struct Foo {+    a: i32,+    b: i32,+}++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C, align(4)]+struct Aligned([u8; 1024]);++fn main() {+    let mut array: Aligned = Aligned([1; 1024]);++    let foo : &mut Foo = (&mut array[0]).transmute_into();++    foo.a += 1;+}+```++### Case Study: Abstractions for Packet Parsing+***TODO: josh***++### Case Study: Abstractions for Pointer Bitpacking+[case-study-alignment]: #case-study-abstractions-for-pointer-bitpacking++A [previous motivating example](#expressing-layout-requirements) involved a generic abstraction only usable with types meeting certain layout requirements: pointer bitpacking. Using this RFC's mechanisms, we can require that a reference to a generic type `T` has alignment of at least a given value (e.g., `8`) by first defining a ZST with that alignment:+```rust+#[derive(PromiseTransmutableFrom)]+#[repr(align(8)]+struct Aligned8;+```+and then using this `where` bound:+```rust+where+    &T: TransmuteInto<&Aligned8>+```++## Rationale: `TransmuteFrom`/`TransmuteInto`++### Why support arbitrary transmutation?+Some [prior art][prior-art], especially in the crate ecosystem, provides an API that [only supports transmutations involving particular types](#Source-and-Destination-Types-Supported) (e.g., from/into bytes). As we discuss in the [prior art][prior-art] section, we believe that the inflexibility of such approaches make them a poor basis of a language proposal. In particular, these restrictive approaches don't leave room to grow: supporting additional transmutations requires additional traits.++The API advocated by this proposal is unopinionated about what transmutations users might wish to do, and what transmutations the compiler is able to reason about. The implementation of this RFC may be initially very simple (and perhaps support no more than the restrictive approaches allow for), but then subsequently grow in sophistication—*without* necessitating public API changes.++### Why *two* traits?+If `TransmuteInto` is implemented in terms of `TransmuteFrom`, why provide it at all? We do so for consistency with libcore's [`From`/`Into`](https://doc.rust-lang.org/stable/rust-by-example/conversion/from_into.html) traits, and because directionality conveys intent: `TransmuteInto` connotes *conversion*, whereas `TransmuteInto` connotes initialization. We believe that the supporting code examples of this RFC demonstrate the explanatory benefits of providing *both* traits.
If `TransmuteInto` is implemented in terms of `TransmuteFrom`, why provide it at all? We do so for consistency with libcore's [`From`/`Into`](https://doc.rust-lang.org/stable/rust-by-example/conversion/from_into.html) traits, and because directionality conveys intent: `TransmuteFrom` connotes *conversion*, whereas `TransmuteInto` connotes initialization. We believe that the supporting code examples of this RFC demonstrate the explanatory benefits of providing *both* traits.
jswrenn

comment created time in 43 minutes

pull request commentrust-lang/rust

Format Duration microseconds with "us" suffix, without Unicode

I'm torn here. What you say isn't unreasonable, but I'm also always opposed to using SI incorrectly, and it's unambiguously the case that "µs" is correct under SI and "us" isn't.

I think I might be more persuaded for Display, but since Debug is developer-focused I think it's fine for them to be expected to configure their system to allow Unicode, since even Windows terminals can do that fine these days.

joshtriplett

comment created time in 43 minutes

Pull request review commentrust-lang/docs.rs

Log HTML rewriting errors

 impl RustdocPage {             .expect("missing TemplateData from the request extensions");          // Build the page of documentation-        let ctx = ctry!(req, tera::Context::from_serialize(self),);+        let ctx = ctry!(req, tera::Context::from_serialize(self));         // Extract the head and body of the rustdoc file so that we can insert it into our own html-        let html = ctry!(-            req,-            utils::rewrite_lol(rustdoc_html, max_parse_memory, ctx, templates)-        );+        // while logging OOM errors from html rewriting+        let html = match utils::rewrite_lol(rustdoc_html, max_parse_memory, ctx, templates) {+            Err(RewritingError::MemoryLimitExceeded(..)) => {+                crate::web::metrics::HTML_REWRITE_OOMS.inc();++                let config = extension!(req, Config);+                let err = failure::err_msg(format!(+                    "Failed to serve the rustdoc file '{}' because rewriting it surpassed the memory limit of {} bytes",+                    file_path, config.max_parse_memory,+                ));++                ctry!(req, Err(err))

I originally tried this but got the error of

error[E0599]: no method named `context` found for enum `std::result::Result<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>` in the current scope
   --> src\web\rustdoc.rs:219:31
    |
219 |                 let err = err.context(format!(
    |                               ^^^^^^^ method not found in `std::result::Result<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>`
    |
   ::: C:\Users\Chase\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\src\libcore\result.rs:247:1
    |
247 | pub enum Result<T, E> {
    | --------------------- doesn't satisfy `_: failure::result_ext::ResultExt<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>`
    |
   ::: C:\Users\Chase\.cargo\registry\src\github.com-1ecc6299db9ec823\lol_html-0.2.0\src\rewriter\mod.rs:60:1
    |
60  | pub enum RewritingError {
    | ----------------------- doesn't satisfy `lol_html::rewriter::RewritingError: failure::Fail`
    |
   ::: C:\Users\Chase\.cargo\registry\src\github.com-1ecc6299db9ec823\quick-error-1.2.3\src\lib.rs:983:8
    |
983 |     fn context<X>(self, x: X) -> Result<T, Context<X, E>>;
    |        -------
    |        |
    |        the method is available for `std::boxed::Box<std::result::Result<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>>` here
    |        the method is available for `std::sync::Arc<std::result::Result<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>>` here
    |        the method is available for `std::rc::Rc<std::result::Result<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>>` here
    |
    = note: the method `context` exists but the following trait bounds were not satisfied:
            `lol_html::rewriter::RewritingError: failure::Fail`
            which is required by `std::result::Result<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>: failure::result_ext::ResultExt<std::vec::Vec<u8>, lol_html::rewriter::RewritingError>`
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope; perhaps add a `use` for it:
            `use quick_error::ResultExt;`

warning: unused import: `failure::ResultExt`
   --> src\web\rustdoc.rs:218:21
    |
218 |                 use failure::ResultExt;
    |                     ^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(unused_imports)]` on by default
Kixiron

comment created time in 43 minutes

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T> {+        data: *const T,+        len: usize,+        lifetime: core::marker::PhantomData<&'a ()>,+    }++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+                lifetime: core::marker::PhantomData,+            }+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```++The above code is "safe" because our simplified definition of constructability fails to recognize this pattern of encapsulation, and because `NeglectStability` is a `SafeTransmutationOption`.++The intent of `NeglectStability` is to permit the safe transmutation of types that predate the stabilization of the stability declaration traits. It also provides a convenient escape-hatch for type authors to neglect the stability of transmutations of their *own* types, without sacrificing safety. `NeglectStability` is a `SafeTransmutationOption` because, in principle, neglecting stability does not diminish safety. Our simplified definition of constructability violates this principle.++By temporarily sacrificing these goals, we may preserve safety solely...++##### ...at the Cost of `NeglectStability`+We may preserve safety by demoting `NeglectStability` to `UnsafeTransmutationOption`-status.++In doing so, a third-party is forced to resort to an `unsafe` transmutation to construct `NonEmptySlice`; e.g.:++```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,+{+    // unsafe because we `NeglectStability`+    unsafe { src.unsafe_transmute_into() }+}+```++Demoting `NeglectStability` to unsafe-status does not stop type authors from opting-in to stable (and thus safe) transmutations; e.g., with `derive(PromiseTransmutableFrom)`:+```rust+pub mod crate_a {++    #[derive(PromiseTransmutableFrom)]+    #[repr(C)]+    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);++    impl<'a, T> NonEmptySlice<'a, T> {+        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                    lifetime: core::marker::PhantomData,+                }+            )+        }++        pub fn first(&self) -> &'a T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[derive(PromiseTransmutableFrom)]+        #[repr(C)]+        pub struct NonEmptySliceInner<'a, T> {+            pub data: *const T,+            pub len: usize,+            pub lifetime: core::marker::PhantomData<&'a ()>,+        }+    }++}+```+In the above example, the type author declares `NonEmptySlice` and `NonEmptySliceInner` to be stably instantiatable via transmutation. Given this, a third-party no longer needs to resort to `unsafe` code to violate the the invariants on `inner`:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>+where+    T: TransmuteInto<NonEmptySlice<'static, u8>>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```+This safety hazard is not materially different from the one that would be induced if the type author implemented `DerefMut<Target=NonEmptySliceInner>` for `NonEmptySlice`, or made the `private` module `pub`, or otherwise explicitly provided outsiders with unrestricted mutable access to `data`.++##### Recommendation+We recommend that that implementers of this RFC initially simplify constructability by:+ - adopting our simplified definition of constructability+ - demoting `NeglectStability` to unsafe status (i.e., not implementing `SafeTransmuteOptions` for `NeglectStability`; *only* `UnsafeTransmuteOptions`)++If and when the implementation of `TransmuteFrom` encodes our complete definition of constructability, `NeglectStability` shall become a safe transmute option.+++## Dissecting Stability++In this section, we iteratively review the design of the stability declaration traits, starting with a simplest-possible design:+```rust+pub unsafe trait PromiseTransmutableFrom+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+{+    type Archetype;+}+```++### Part 1: Towards Safety++#### Forbidding Archetypes with Nonsense Validity+The simplest definitions of the stability declaration traits *must* be `unsafe` because `Archetype` can be instantiated in ways that undermine soundness; e.g.:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16; // <- Nonsense!+}++unsafe impl PromiseTransmutableFrom for u16 {+    type Archetype = u16;+}+```+These declarations subvert safety! Given these declarations, Rust will accept `u8: TransmuteInto<u16>`. This is problematic: `u8` is smaller than `u16`.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+u8:+    TransmuteInto<&'a Aligned8>+```++First, recall that a `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable into `<Dst as PromiseTransmutableFrom>::Archetype`, notwithstanding stability. The layouts of `Src` and `Dst` themselves are, in theory, immaterial — all that matters are the layouts of their stability archetypes. Formally:+```rust+𝙞𝙛+    <Src as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <Dst as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    Src: TransmuteInto<Dst>+```++We apply this rule to our initial equation:+```rust+𝙞𝙛+    <u8 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <u16 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    u8: TransmuteInto<u16>+```++Next, recall the definitions of `PromiseTransmutableInto` for `u8` and `PromiseTransmutableFrom` for `u16`:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16; // <- Nonsense!+}++unsafe impl PromiseTransmutableFrom for u16 {+    type Archetype = u16;+}+```+We apply these definitions to evaluate `<u8 as PromiseTransmutableInto>::Archetype` and `<u16 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    u16:+        TransmuteInto<+            u16,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    u8: TransmuteInto<u16>+```+Since `u16` can be safely transmuted into `u16`, the compiler accepts the transmutation of `u8` into `u16`!++</details>++---++We can prevent  nonsense archetypes by demanding that `Archetype` is transmutable into `Self` (notwithstanding stability):+```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+{+    type Archetype;+}+```++Our previous attempt to skirt soundness now produces a compile error:+```rust+unsafe impl PromiseTransmutableInto for u8 {+    type Archetype = u16;+                  // ^^^ the trait `TransmuteInto<u8, _>` is not implemented for `u16`+}+```++#### Forbidding Archetypes with Nonsense Alignment+Unfortunately, the above definition is still flawed. Consider these stability declarations:++```rust+#[derive(PromiseTransmutableFrom)]+#[repr(C)]+pub struct Aligned1;++#[derive(PromiseTransmutableInto)]+#[repr(C, align(8))]+pub struct Aligned8;++unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```++These declarations subvert safety! Given these declarations, Rust would accept the bound `&Aligned1: TransmuteInto<&Aligned8>`. This is problematic: `Aligned8` has *stricter* alignment requirements than `Aligned1`.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+for<'a> &'a Aligned1:+        TransmuteInto<&'a Aligned8>+```++As before, we first apply the stability rule to our equation:+```rust+𝙞𝙛+    <&'a Aligned1 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            <&'a Aligned8 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```++Next, recall the definitions of `PromiseTransmutableInto` and `PromiseTransmutableFrom` for `&T`:+```rust+unsafe impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a T::Archetype;+}++unsafe impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+We apply these definitions to evaluate `<&_ as PromiseTransmutableInto>::Archetype` and `<&_ as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    &'a <Aligned1 as PromiseTransmutableInto>::Archetype:+        TransmuteInto<+            &'a <Aligned8 as PromiseTransmutableFrom>::Archetype,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```++Finally, recall the definitions of `PromiseTransmutableInto` for `Aligned1` and `PromiseTransmutableFrom` for `Aligned8`:+```rust+unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```+We apply these definitions to evaluate `<Aligned1 as PromiseTransmutableInto>::Archetype` and `<Aligned8 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    &'a Aligned8:+        TransmuteInto<+            &'a Aligned1,+            NeglectStability+        >+𝙩𝙝𝙚𝙣+    for<'a> &'a Aligned1:+            TransmuteInto<&'a Aligned8>+```+Since `&'a Aligned8` can be safely transmuted into `&'a Aligned1`, the compiler accepts the transmutation of `&'a Aligned1` into `&'a Aligned1`!++</details>++---++This safety hazard can be prevented by rewriting our `where` bound like so: +```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>+{+    type Archetype;+}+```++Our previous attempt to skirt safety now produces a compiler error:+```rust+unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+                  // ^^^^^^^^ the trait `TransmuteFrom<&'_ Aligned1, NeglectStability>` is not implemented for `&'_ Aligned8`+}+```+++#### Forbidding Archetypes with Nonsense Validity Under Mutate-able Reference Transmutation+Unfortunately, the above definition is still flawed. Consider these stability declarations:+```rust+#[repr(u8)]+enum Boolean {+    False = 0,+    True = 1,+}++unsafe impl PromiseTransmutableInto for Boolean {+    type Type = u8;+}+```++Given these declarations, Rust would accept the bound `&mut Boolean: TransmuteInto<&mut u8>`. This is problematic: transmutations involving mutate-able references must not expand bit-validity.++---++<details style="background-color:#d9edf7;padding:1em">+<summary>Why would this transmutation be accepted? (Click to Expand)</summary>++Why would this transmutation be accepted? Let's solve this trait bound step-by-step:+```rust+/// 0. Initial equation:+for<'a> &'a mut Boolean:+        TransmuteInto<&'a mut u8>+```++As before, we first apply the stability rule to our equation:+```rust+𝙞𝙛+    for<'a> <&'a mut Boolean as PromiseTransmutableInto>::Archetype:+            TransmuteInto<+                <&'a mut u8 as PromiseTransmutableFrom>::Archetype,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```++Next, recall the definitions of `PromiseTransmutableInto` and `PromiseTransmutableFrom` for `&mut T`:+```rust+unsafe impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a T::Archetype;+}++unsafe impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+We apply these definitions to evaluate `<& mut _ as PromiseTransmutableInto>::Archetype` and `<& mut _ as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    for<'a> &'a mut <Boolean as PromiseTransmutableInto>::Archetype:+            TransmuteInto<+                &'a mut <u8 as PromiseTransmutableFrom>::Archetype,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```++Finally, recall the definitions of `PromiseTransmutableInto` for `Boolean` and `PromiseTransmutableFrom` for `u8`:+```rust+unsafe impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+}++unsafe impl PromiseTransmutableFrom for u8 {+    type Archetype = Self;+}+```+We apply these definitions to evaluate `<Boolean as PromiseTransmutableInto>::Archetype` and `<u8 as PromiseTransmutableFrom>::Archetype`:+```rust+𝙞𝙛+    for<'a> &'a mut u8:+            TransmuteInto<+                &'a mut u8,+                NeglectStability+            >+𝙩𝙝𝙚𝙣+    for<'a> '&mut Boolean:+            TransmuteInto<&'a mut u8>+```+Since `&'a mut u8` can be safely transmuted into `&'a mut u8`, the compiler accepts the transmutation of `&mut Boolean` into `&mut u8`.++</details>++---++This safety hazard can be prevented by rewriting our `where` bounds like so: +```rust+pub trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>,+    for<'a> &'a mut Self::Archetype: TransmuteInto<&'a mut Self, NeglectStability>+{+    type Archetype;+}++pub trait PromiseTransmutableInto+where+    Self::Archetype: TransmutFrom<Self, NeglectStability>,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>,+    for<'a> &'a mut Self::Archetype: TransmuteFrom<&'a mut Self, NeglectStability>+{+    type Archetype;+}+```++Our previous attempt to skirt safety now produces a compiler error:+```rust+impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+                  // ^^ the trait `TransmuteFrom<&'_ mut u8, NeglectStability>` is not implemented for `&'_ mut Boolean`+}+```++### Part 2: Towards Flexibility+In the previous two sections, we bypassed the safety effects of the `PromiseTransmutable{From,Into}` traits' `where` bounds by defining archetypes whose quirks were only apparent under a *more* restrictive transmutation than that enforced by the `where` bound.++We cannot play the same trick to bypass safety with our latest `where` bound. Between transmutations involving values, shared references and unique references, the rules governing transmutations involving unique references are the most restrictive.++However, this safety comes at the expense of flexibility. Recall our last 'dangerous' archetype:+```rust+impl PromiseTransmutableInto for Boolean {+    type Archetype = u8;+                  // ^^ the trait `TransmuteFrom<&'_ mut u8, NeglectStability>` is not implemented for `&'_ mut Boolean`+}+```+This archetype is sensible in the context of value transmutations. It's sensible in the context of immutable reference transmutations. The *only* context in which it is *not* sensible are mutate-able reference transmutations! Our changes achieved safety at the significant expense of flexibility.++In this section, we begin at our previous value-safe definition of the stability declaration traits:+```rust+pub unsafe trait PromiseTransmutableFrom+where+    Self::Archetype: TransmuteInto<Self, NeglectStability>,+{+    type Archetype;+}++pub unsafe trait PromiseTransmutableInto+where+    Self::Archetype: TransmuteFrom<Self, NeglectStability>,+{+    type Archetype;+}+```+...and solve its reference-unsafety in a manner that preserves flexibility.++#### Compartmentalizing Shared Reference Transmutation Stability+Reconsider these stability declarations:+```rust+#[derive(PromiseTransmutableFrom)]+#[repr(C)]+pub struct Aligned1;++#[derive(PromiseTransmutableInto)]+#[repr(C, align(8))]+pub struct Aligned8;++unsafe impl PromiseTransmutableInto for Aligned1 {+    type Archetype = Aligned8;+}++unsafe impl PromiseTransmutableFrom for Aligned8 {+    type Archetype = Aligned1;+}+```++Given these declarations, Rust would accept the bound `&Aligned1: TransmuteInto<&Aligned8>`. This is problematic: `Aligned8` has *stricter* alignment requirements than `Aligned1`.++In our derivation of why the compiler accepted this transmutation, we referred to the stability declarations of `&T`:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom,+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a T::Archetype;+}+```+Rather than change the `where` bound of the *definitions* of `PromiseTransmutableFrom` and `PromiseTransmutableInto`, we can simply change the `where` bound of those two *implementations* of the traits:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a T+where+    T: PromiseTransmutableFrom,+    for<'a> &'a Self::Archetype: TransmuteInto<&'a Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a T+where+    T: PromiseTransmutableInto,+    for<'a> &'a Self::Archetype: TransmuteFrom<&'a Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}+```++#### Compartmentalizing Unique Reference Transmutation Stability+Likewise, for unique references, we go from this:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom+{+    type Archetype = &'a mut T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto+{+    type Archetype = &'a mut T::Archetype;+}+```+...to this:+```rust+impl<'a, T> PromiseTransmutableFrom for &'a mut T+where+    T: PromiseTransmutableFrom,+    for<'a> &'a mut Self::Archetype: TransmuteInto<&'a mut Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}++impl<'a, T> PromiseTransmutableInto for &'a mut T+where+    T: PromiseTransmutableInto,+    for<'a> &'a mut Self::Archetype: TransmuteFrom<&'a mut Self, NeglectStability>+{+    type Archetype = &'a T::Archetype;+}+```++### Part 3: Towards Sensibility++In the previous two parts, we developed safe-and-flexible stability declaration traits. While we cannot make unsafe archetype choices, we can still make *silly* archetype choices. For instance, we can declare the stability of our types in terms of types that are *not* stable:++```rust+#[repr(u8)]+pub struct Foo { ... }++#[repr(u8)]+pub struct Bar { ... }++impl PromiseTransmutableInto for Foo {+    type Archetype = Bar;+}+```++We can prevent these sorts of silly archetypes by requiring that `Archetype` itself is stable, and that its stability archetype is not transitively defined:++```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++# Drawbacks+[drawbacks]: #drawbacks++## No Notion of Platform Stability+The stability declaration traits communicate library layout stability, but not *platform* layout stability. A transmutation is platform-stable if it compiling one one platform implies it will compile on all other platforms. Unfortunately, platform-unstable types are common;  e.g.:++- All pointer-related primitive types (`usize`, `isize`, `*const T`, `*mut T`, `&T`, `&mut T`) possess platform-dependent layouts; their sizes and alignments are well-defined, but vary between platforms. Concretely, whether `usize` is `TransmuteInto<[u8; 4]>` or `TransmuteInto<[u8; 8]>` will depend on  the platform.+- The very existence of some types depends on platform, too; e.g., the contents of [`core::arch`](https://doc.rust-lang.org/stable/core/arch/), [`std::os`](https://doc.rust-lang.org/stable/std/os/), and [`core::sync::atomic`](https://doc.rust-lang.org/stable/std/sync/atomic/) all depend on platform.++Expanding this RFC to address such types would introduce considerable additional complexity:+<ol>+<li>++**Cognitive Complexity:** For types whose layout varies between platforms, the [stability] declaration traits could, *perhaps*, be adapted to encode platform-related guarantees. We anticipate this would contribute substantial cognitive complexity. Type authors, even those with no interest in cross-platform stability, would nonetheless need to reason about the layout properties of their types on platforms that might not yet exist.+</li>+<li>++**Ergonomic Complexity:** Platform instabilities are contagious: a type that *contains* a platform-unstable type is, itself, platform-unstable. Due to the sheer virulence of types with platform-dependent layouts, an explicit '`NeglectPlatformStability`' option would need to be used for *many* simple transmutations. The ergonomic cost of this would also be substantial.++</li>+<li>++**Implementation Complexity:** The mechanisms proposed by this RFC are, fundamentally, applications of and additions to Rust's type system (i.e., they're traits). Mechanisms that impact platform stability, namely `#[cfg(...)]` annotations, long precede type-resolution and layout computation in the compilation process. For instance, it's possible to define types with impossible layouts:    +```rust+#[cfg(any())]+struct Recursive(Recursive);+```+This program compiles successfully on all platforms because, from the perspective of later compilation stages, `Recursive` may as well not exist.++</li>+</ol>++The issues of platform layout stability exposed by this RFC are not fundamentally different from the challenges of platform API stability. These challenges are already competently addressed by the mechanisms proposed in [RFC1868](https://github.com/rust-lang/rfcs/pull/1868). For this reason, and for the aforementioned concerns of additional complexity, we argue that communicating and enforcing platform layout stability must remain outside the scope of this RFC.++## Stability of *Unsafe* Transmutations+[drawback-unsafe-stability]: #Stability-of-Unsafe-Transmutations++The model of stability proposed by this RFC frames stability as a quality of *safe* transmutations. A type author cannot specify stability archetypes for *unsafe* transmutations, and it is reasonable to want to do so.++To accomodate this, we may modify the definitions of `PromiseTransmutableFrom` and `PromiseTransmutableInto` to consume an optional `Neglect` parameter, to allow for stability declarations for unsafe transmutations:+```rust+pub trait PromiseTransmutableFrom<Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions+{+    type Archetype+        : TransmuteInto<Self, Sum<Neglect, NeglectStability>>+        + PromiseTransmutableInto<Sum<Neglect, NeglectStability>>;+}++pub trait PromiseTransmutableInto<Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions+{+    type Archetype+        : TransmuteFrom<Self, Sum<Neglect, NeglectStability>>+        + PromiseTransmutableInto<Sum<Neglect, NeglectStability>>;+}+```+Implementations of these traits for a given `Neglect` declares that a transmutation which is accepted while neglecting a particular set of checks (namely the set encoded by `Neglect`) will *continue* to be possible.++We omit these definition from this RFC's recommendations because they are not completely satisfying. For instance, `Neglect` is a *logically* unordered set of options, but is encoded as a tuple (which *is* ordered). To declare a transmutation that requires neglecting validity and alignment checks as stable, only *one* of these impls ought to be necessary:++```rust+impl PromiseTransmutableFrom<(NeglectAlignment, NeglectValidity)> for Foo+{+    ...+}++impl PromiseTransmutableFrom<(NeglectValidity, NeglectAlignment)> for Foo+{+    ...+}+```+Writing *both* impls (as we do above) is logically nonsense, but is nonetheless supported by Rust's coherence rules.+++# Rationale and alternatives+[rationale-and-alternatives]: #rationale-and-alternatives++## Case Studies++### Case Study: Making Unsafe Rust Safer+[case-study-safer-unsafe]: #Case-Study-Making-Unsafe-Rust-Safer++This RFC proposes mechanisms for safe transmutation and safer *unsafe* transmutation. How might [Kelley's motivating example][motivation-safer-unsafe] change in light of these mechanisms?++#### Safer Unsafe+For the compiler to accept a use of `unsafe_transmute`, we must:+   - use `unsafe_transmute` with the `NeglectAlignment` option+   - annotate `Foo` with `#[repr(C)]` so its layout is defined+   - annotate `Foo` with `#[derive(PromiseTransmutableFrom,PromiseTransmutableInto)]` to indicate its layout is library-stable (alternatively, we could also use the  `NeglectStability` option)++The sum of these changes:+```rust+use core::transmute::{+    unsafe_transmute,+    options::NeglectAlignment,+    stability::FixedLayout,+};+++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    let mut array: [u8; 1024] = [1; 1024];++    let mut foo = unsafe {+        // check alignment ourselves+        assert_eq!((src as *const u8 as usize) % align_of::<Foo>(), 0);++        // transmute `&mut array` to `&mut Foo`+        // permitted becasue we promise to check the alignment ourselves+        let foo = unsafe_transmute::<&mut [u8; 1024], &mut Foo, NeglectAlignment>(&mut array);+    };++    foo.a += 1;+}+```++#### No Unsafe Needed!+Better yet, we may use a completely *safe* transmute if we statically align the byte array:++```rust+use core::transmute::{+    TransmuteInto,+    options::NeglectAlignment,+    stability::FixedLayout,+};+++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+struct Foo {+    a: i32,+    b: i32,+}++#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C, align(4)]+struct Aligned([u8; 1024]);++fn main() {+    let mut array: Aligned = Aligned([1; 1024]);++    let foo : &mut Foo = (&mut array[0]).transmute_into();++    foo.a += 1;+}+```++### Case Study: Abstractions for Packet Parsing+***TODO: josh***++### Case Study: Abstractions for Pointer Bitpacking+[case-study-alignment]: #case-study-abstractions-for-pointer-bitpacking++A [previous motivating example](#expressing-layout-requirements) involved a generic abstraction only usable with types meeting certain layout requirements: pointer bitpacking. Using this RFC's mechanisms, we can require that a reference to a generic type `T` has alignment of at least a given value (e.g., `8`) by first defining a ZST with that alignment:+```rust+#[derive(PromiseTransmutableFrom)]+#[repr(align(8)]+struct Aligned8;+```+and then using this `where` bound:+```rust+where+    &T: TransmuteInto<&Aligned8>+```++## Rationale: `TransmuteFrom`/`TransmuteInto`++### Why support arbitrary transmutation?+Some [prior art][prior-art], especially in the crate ecosystem, provides an API that [only supports transmutations involving particular types](#Source-and-Destination-Types-Supported) (e.g., from/into bytes). As we discuss in the [prior art][prior-art] section, we believe that the inflexibility of such approaches make them a poor basis of a language proposal. In particular, these restrictive approaches don't leave room to grow: supporting additional transmutations requires additional traits.++The API advocated by this proposal is unopinionated about what transmutations users might wish to do, and what transmutations the compiler is able to reason about. The implementation of this RFC may be initially very simple (and perhaps support no more than the restrictive approaches allow for), but then subsequently grow in sophistication—*without* necessitating public API changes.++### Why *two* traits?+If `TransmuteInto` is implemented in terms of `TransmuteFrom`, why provide it at all? We do so for consistency with libcore's [`From`/`Into`](https://doc.rust-lang.org/stable/rust-by-example/conversion/from_into.html) traits, and because directionality conveys intent: `TransmuteInto` connotes *conversion*, whereas `TransmuteInto` connotes initialization. We believe that the supporting code examples of this RFC demonstrate the explanatory benefits of providing *both* traits.

I believe this should read:

TransmuteInto connotes conversion, whereas TransmuteFrom connotes initialization

With the second one being TransmuteFrom.

jswrenn

comment created time in 44 minutes

pull request commentrust-lang/rust

Add `#[cfg(panic = '...')]`

@rfcbot concern breakage-if-we-add-more-unwind-strategies

I'm registering this concern to represent @Mark-Simulacrum's excellent point that this likely means that we would "de facto" break code when adding new unwind strategies in the future.

davidhewitt

comment created time in 44 minutes

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

:hourglass: Testing commit 18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f with merge cca2c20c8b6cd0a71346bf7f85feb3c6291bd60d... <!-- homu: {"type":"BuildStarted","head_sha":"18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f","merge_sha":"cca2c20c8b6cd0a71346bf7f85feb3c6291bd60d"} -->

eggyal

comment created time in 44 minutes

PR merged rust-lang/rust

Forbid non-derefable types explicitly in unsizing casts S-waiting-on-bors merged-by-bors

Fixes #75118 r? @oli-obk

+31 -1

9 comments

3 changed files

JohnTitor

pr closed time in 44 minutes

push eventrust-lang/rust

Yuki Okushi

commit sha cd7204ef394d1e53bb967086186e9b8664d7e268

Forbid non-derefable types explicitly in unsizing casts

view details

bors

commit sha f9d422ea78a4652c5d9ecd6b6d7577bdfbfd98a8

Auto merge of #75136 - JohnTitor:unsizing-casts-non-null, r=oli-obk Forbid non-derefable types explicitly in unsizing casts Fixes #75118 r? @oli-obk

view details

push time in 44 minutes

issue closedrust-lang/rust

ICE when coercing `NonNull<[T; 0]>` to `NonNull<[T]>` in const fn

Code

use core::ptr::NonNull;

pub const fn dangling_slice<T>() -> NonNull<[T]> {
    NonNull::<[T; 0]>::dangling()
}

Meta

rustc --version --verbose:

1.46.0-beta.2

(2020-07-23 6f959902b3103c49ca98)

Error output

   Compiling playground v0.0.1 (/playground)
thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value', src/librustc_mir/transform/qualify_min_const_fn.rs:196:58
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.46.0-beta.2 (6f959902b 2020-07-23) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type lib

note: some of the compiler flags provided by cargo are hidden

error: could not compile `playground`.

To learn more, run the command again with --verbose.

<!-- Include a backtrace in the code block by setting RUST_BACKTRACE=1 in your environment. E.g. RUST_BACKTRACE=1 cargo build. --> <details><summary><strong>Backtrace</strong></summary> <p>

thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value', src/librustc_mir/transform/qualify_min_const_fn.rs:196:58
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:217
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:530
  12: rust_begin_unwind
             at src/libstd/panicking.rs:437
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  14: core::panicking::panic
             at src/libcore/panicking.rs:50
  15: rustc_mir::transform::qualify_min_const_fn::is_min_const_fn
  16: rustc_mir::transform::check_consts::validation::Validator::check_body
  17: rustc_mir::transform::mir_const_qualif
  18: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::mir_const_qualif>::compute
  19: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  20: rustc_data_structures::stack::ensure_sufficient_stack
  21: rustc_query_system::query::plumbing::get_query_impl
  22: rustc_mir::transform::mir_validated
  23: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::mir_validated>::compute
  24: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  25: rustc_data_structures::stack::ensure_sufficient_stack
  26: rustc_query_system::query::plumbing::get_query_impl
  27: rustc_mir::borrow_check::mir_borrowck
  28: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::mir_borrowck>::compute
  29: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  30: rustc_data_structures::stack::ensure_sufficient_stack
  31: rustc_query_system::query::plumbing::get_query_impl
  32: rustc_query_system::query::plumbing::ensure_query_impl
  33: rustc_session::utils::<impl rustc_session::session::Session>::time
  34: rustc_interface::passes::analysis
  35: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::analysis>::compute
  36: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  37: rustc_query_system::query::plumbing::get_query_impl
  38: rustc_middle::ty::context::tls::enter_global
  39: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
  40: rustc_span::with_source_map
  41: rustc_interface::interface::create_compiler_and_run
  42: scoped_tls::ScopedKey<T>::set
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.46.0-beta.2 (6f959902b 2020-07-23) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type lib

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [mir_const_qualif] const checking `dangling`
#1 [mir_validated] processing `dangling`
#2 [mir_borrowck] borrow-checking `dangling`
#3 [analysis] running analysis passes on this crate
end of query stack
error: could not compile `playground`.

To learn more, run the command again with --verbose.

</p> </details>

closed time in 44 minutes

rodrimati1992

pull request commentrust-lang/rust

Forbid non-derefable types explicitly in unsizing casts

:sunny: Test successful - checks-actions, checks-azure Approved by: oli-obk Pushing f9d422ea78a4652c5d9ecd6b6d7577bdfbfd98a8 to master... <!-- homu: {"type":"BuildCompleted","approved_by":"oli-obk","base_ref":"master","builders":{"checks-azure":"https://dev.azure.com/rust-lang/e71b0ddf-dd27-435a-873c-e30f86eea377/_build/results?buildId=35788","checks-actions":"https://github.com/rust-lang-ci/rust/runs/946652502"},"merge_sha":"f9d422ea78a4652c5d9ecd6b6d7577bdfbfd98a8"} -->

JohnTitor

comment created time in 44 minutes

pull request commentrust-lang/rust

rustc_ast: Stop using "string typing" for doc comment tokens

Updated with the requested comments.

petrochenkov

comment created time in 44 minutes

push eventrust-lang/crates.io-index

bors

commit sha 40c705c63cb8b3942b24c738e15865ab1c3af483

Updating crate `urandom#0.1.0`

view details

push time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

 let p = Point { x: 4, y: 2 };      // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor. ``` -Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `Constrained`, which enforces a validity constraint on its fields via its constructor:+Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:  ```rust pub mod crate_a {      #[repr(C)]-    pub struct Constrained {-        wizz: i8,-        bang: u8,+    pub struct NonEmptySlice<T> {+        data: *const T,+        len: usize,     } -    impl Constrained {-        /// the sum of `wizz` and `bang` must be greater than or equal to zero.-        pub fn new(wizz: i8, bang: u8) -> Self {-            assert!((wizz as i16) + (bang as i16) >= 0);-            Constrained { wizz, bang }+    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,

Fixed by https://github.com/rust-lang/project-safe-transmute/pull/5/commits/00167d659e8c94c7f92468831714df47dadceab8

jswrenn

comment created time in an hour

pull request commentrust-lang/rustc-perf

Revert "Share target directories between benchmarks"

I'm going to hold off on merging this until I finish a local collection with this on -- without, I see a full build taking 4014 seconds. If this is faster locally then I'll see if we can't reproduce that on the collector somehow before landing this.

Mark-Simulacrum

comment created time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:
A value may ***not*** be transmuted into a type of greater size, if doing so would expose uninitialized bytes as initialized:
jswrenn

comment created time in an hour

PR opened rust-lang/rustc-perf

Revert "Share target directories between benchmarks"

Reverts rust-lang/rustc-perf#738

It appears to be a performance regression (up 5 minutes on the collector).

+31 -66

0 comment

2 changed files

pr created time in an hour

create barnchrust-lang/rustc-perf

branch : revert-738-share-build-cache

created branch time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelly notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelly misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialized types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```+

I presume the same problem is true in this case (the extra bytes would be uninitialized) but it may be worth calling that out for clarity.

This is an interesting observation, because I hadn't considered that expanding the size could ever be valid, except your observation suggests a case where it could be: transmuting [MaybeUninit<u8>; 2] to [MaybeUninit<u8>; 4] (or any situation where the trailing bit of the destination type may be uninit)!

I'm going to rephrase this as:

A value may not be transmuted into a type of greater size, if doing so would expose uninitialized bytes as if they were initialized:

jswrenn

comment created time in an hour

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

:pushpin: Commit 18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f has been approved by Mark-Simulacrum

<!-- @bors r=Mark-Simulacrum 18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f --> <!-- homu: {"type":"Approved","sha":"18d4ba34907e7d0b9fc142a9d9a9c5bbdae4279f","approver":"Mark-Simulacrum"} -->

eggyal

comment created time in an hour

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

@bors r+ rollup=iffy -- not sure if the added test will have the exact same output on other platforms

eggyal

comment created time in an hour

startedrust-lang/rustlings

started time in an hour

pull request commentrust-lang/rustc-perf

Share target directories between benchmarks

Okay this does indeed seem to be a regression:

  • 01:47:05 before this landed
  • 01:51:52 after this landed

Nothing obviously slower landed in rustc in that time either. I am unsure yet if there's some room for wins here or if we should just revert.

Mark-Simulacrum

comment created time in an hour

pull request commentrust-lang/rust

Prevent `__rust_begin_short_backtrace` frames from being tail-call optimised away

Sure, force-pushed a squash. Had thought bors would do that when merging.

eggyal

comment created time in an hour

Pull request review commentrust-lang/docs.rs

Fixed accidental URL escaping

     <updated>{{ recent_releases[0].release_time | default(value=now()) | date(format="%+") }}</updated>      {%- for release in recent_releases -%}-        {# FIXME: https://github.com/Keats/tera/issues/539 #}-        {%- set name = release.name | escape_xml -%}-        {%- set version = release.version | escape_xml -%}         {%- if release.rustdoc_status -%}-            {%- set link = "/" ~ name ~ "/" ~ version ~ "/" ~ release.target_name -%}+            {%- set link = "/" ~ release.name ~ "/" ~ release.version ~ "/" ~ release.target_name -%}         {%- else -%}-            {%- set link = "/crate/" ~ name ~ "/" ~ version -%}+            {%- set link = "/crate/" ~ release.name ~ "/" ~ release.version -%}         {%- endif %}          <entry>-            <title>{{ name }}-{{ version }}</title>+            <title>{{ release.name }}-{{ version }}</title>              <link href="{{ link | safe }}" />-            <id>urn:docs-rs:{{ name }}:{{ version }}</id>+            <id>urn:docs-rs:{{ release.name }}:{{ version }}</id>
            <id>urn:docs-rs:{{ release.name }}:{{ release.version }}</id>
Kixiron

comment created time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T> {+        data: *const T,+        len: usize,+    }++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+            }+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,
pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>
where
    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,
jswrenn

comment created time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T> {+        data: *const T,+        len: usize,+    }++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+            }+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```++The above code is "safe" because our simplified definition of constructability fails to recognize this pattern of encapsulation, and because `NeglectStability` is a `SafeTransmutationOption`.++The intent of `NeglectStability` is to permit the safe transmutation of types that predate the stabilization of the stability declaration traits. It also provides a convenient escape-hatch for type authors to neglect the stability of transmutations of their *own* types, without sacrificing safety. `NeglectStability` is a `SafeTransmutationOption` because, in principle, neglecting stability does not diminish safety. Our simplified definition of constructability violates this principle.++By temporarily sacrificing these goals, we may preserve safety solely...++##### ...at the Cost of `NeglectStability`+We may preserve safety by demoting `NeglectStability` to `UnsafeTransmutationOption`-status.++In doing so, a third-party is forced to resort to an `unsafe` transmutation to construct `NonEmptySlice`; e.g.:++```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,+{+    // unsafe because we `NeglectStability`+    unsafe { src.unsafe_transmute_into() }+}+```++Demoting `NeglectStability` to unsafe-status does not stop type authors from opting-in to stable (and thus safe) transmutations; e.g., with `derive(PromiseTransmutableFrom)`:+```rust+pub mod crate_a {++    #[derive(PromiseTransmutableFrom)]+    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[derive(PromiseTransmutableFrom)]+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+In the above example, the type author declares `NonEmptySlice` and `NonEmptySliceInner` to be stably instantiatable via transmutation. Given this, a third-party no longer needs to resort to `unsafe` code to violate the the invariants on `inner`:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>>,
pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>
where
    T: TransmuteInto<NonEmptySlice<'static, u8>>,
jswrenn

comment created time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T> {+        data: *const T,+        len: usize,+    }++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+            }+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```++The above code is "safe" because our simplified definition of constructability fails to recognize this pattern of encapsulation, and because `NeglectStability` is a `SafeTransmutationOption`.++The intent of `NeglectStability` is to permit the safe transmutation of types that predate the stabilization of the stability declaration traits. It also provides a convenient escape-hatch for type authors to neglect the stability of transmutations of their *own* types, without sacrificing safety. `NeglectStability` is a `SafeTransmutationOption` because, in principle, neglecting stability does not diminish safety. Our simplified definition of constructability violates this principle.++By temporarily sacrificing these goals, we may preserve safety solely...++##### ...at the Cost of `NeglectStability`+We may preserve safety by demoting `NeglectStability` to `UnsafeTransmutationOption`-status.++In doing so, a third-party is forced to resort to an `unsafe` transmutation to construct `NonEmptySlice`; e.g.:++```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,
pub evil_constructor<T>(src: T) -> NonEmptySlice<'static, u8>
where
    T: TransmuteInto<NonEmptySlice<'static, u8>, NeglectStability>,
jswrenn

comment created time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T> {+        data: *const T,+        len: usize,+    }++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+            }+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {+    type Type = [MaybeUninit<u8>; 5];+}+```++##### Crafting Uninformative `PromiseTransmutableFrom` Archetypes++###### Archetype Alignment+You may freely decrease the required alignment of your type to any value less-than-or-equal to the required alignment of your archetype. The maximum alignment requirement permitted by Rust is 2<sup>29</sup>.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. Unfortunately, the maximum size of types in Rust is [architecture-dependent](https://github.com/rust-lang/rust/blob/63b441aafbf52d6ba789ecc478455800c1a48df9/src/librustc_target/abi/mod.rs#L179-L197). For the greatest portability, your archetype should be no larger than 2<sup>15</sup>. An archetype of this size provides (un)reasonable future flexibility.++###### Archetype Validity & Visibility+You may freely make your type *less* constructible (in terms of both theoretical validity and constructor visibility) than your archetype.++A minimally-informative archetype may be constructed using this as a building-block:+```rust+struct None(u8);+```+Since the `u8` field is private, its valid values are assumed to be constrained by library invariants.++##### Crafting Uninformative `PromiseTransmutableInto` Archetypes++###### Archetype Alignment+You may freely increase the required alignment of your type to any value greater-than-or-equal to the required alignment of your archetype. The minimum alignment requirement permitted by Rust is 1.++###### Archetype Size+You may decrease the size of your type without violating stability to any size less-than-or-equal to the size of your archetype. The minimum size of types in Rust is 0.++###### Archetype Validity & Visibility+You may freely make your type more constructible (in terms of both visibility and theoretical validity) than your archetype. A minimally-informative archetype may be constructed using `MaybeUninit<u8>` as a building-block, since *any* possible instantiation of a byte is a valid instantiation of `MaybeUninit<u8>`.+++## Mechanisms of Transmutation++Two traits provide mechanisms for transmutation between types: +```rust+// this trait is implemented automagically by the compiler+#[lang = "transmute_from"]+pub unsafe trait TransmuteFrom<Src: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    #[inline(always)]+    fn transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: SafeTransmuteOptions,+    {+        unsafe { Self::unsafe_transmute_from(src) }+    }++    #[inline(always)]+    unsafe fn unsafe_transmute_from(src: Src) -> Self+    where+        Src: Sized,+        Self: Sized,+        Neglect: UnsafeTransmuteOptions,+    {+        use core::{mem, ptr};+        unsafe {+            let dst = ptr::read_unaligned(&src as *const Src as *const Self);+            mem::forget(src);+            dst+        }+    }+}++// implemented in terms of `TransmuteFrom`+pub unsafe trait TransmuteInto<Dst: ?Sized, Neglect = ()>+where+    Neglect: UnsafeTransmuteOptions,+{+    fn transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: SafeTransmuteOptions;++    unsafe fn unsafe_transmute_into(self) -> Dst+    where+        Self: Sized,+        Dst: Sized,+        Neglect: UnsafeTransmuteOptions;+}++unsafe impl<Src, Dst, Neglect> TransmuteInto<Dst, Neglect> for Src+where+    Src: ?Sized,+    Dst: ?Sized + TransmuteFrom<Src, Neglect>,+    Neglect: UnsafeTransmuteOptions,+{+    ...+}+```++In the above definitions, `Src` represents the source type of the transmutation, `Dst` represents the destination type of the transmutation, and `Neglect` is a parameter that [encodes][options] which static checks the compiler ought to neglect when considering if a transmutation is valid. The default value of `Neglect` is `()`, which reflects that, by default, the compiler does not neglect *any* static checks.++### Neglecting Static Checks+[options]: #Neglecting-Static-Checks++The default value of the `Neglect` parameter, `()`, statically forbids transmutes that are unsafe, unsound, or unstable. However, you may explicitly opt-out of some static checks:++| Transmute Option    | Compromises | Usable With                                             |+|---------------------|-------------|---------------------------------------------------------|+| `NeglectStabilty`   | Stability   | `transmute_{from,into}`, `unsafe_transmute_{from,into}` |+| `NeglectAlignment`  | Safety      | `unsafe_transmute_{from,into}`                          |+| `NeglectValidity`   | Soundness   | `unsafe_transmute_{from,into}`                          |++`NeglectStabilty` implements the `SafeTransmuteOptions` and `UnsafeTransmuteOptions` marker traits, as it can be used in both safe and unsafe code. The selection of multiple options is encoded by grouping them as a tuple; e.g., `(NeglectAlignment, NeglectValidity)` is a selection of both the `NeglectAlignment` and `NeglectValidity` options.++We introduce two marker traits which serve to group together the options that may be used with safe transmutes, and those which may be used with `unsafe` transmutes:+```rust+pub trait SafeTransmuteOptions: private::Sealed+{}++pub trait UnsafeTransmuteOptions: SafeTransmuteOptions+{}++impl SafeTransmuteOptions for () {}+impl UnsafeTransmuteOptions for () {}+```++#### `NeglectStability`+[`NeglectStability`]: #neglectstability++By default, `TransmuteFrom` and `TransmuteInto`'s methods require that the [layouts of the source and destination types are SemVer-stable][stability]. The `NeglectStability` option disables this requirement.+```rust+pub struct NeglectStability;++impl SafeTransmuteOptions for NeglectStability {}+impl UnsafeTransmuteOptions for NeglectStability {}+```++Prior to the adoption of the [stability declaration traits][stability], crate authors documented the layout guarantees of their types with doc comments. The `TransmuteFrom` and `TransmuteInto` traits and methods may be used with these types by requesting that the stability check is neglected; for instance:++```rust+fn serialize<W: Write>(val : LibraryType, dst: W) -> std::io::Result<()>+where+    LibraryType: TransmuteInto<[u8; size_of::<LibraryType>()], NeglectStability>+{+    ...+}+```++Neglecting stability over-eagerly cannot cause unsoundness or unsafety. For this reason, it is the only transmutation option available on the safe methods `transmute_from` and `transmute_into`. However, neglecting stability over-eagerly may cause your code to cease compiling if the authors of the source and destination types make changes that affect their layout.++By using the `NeglectStability` option to transmute types you do not own, you are committing to ensure that your reliance on these types' layouts is consistent with their documented stability guarantees.++#### `NeglectAlignment`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that, when transmuting references, the minimum alignment of the destination's referent type is no greater than the minimum alignment of the source's referent type. The `NeglectAlignment` option disables this requirement.+```rust+pub struct NeglectAlignment;++impl UnsafeTransmuteOptions for NeglectAlignment {}+```++By using the `NeglectAlignment` option, you are committing to ensure that the transmuted reference satisfies the alignment requirements of the destination's referent type. For instance:+```rust+/// Try to convert a `&T` into `&U`.+///+/// This produces `None` if the referent isn't appropriately+/// aligned, as required by the destination type.+pub fn try_cast_ref<'t, 'u, T, U>(src: &'t T) -> Option<&'u U>+where+    &'t T: TransmuteInto<&'u U, neglect::Alignment>,+{+    if (src as *const T as usize) % align_of::<U>() != 0 {+        None+    } else {+        // Safe because we dynamically enforce the alignment+        // requirement, whose static check we chose to neglect.+        Some(unsafe { src.unsafe_transmute_into() })+    }+}+```++#### `NeglectValidity`+By default, `TransmuteFrom` and `TransmuteInto`'s methods require that all instantiations of the source type are guaranteed to be valid instantiations of the destination type. This precludes transmutations which *might* be valid depending on the source value:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++/* ⚠️ This example intentionally does not compile. */+let _ : Bool  = some_u8_value.transmute_into(); // Compile Error!+```+The `NeglectValidity` option disables this check.+```rust+pub struct NeglectValidity;++impl UnsafeTransmuteOptions for NeglectValidity {}+```++By using the `NeglectValidity` option, you are committing to ensure dynamically source value is a valid instance of the destination type. For instance:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++pub trait TryIntoBool+{+    fn try_into_bool(self) -> Option<Bool>;+}++impl<T> TryIntoBool for T+where+    T: TransmuteInto<u8>,+    u8: TransmuteInto<Bool, NeglectValidity>+{+    fn try_into_bool(self) -> Option<Bool> {+        let val: u8 = self.transmute_into();++        if val > 1 {+            None+        } else {+            // Safe, because we've first verified that+            // `val` is a bit-valid instance of a boolean.+            Some(unsafe {val.unsafe_transmute_into()})+        }+    }+}+```++Even with `NeglectValidity`, the compiler will statically reject transmutations that cannot possibly be valid:+```rust+#[derive(PromiseTransmutableInto)]+#[repr(C)] enum Foo { A = 24 }++#[derive(PromiseTransmutableFrom)]+#[repr(C)] enum Bar { Z = 42 }++let _ = <Bar as TransmuteFrom<Foo, NeglectValidity>::unsafe_transmute_from(Foo::N) // Compile error!+```++# Reference-level explanation+[reference-level-explanation]: #reference-level-explanation+++## Implementation Guidance+The *only* item defined by this RFC requiring special compiler support is `TransmuteFrom`. To realize this RFC's proposal of safe transmutation between different types, this item will require compiler support. However, the *most* minimal acceptable implementation of `TransmuteFrom` can be achieved entirely in-language:++```rust+/// A type is transmutable into itself.+unsafe impl<T, Neglect> TransmuteFrom<T, Neglect> for T+where+    Neglect: UnsafeTransmuteOptions+{}++/// A transmutation is *stable* if...+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```+This [minimal implementation][minimal-impl] is sufficient for convincing the compiler to accept basic stability declarations, such as those of Rust's primitive types. It is *insufficient* for making the compiler accept transmutations between *different* types (and, consequently, complex stability declarations). Implementers should use this as a starting point.++### Listing for Initial, Minimal Implementation+[minimal-impl]: #Listing-for-Initial-Minimal-Implementation+**[This module listing provides the minimal-viable implementation of this RFC (excepting the automatic derives).](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=25a83d8d8e33e9f631a64b53e3c39844)** This listing is also the **canonical specification** of this RFC's public API surface.++### Towards an Initial, Smart Implementation++To support transmutations between different types, implementers of this RFC should begin by defining a `transmute_from` lang item to annotate libcore's definition of `TransmuteFrom`. Whether `TransmuteFrom` is implemented for a given type and parameters shall be determined within the implementation of the type system (à la [`Sized`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_sized) and [`Freeze`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_freeze)).++This initial smart implementation may be made simpler by:+  - *not* supporting enums+  - *not* supporting unions+  - *not* supporting `Neglect` parameters besides `()` and `NeglectStability`+  - simplifying constructability++#### Simplifying Constructability+The safety property of constructability defined in the guidance-level examplation of this RFC describes a platonic ideal of the property. ++However, we recognize that this definition poses implementation challenges: In our definition of constructability, answering the question of whether a struct or enum variant is constructible depends on *where* that question is being asked. Consequently, answering whether a given type `Src` is `TransmutableInto` a given type `Dst` will depend on *where* that question is posed.++We recommend adopting a simplified definition of *constructability*: a type is *constructible* if its fields are marked `pub`, and those fields are constructible. With this definition, answering the question of whether a type is constructible does *not* depend on where the question is asked: we do not examine the visibility of the involved types.++Unfortunately, with no other actions taken, this simplified definition comes...++##### ...at the Cost of Safety+This definition is *usually* sufficient for ensuring safety: it is *generally* an error to expose a private type in a public type signature. However, these errors may be circumvented using the public-type-in-private-module trick:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+With this simplified definition of constructability, it is possible for a third-party to define a *safe* constructor of `NonEmptySlice` that produces a value which is *unsafe* to use:+```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,+{+    src.transmute_into()+}++evil_constructor(0u128).first() // muahaha!+```++The above code is "safe" because our simplified definition of constructability fails to recognize this pattern of encapsulation, and because `NeglectStability` is a `SafeTransmutationOption`.++The intent of `NeglectStability` is to permit the safe transmutation of types that predate the stabilization of the stability declaration traits. It also provides a convenient escape-hatch for type authors to neglect the stability of transmutations of their *own* types, without sacrificing safety. `NeglectStability` is a `SafeTransmutationOption` because, in principle, neglecting stability does not diminish safety. Our simplified definition of constructability violates this principle.++By temporarily sacrificing these goals, we may preserve safety solely...++##### ...at the Cost of `NeglectStability`+We may preserve safety by demoting `NeglectStability` to `UnsafeTransmutationOption`-status.++In doing so, a third-party is forced to resort to an `unsafe` transmutation to construct `NonEmptySlice`; e.g.:++```rust+pub evil_constructor<T>(src: T) -> NonEmptySlice<u8>+where+    T: TransmuteInto<NonEmptySlice<u8>, NeglectStability>,+{+    // unsafe because we `NeglectStability`+    unsafe { src.unsafe_transmute_into() }+}+```++Demoting `NeglectStability` to unsafe-status does not stop type authors from opting-in to stable (and thus safe) transmutations; e.g., with `derive(PromiseTransmutableFrom)`:+```rust+pub mod crate_a {++    #[derive(PromiseTransmutableFrom)]+    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[derive(PromiseTransmutableFrom)]+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}
pub mod crate_a {

    #[derive(PromiseTransmutableFrom)]
    #[repr(C)]
    pub struct NonEmptySlice<'a, T>(pub private::NonEmptySliceInner<'a, T>);

    impl<'a, T> NonEmptySlice<'a, T> {
        pub fn from_array<const N: usize>(arr: &'a [T; N], len: usize) -> Self {
            assert!(len <= N && len > 0);
            Self(
                private::NonEmptySliceInner {
                    data: arr as *const T,
                    len,
                    lifetime: core::marker::PhantomData,
                }
            )
        }

        pub fn first(&self) -> &'a T {
            unsafe { &*self.0.data }
        }
    }

    // introduce a private module to avoid `private_in_public` error (E0446):
    pub(crate) mod private {
        #[derive(PromiseTransmutableFrom)]
        #[repr(C)]
        pub struct NonEmptySliceInner<'a, T> {
            pub data: *const T,
            pub len: usize,
            pub lifetime: core::marker::PhantomData<&'a ()>,
        }
    }

}
jswrenn

comment created time in an hour

Pull request review commentrust-lang/project-safe-transmute

Safe Transmute RFC

+# Safe Transmute RFC++- Feature Name: `safe_transmute`+- Start Date: (fill me in with today's date, YYYY-MM-DD)+- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)+- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)+++# Summary+[summary]: #summary++We propose traits, namely `TransmuteInto` and `TransmuteFrom`, that are implemented *automatically* for combinations of types that may be safely transmuted. In other words, this RFC makes safe transmutation *as easy as 1..., 2..., `repr(C)`!*+```rust+use core::transmute::{+    TransmuteInto,+    stability::{PromiseTransmutableInto, PromiseTransmutableFrom},+};++#[derive(PromiseTransmutableInto, PromiseTransmutableFrom)]+#[repr(C)]+pub struct Foo(pub u8, pub u16);+//                   ^ there's a padding byte here++// Transmute fearlessly!+let _ : Foo = 64u32.transmute_into(); // Alchemy Achieved!++let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!++// error[E0277]: the trait bound `u32: TransmuteFrom<foo::Foo, _>` is not satisfied+//   --> src/demo.rs:14:27+//    |+// 14 | let _ : u32 = Foo(16, 12).transmute_into(); // Compile Error!+//    |                           ^^^^^^^^^^^^^^ the trait `TransmuteFrom<foo::Foo, _>` is not implemented for `u32`+//    |+//   = note: required because of the requirements on the impl of `TransmuteInto<u32, _>` for `foo::Foo`+```+++# Motivation+[motivation]: #motivation++We foresee a range of practical consequences of fulfilling these goals, including [making unsafe Rust safer](#making-unsafe-rust-safer), providing [safer initialization primitives](#safer-initialization-primitives), and [generic atomics](#atomict). We explore these use-cases, and more, in this section.++A *comprehensive* approach to safe transmutation provides benefits beyond the mere act of transmutation; namely:+ - [authoritatively codifies language layout guarantees](#codifying-language-layout-guarantees)+ - [allows crate authors to codify their types' layout stability guarantees](#expressing-library-layout-guarantees)+ - [allows crate authors to codify their abstractions' layout requirements](#expressing-layout-requirements)++## Codifying Language Layout Guarantees+Documentation of Rust's layout guarantees for a type are often spread across countless issues, pull requests, RFCs and various official resources. It can be very difficult to get a straight answer. When transmutation is involved, users must reason about the *combined* layout properties of the source and destination types.++This RFC proposes mechanisms that programmers will use to confidently answer such questions—by checking whether the `TransmuteFrom` and `TransmuteInto` traits are implemented, or (equivalently) by checking whether the `can_transmute` predicate (a `const fn`) is satisfied.++## Expressing Library Layout Guarantees+There is no canonical way for crate authors to declare the SemVer layout guarantees of their types. Crate authors currently must state their layout guarantees using prose in their documentation. In contrast to structural stability (e.g., the declared visibility of fields), layout stability is expressed extra-linguistically.++This isn't satisfactory: guarantees expressed in prose outside of the Rust programming language are guarantees that cannot be reasoned about *inside* the language. Whereas `rustc` can dutifully deny programmers access to private fields, it is unable to prevent programmers from making unfounded expectations of types' in-memory layouts.++This RFC proposes simple-but-powerful [mechanisms][stability] for declaring layout stability guarantees.++## Expressing Layout Requirements+Similarly, there is no canonical way for crate authors to declare the layout requirements of generic abstractions over types that have certain layout properties. ++For instance, a common bit-packing technique involves abusing the relationship between allocations and alignment. If a type is aligned to 2<sup>n</sup>, then the *n* least significant bits of pointers to that type will equal `0`. These known-zero bits can be packed with data. Since alignment cannot be currently reasoned about at the type-level, it's currently impossible to bound instantiations of a generic parameter based on minimum alignment.++The mechanisms proposed by the RFC enable this. We return to this example near the end of the RFC, [here][case-study-alignment].++## Making Unsafe Rust Safer+[motivation-safer-unsafe]: #Making-Unsafe-Rust-Safer+In the blog post [*Unsafe Zig is Safer than Unsafe Rust*](https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html), Andrew Kelley asks readers to consider the following Rust code:++```rust+struct Foo {+    a: i32,+    b: i32,+}++fn main() {+    unsafe {+        let mut array: [u8; 1024] = [1; 1024];+        let foo = mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);+        foo.a += 1;+    }+}+```+This pattern, Kelley notes, is common when interacting with operating system APIs.++This rust program compiles, but quietly introduces undefined behavior. `Foo` requires stricter in-memory alignment than `u8`. The equivalent code in Zig produces a compiler error for this reason and requires modification.++And that's not all: Kelley misses that the very layout of `Foo` itself is undefined⁠—it must be annotated with `#[repr(C)]`!++Kelley concludes:+> In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use `@alignCast`. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.++This situation is frustrating. Like `zig`, `rustc` *knows* the layout of `Foo`, it *knows* that the layout of `Foo` is unspecified because it lacks the `#[repr(C)]` attribute, and it *knows* the minimum alignment requirements of `Foo` are stricter than that of `u8`. Why doesn't it also help us avoid UB?++This RFC proposes mechanisms that use this information to enable safer transmutation. We revisit Kelley's motivating example with these proposed mechanisms near the end of this RFC, [*here*][case-study-safer-unsafe].++## Efficient Network Parsing+***TODO: Josh?***++## Safer Initialization Primitives+The initialization primitives `mem::zeroed<T>` and `mem::uninitialized<T>` are `unsafe` because they may be used to initialize types for which zeroed or uninitialized memory are *not* valid bit-patterns. The `mem::zeroed` function recently gained a dynamically-enforced validity check, but this safety measure isn't wholly satisfactory: the validity properties of `T` are statically known, but the check is dynamic.++This RFC proposes mechanisms that would allow these functions to explicitly bound their generic parameter `T` based on its validity properties. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-safe-initialization].++## Including Structured Data+[motivation-including-data]: #Including-Structured-Data++[`include_bytes`]: https://doc.rust-lang.org/core/macro.include_bytes.html++The [`include_bytes`] macro statically includes the contents of another file as a byte array, producing a value of type `&'static [u8; N]`. Often, these bytes correspond to structured data and a `transmute` must be used to deserialize the bytes into useful form; e.g.:+```rust+pub fn recognize(input: &Matrix<f64, U1, U784>) -> usize+{+    static RAW_WEIGHT : &'static [u8; 62_720] = include_bytes!("/weight.bin");++    static RAW_BIAS : &'static [u8; 80] = include_bytes!("/bias.bin");++    let WEIGHT: &Matrix<f64, U784, U10> = unsafe{ mem::transmute(RAW_WEIGHT) };++    let BIAS: &Matrix<f64, U1, U10> = unsafe{ mem::transmute(RAW_BIAS) };++    network::recognize(input, WEIGHT, BIAS)+}+```++This RFC proposes mechanisms that would eliminate `unsafe` in this example. We revisit this motivating use-case with our proposed mechanisms near the end of this RFC, [*here*][future-possibility-include_data].+++## SIMD+***TODO:*** https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071+++## `Atomic<T>`+Rust defines a dozen `Atomic*` types (`AtomicBool`, `AtomicI8`, `AtomicI16`, `AtomicI32`, `AtomicI64`, `AtomicIsize`, `AtomicPtr`, `AtomicU8`, `AtomicU16`, `AtomicU32`, `AtomicU64`, and `AtomicUsize`).++This set is large—a distinct `Atomic*` type is required for each primitive type—but incomplete. If one wants atomic operations on their own type, they must define a wrapper around an existing `Atomic*` type of appropriate size and validity, then transmute at API boundaries; e.g.:++```rust+#[repr(u8)]+enum Trilean {+    False,+    True,+    Unknown,+}++#[repr(transparent)]+pub AtomicTrilean(AtomicU8);++impl AtomicTrilean {++    pub const fn new(v: Trilean) -> Self {+        AtomicTrilean(+          AtomicU8::new(+            unsafe { mem::transmute(v) }+          ))+    }++    ...+}+```++The mechanisms proposed by this RFC would eliminate this pattern, permitting truly generic `Atomic` types. We revisit this motivating use-case with these proposed mechanisms near the end of this RFC, [*here*][future-possibility-generic-atomics].++# Guide-level explanation+[guide-level-explanation]: #guide-level-explanation++## Terminology & Concepts++### 📖 Transmutation+**Transmutation** is the act of reinterpreting the bytes corresponding to a value of one type as if they corresponded to a different type.++### 📖 Soundness+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not compiler undefined behavior.++### 📖 Safety+A sound transmutation is ***safe*** if *using* the transmuted value cannot violate memory safety.++### 📖 Stability+A safe transmutation is ***stable*** if the authors of the source type and destination types have indicated that the layouts of those types is part of their libraries' stability guarantees.++## Concepts in Depth++***Disclaimer:** While the high-level definitions of transmutation soundness, safety and stability are a core component of this RFC, the detailed rules and examples in this section are **not**. We expect that the initial implementation of `TransmuteFrom` may initially be considerably less sophisticated than the examples in this section (and thus forbid valid transmutations). Nonetheless, this section explores nuanced cases of transmutation soundness and safety to demonstrate that the APIs we propose can grow to handle that nuance.*+++### 📖 When is a transmutation sound?+[sound transmutation]: #When-is-a-transmutation-sound?+A transmutation is ***sound*** if the mere act of transmuting a value from one type to another is not undefined behavior.++#### Well-Defined Representation+[`u8`]: core::u8+[`f32`]: core::f32++Transmutation is *always unsound* if it occurs between types with unspecified representations.++Most of Rust's primitive types have specified representations. That is, the precise layout characteristics of [`u8`], [`f32`] is a documented and guaranteed aspect of those types.++In contrast, most `struct` and `enum` types defined without an explicit `#[repr(C)]` attribute do ***not*** have well-specified layout characteristics.++To ensure that types you've define are soundly transmutable, you almost always (with very few exceptions) must mark them with the `#[repr(C)]` attribute.++#### Requirements on Owned Values+[transmute-owned]: #transmuting-owned-values++Transmutations involving owned values must adhere to two rules to be sound. They must:+ * [preserve or broaden the bit validity][owned-validity], and+ * [preserve or shrink the size][owned-size].++##### Preserve or Broaden Bit Validity+[owned-validity]: #Preserve-or-Broaden-Bit-Validity+[`NonZeroU8`]: https://doc.rust-lang.org/beta/core/num/struct.NonZeroU8.html++The bits of any valid instance of the source type must be a bit-valid instance of the destination type.++For example, we are permitted to transmute a `Bool` into a [`u8`]:+```rust+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(u8)]+enum Bool {+    True = 1,+    False = 0,+}++let _ : u8 = Bool::True.transmute_into();+let _ : u8 = Bool::False.transmute_into();+```+<sup>+(Note: <code>#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]</code> annotation connotes that <i>all</i> aspects of <code>Bool</code>'s layout are part of its <a href="#When-is-a-transmutation-stable?">library stability guarantee</a>.)+</sup>++...because all possible instances of `Bool` are also valid instances of [`u8`]. However, transmuting a [`u8`] into a `Bool` is forbidden:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Bool = u8::default().transmute_into(); // Compile Error!+```+...because not all instances of [`u8`] are valid instances of `Bool`.++Another example: While laying out certain types, Rust may insert padding bytes between the layouts of fields. In the below example `Padded` has two padding bytes, while `Packed` has none:+```rust+#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Padded(pub u8, pub u16, pub u8);++#[repr(C)]+#[derive(Default, PromiseTransmutableFrom, PromiseTransmutableInto)]+struct Packed(pub u16, pub u16, pub u16);++assert_eq!(mem::size_of::<Packed>(), mem::size_of::<Padded>());+```++We may safely transmute from `Packed` to `Padded`:+```rust+let _ : Padded = Packed::default().transmute_into();+```+...but not from `Padded` to `Packed`:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : Packed = Padded::default().transmute_into(); // Compile Error!+```+...because doing so would expose two uninitialized padding bytes in `Padded` as if they were initialized bytes in `Packed`.++##### Preserve or Shrink Size+[owned-size]: #Preserve-or-Shrink-Size++It's completely sound to transmute into a type with fewer bytes than the source type; e.g.:+```rust+let _ : [u8; 16] = [0u8; 32]::default().transmute_into();+```+This transmute truncates away the final sixteen bytes of the `[u8; 32]` value.++A value may ***not*** be transmuted into a type of greater size:+```rust+/* ⚠️ This example intentionally does not compile. */+let _ : [u8; 32] = [0u8; 16]::default().transmute_into(); // Compile Error!+```++#### Requirements on References+[transmute-references]: #transmuting-references++The [restrictions above that apply to transmuting owned values][transmute-owned] also apply to transmuting references. However, references carry a few additional restrictions.++A [sound transmutation] must:+ - [preserve or relax alignment][reference-alignment],+ - [preserve or shrink lifetimes][reference-lifetimes],+ - [preserve or shrink uniqueness][reference-mutability], and+ - and if the destination type is a mutate-able reference, [preserve validity][reference-validity].++##### Preserve or Relax Alignment+[reference-alignment]: #Preserve-or-Relax-Alignment++Unaligned loads are undefined behavior. You may transmute a reference into reference of more relaxed alignment:+```rust+let _: &[u8; 0] = (&[0u16; 0]).transmute_into();+```++However, you may **not** transmute a reference into a reference of more-restrictive alignment:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &[u16; 0] = (&[0u8; 0]).transmute_into(); // Compile Error! +```++##### Preserve or Shrink Lifetimes+[reference-lifetimes]: #Preserve-or-Shrink-Lifetimes++You may transmute a reference into a reference of lesser lifetime:+```rust+fn shrink<'a>() -> &'a u8 {+    static long : &'static u8 = &16;+    long.transmute_into()+}+```++However, you may **not** transmute a reference into a reference of greater lifetime:+```rust+/* ⚠️ This example intentionally does not compile. */+fn extend<'a>(short: &'a u8) -> &'static u8 {+    short.transmute_into() // Compile Error!+}+```++##### Preserve or Shrink Uniqueness+[reference-mutability]: #Preserve-or-Shrink-Uniqueness++You may preserve or decrease the uniqueness of a reference through transmutation:+```rust+let _: &u8 = (&42u8).transmute_into();+let _: &u8 = (&mut 42u8).transmute_into();+```++However, you may **not** transmute a shared reference into a unique reference:+```rust+/* ⚠️ This example intentionally does not compile. */+let _: &mut u8 = (&42u8).transmute_into(); // Compile Error!+```++##### Mutate-able References Must Preserve Validity+[reference-validity]: #Mutate-able-References-Must-Preserve-Validity++A mutate-able reference is:+- all unique (i.e., `&mut T`) references+- all shared (i.e., `&T`) references whose referent type contain any bytes produced by the contents of `UnsafeCell`.++Unlike transmutations of owned values, the transmutation of a mutate-able reference may also not expand the bit-validity of the referenced type. For instance:+```rust+/* ⚠️ This example intentionally does not compile. */+let mut x = NonZeroU8::new(42).unwrap();+{+    let y : &mut u8 = (&mut x).transmute_into(); // Compile Error!+    *y = 0;+}++let z : NonZeroU8 = x;+```+If this example did not produce a compile error, the value of `z` would not be a bit-valid instance of its type, [`NonZeroU8`].++++### 📖 When is a transmutation safe?+A sound transmutation is ***safe*** if *using* the transmuted value safely cannot violate memory safety. Whereas soundness solely concerns the act of transmutation, *safety* is concerned with what might happen with a value *after* transmutation occurs.++#### Implicit Constructability+A struct or enum variant is *fully implicitly constructable* at a given location only if, at that location, that type can be instantiated via its *implicit constructor*, and its fields are also *implicitly constructable*.++The *implicit constructor* of a struct or enum variant is the constructor Rust creates implicitly from its definition; e.g.:+```rust+struct Point<T> {+    x: T,+    y: T,+}++let p = Point { x: 4, y: 2 };+     // ^^^^^^^^^^^^^^^^^^^^ An instance of `Point` is created here, via its implicit constructor.+```++Limiting implicit constructability is the fundamental mechanism with which type authors build safe abstractions for `unsafe` code, whose soundness is dependent on preserving invariants on fields. Usually, this takes the form of restricting the visibility of fields. For instance, consider the type `NonEmptySlice`, which enforces a validity constraint on its fields via its constructor:++```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T> {+        data: *const T,+        len: usize,+    }++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N);+            assert!(len > 0);+            Self {+                data: arr as *const T,+                len,+            }+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.data }+        }+    }++}+```+It is sound for `first` to be a *safe* method is because the `from_array` constructor ensures that `data` is safe to dereference, and because `from_array` is the *only* way to safely initialize `NonEmptySlice` outside of `crate_a` (note that `NonEmptySlice`'s fields are *not* `pub`). As a rule: any field that is not marked `pub` should be assumed to be private *because* it is subject to safety invariants.++Unfortunately, field visibility modifiers are not a surefire indicator of whether a type is *fully* implicitly constructable. A type author may restrict the implicit constructability of a type even in situations where all fields of that type (*and all fields of those fields*) are `pub`; consider:+```rust+pub mod crate_a {++    #[repr(C)]+    pub struct NonEmptySlice<T>(pub private::NonEmptySliceInner<T>);++    impl<T> NonEmptySlice<T> {+        pub fn from_array<const N: usize>(arr: &[T; N], len: usize) -> Self {+            assert!(len <= N && len > 0);+            Self(+                private::NonEmptySliceInner {+                    data: arr as *const T,+                    len,+                }+            )+        }++        pub fn first(&self) -> &T {+            unsafe { &*self.0.data }+        }+    }++    // introduce a private module to avoid `private_in_public` error (E0446):+    pub(crate) mod private {+        #[repr(C)]+        pub struct NonEmptySliceInner<T> {+            pub data: *const T,+            pub len: usize,+        }+    }++}+```+In the above example, the definitions of both `NonEmptySlice` and its field `NonEmptySliceInner` are marked `pub`, and all fields of these types are marked `pub`. However, `NonEmptySlice` is *not* fully implicitly constructible outside of `crate_a`, because the module containing `NonEmptySliceInner` is not visibile outside of `crate_a`.++#### Constructability and Transmutation+Transmutation supplies a mechanism for constructing instances of a type *without* invoking its implicit constructor, nor any constructors defined by the type's author.++In the previous examples, it would be *unsafe* to transmute `0u128` into `NonEmptySlice` outside `crate_a`, because subsequent *safe* use of that value (namely, calling `first`) would violate memory safety. (However, it's completely safe to transmute `NonEmptySlice` into a `u128`.)++For transmutations where the destination type involves mutate-able references, the constructability of the source type is also relevant. Consider:+```rust+/* ⚠️ This example intentionally does not compile. */+let arr = [0u8, 1u8, 2u8];+let mut x = NonEmptySlice::from_array(&arr, 2);+{+    let y : &mut u128 = (&mut x).transmute_into(); // Compile Error!+    *y = 0u128;+}++let z : NonEmptySlice<u8> = x;+```+If this example did not produce a compile error, the value of `z` would not be a safe instance of its type, `NonEmptySlice`, because `z.first()` would dereference a null pointer.++### 📖 When is a transmutation stable?+[stability]: #When-is-a-transmutation-stable++Since the soundness and safety of a transmutation is affected by the layouts of the source and destination types, changes to those types' layouts may cause code which previously compiled to produce errors. In other words, transmutation causes a type's layout to become part of that type's API for the purposes of SemVer stability.++The question is, then: *how can the author of a type reason about transmutations they did not write, from-or-to types they did not write?* We address this problem by introducing two traits which both allow an author to opt-in to stability guarantees for their types, and allow third-parties to reason at compile-time about what guarantees are provided for such types.++#### `PromiseTransmutableFrom` and `PromiseTransmutableInto`++You may declare the stability guarantees of your type by implementing one or both of two traits:+```rust+pub trait PromiseTransmutableFrom+{+    type Archetype+        : TransmuteInto<Self, NeglectStability>+        + PromiseTransmutableFrom;+}++pub trait PromiseTransmutableInto+{+    type Archetype+        : TransmuteFrom<Self, NeglectStability>+        + PromiseTransmutableInto;+}+```++To implement each of these traits, you must specify an `Archetype`. An `Archetype` is a type whose layout exemplifies the extremities of your stability promise (i.e., the least/most constrained type for which it is valid to transmute your type into/from).++By implementing `PromiseTransmutableFrom`, you promise that your type is guaranteed to be safely transmutable *from* `PromiseTransmutableFrom::Archetype`. Conversely, by implementing `PromiseTransmutableInto`, you promise that your type is guaranteed to be safely transmutable *into* `PromiseTransmutableInto::Archetype`.++You are free to change the layout of your type however you like between minor crate versions so long as that change does not violates these promises. These two traits are capable of expressing simple and complex stability guarantees.++#### Stability & Transmutation+A `Src` type is *stably* transmutable into a `Dst` type *only if* `<Src as PromiseTransmutableInto>::Archetype` is transmutable, stability notwithstanding, into `<Dst as PromiseTransmutableFrom>::Archetype`; formally:+```rust+unsafe impl<Src, Dst> TransmuteFrom<Src> for Dst+where+    Src: PromiseTransmutableInto,+    Dst: PromiseTransmutableFrom,+    <Dst as PromiseTransmutableFrom>::Archetype:+        TransmuteFrom<+            <Src as PromiseTransmutableInto>::Archetype,+            NeglectStability+        >+{}+```++Why is this the case?++The type `<Src as PromiseTransmutableInto>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Src` that could affect its use as a source type in transmutations. Conversely, `<Dst as PromiseTransmutableFrom>::Archetype` exemplifies the furthest extreme of non-breaking changes that could be made to the layout of `Dst` that could affect its use as a destination type in transmutations. If a transmutation between these extremities is valid, then so is `Src: TransmuteInto<Dst>`.++#### Common Use-Case: Promising a Fixed Layout+To promise that type's layout is completely fixed, simply `derive` the `PromiseTransmutableFrom` and `PromiseTransmutableInto` traits:+```rust+#[derive(PromiseTransmutableFrom, PromiseTransmutableInto)]+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);+```+This expands to:+```rust+#[repr(C)]+pub struct Foo(pub Bar, pub Baz);++/// Generated `PromiseTransmutableFrom` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableFrom;++    #[repr(C)]+    pub struct TransmutableFromArchetype(+        pub <Bar as PromiseTransmutableFrom>::Archetype,+        pub <Baz as PromiseTransmutableFrom>::Archetype,+    );++    impl PromiseTransmutableFrom for Foo {+        type Archetype = TransmutableFromArchetype;+    }+};++/// Generated `PromiseTransmutableInto` for `Foo`+const _: () = {+    use core::transmute::stability::PromiseTransmutableInto;++    #[repr(C)]+    pub struct TransmutableIntoArchetype(+        pub <Bar as PromiseTransmutableInto>::Archetype,+        pub <Baz as PromiseTransmutableInto>::Archetype,+    );++    impl PromiseTransmutableInto for Foo {+        type Archetype = TransmutableIntoArchetype;+    }+};+```+++#### Uncommon Use Case: Complex Stability Guarantees++If you are *most people* and want to declare your types as layout-stable, you should follow the advice in the previous sections. In doing so, you declare that you will *not* modify the layout of your type in virtually any way, except as a breaking change. If your type's fields have simple stability guarantees, this effects the strongest possible declaration of stability: it declares that *all* transmutations that are safe are *also* stable.++However, if you anticipate that you will need to make changes to your type's layouts in a non-breaking way, you can craft uninformative archetypes that effect *weaker* promises of stability. With uninformative archetypes, only a *subset* of transmutations that are safe are also considered stable. For instance, you may use `PromiseTransmutableInto` to specify an lower-bound for the size of a type, but *not* make promises about its bit-validity:++```rust+#[repr(C)] pub struct Foo(u8, u8, u8, u8, u8, u8);++#[repr(C)]+struct FooArchetype(pub [MaybeUninit<u8>; 5]);++impl PromiseTransmutableInto for Foo {<