From ba60af3bbdde527c7944e67218bff4c6b283ad3b Mon Sep 17 00:00:00 2001
From: Chris Krycho <chris@chriskrycho.com>
Date: Mon, 21 Nov 2016 20:19:52 -0500
Subject: [PATCH 1/4] Document RFC 1623: static lifetime elision.

---
 src/doc/reference.md | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/doc/reference.md b/src/doc/reference.md
index 9898c31282c34..713e6f1ab99eb 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1271,7 +1271,8 @@ guaranteed to refer to the same memory address.
 
 Constant values must not have destructors, and otherwise permit most forms of
 data. Constants may refer to the address of other constants, in which case the
-address will have the `static` lifetime. The compiler is, however, still at
+address will have the `static` lifetime. (See below on [static lifetime
+elision](#static-lifetime-elision).) The compiler is, however, still at 
 liberty to translate the constant many times, so the address referred to may not
 be stable.
 
@@ -1279,7 +1280,7 @@ Constants must be explicitly typed. The type may be `bool`, `char`, a number, or
 a type derived from those primitive types. The derived types are references with
 the `static` lifetime, fixed-size arrays, tuples, enum variants, and structs.
 
-```
+```rust
 const BIT1: u32 = 1 << 0;
 const BIT2: u32 = 1 << 1;
 
@@ -1331,7 +1332,7 @@ running in the same process.
 Mutable statics are still very useful, however. They can be used with C
 libraries and can also be bound from C libraries (in an `extern` block).
 
-```
+```rust
 # fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 }
 
 static mut LEVELS: u32 = 0;
@@ -1355,6 +1356,31 @@ unsafe fn bump_levels_unsafe2() -> u32 {
 Mutable statics have the same restrictions as normal statics, except that the
 type of the value is not required to ascribe to `Sync`.
 
+#### `'static` lifetime elision
+
+Both constant and static declarations of reference types have *implicit*
+`'static` lifetimes unless an explicit lifetime is specified. As such, the
+constant declarations involving `'static` above may be written without the
+lifetimes. Returning to our previous example:
+
+```rust
+const BIT1: u32 = 1 << 0;
+const BIT2: u32 = 1 << 1;
+
+const BITS: [u32; 2] = [BIT1, BIT2];
+const STRING: &str = "bitstring";
+
+struct BitsNStrings<'a> {
+    mybits: [u32; 2],
+    mystring: &'a str,
+}
+
+const BITS_N_STRINGS: BitsNStrings = BitsNStrings {
+    mybits: BITS,
+    mystring: STRING,
+};
+```
+
 ### Traits
 
 A _trait_ describes an abstract interface that types can
@@ -2458,9 +2484,6 @@ The currently implemented features of the reference compiler are:
             into a Rust program. This capability, especially the signature for the
             annotated function, is subject to change.
 
-* `static_in_const` - Enables lifetime elision with a `'static` default for
-                      `const` and `static` item declarations.
-
 * `thread_local` - The usage of the `#[thread_local]` attribute is experimental
                    and should be seen as unstable. This attribute is used to
                    declare a `static` as being unique per-thread leveraging

From e8cb83a8237d79f4c8523f4b8df5e73688cfb8bb Mon Sep 17 00:00:00 2001
From: Chris Krycho <chris@chriskrycho.com>
Date: Sat, 28 Jan 2017 09:42:32 -0500
Subject: [PATCH 2/4] Add feature flag to reference docs for RFC 1623.

---
 src/doc/reference.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/doc/reference.md b/src/doc/reference.md
index 713e6f1ab99eb..c6fc2ea40590c 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1356,7 +1356,7 @@ unsafe fn bump_levels_unsafe2() -> u32 {
 Mutable statics have the same restrictions as normal statics, except that the
 type of the value is not required to ascribe to `Sync`.
 
-#### `'static` lifetime elision
+#### `'static` lifetime elision [unstable]
 
 Both constant and static declarations of reference types have *implicit*
 `'static` lifetimes unless an explicit lifetime is specified. As such, the
@@ -1364,6 +1364,7 @@ constant declarations involving `'static` above may be written without the
 lifetimes. Returning to our previous example:
 
 ```rust
+#[feature(static_in_const)]
 const BIT1: u32 = 1 << 0;
 const BIT2: u32 = 1 << 1;
 

From 3f0ca5578051f67046abb04d053118439b162f87 Mon Sep 17 00:00:00 2001
From: Chris Krycho <chris@chriskrycho.com>
Date: Sat, 28 Jan 2017 12:45:54 -0500
Subject: [PATCH 3/4] Change placement of `[Unstable]` marker in RFC 1623 docs.

---
 src/doc/reference.md | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/doc/reference.md b/src/doc/reference.md
index c6fc2ea40590c..dd3ccb82211f5 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1356,12 +1356,12 @@ unsafe fn bump_levels_unsafe2() -> u32 {
 Mutable statics have the same restrictions as normal statics, except that the
 type of the value is not required to ascribe to `Sync`.
 
-#### `'static` lifetime elision [unstable]
+#### `'static` lifetime elision
 
-Both constant and static declarations of reference types have *implicit*
-`'static` lifetimes unless an explicit lifetime is specified. As such, the
-constant declarations involving `'static` above may be written without the
-lifetimes. Returning to our previous example:
+[Unstable] Both constant and static declarations of reference types have
+*implicit* `'static` lifetimes unless an explicit lifetime is specified. As
+such, the constant declarations involving `'static` above may be written
+without the lifetimes. Returning to our previous example:
 
 ```rust
 #[feature(static_in_const)]

From 4096dd684c5f11dea5bd231a97adfb7205a82213 Mon Sep 17 00:00:00 2001
From: Chris Krycho <chris@chriskrycho.com>
Date: Wed, 8 Feb 2017 14:30:31 -0500
Subject: [PATCH 4/4] Add more examples, get everything passing at last.

---
 src/doc/reference.md | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/doc/reference.md b/src/doc/reference.md
index dd3ccb82211f5..4910313af9303 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1271,10 +1271,12 @@ guaranteed to refer to the same memory address.
 
 Constant values must not have destructors, and otherwise permit most forms of
 data. Constants may refer to the address of other constants, in which case the
-address will have the `static` lifetime. (See below on [static lifetime
-elision](#static-lifetime-elision).) The compiler is, however, still at 
-liberty to translate the constant many times, so the address referred to may not
-be stable.
+address will have elided lifetimes where applicable, otherwise – in most cases –
+defaulting to the `static` lifetime. (See below on [static lifetime elision].)
+The compiler is, however, still at liberty to translate the constant many times,
+so the address referred to may not be stable.
+
+[static lifetime elision]: #static-lifetime-elision
 
 Constants must be explicitly typed. The type may be `bool`, `char`, a number, or
 a type derived from those primitive types. The derived types are references with
@@ -1298,6 +1300,8 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
 };
 ```
 
+
+
 ### Static items
 
 A *static item* is similar to a *constant*, except that it represents a precise
@@ -1364,7 +1368,7 @@ such, the constant declarations involving `'static` above may be written
 without the lifetimes. Returning to our previous example:
 
 ```rust
-#[feature(static_in_const)]
+# #![feature(static_in_const)]
 const BIT1: u32 = 1 << 0;
 const BIT2: u32 = 1 << 1;
 
@@ -1382,6 +1386,27 @@ const BITS_N_STRINGS: BitsNStrings = BitsNStrings {
 };
 ```
 
+Note that if the `static` or `const` items include function or closure
+references, which themselves include references, the compiler will first try the
+standard elision rules ([see discussion in the nomicon][elision-nomicon]). If it
+is unable to resolve the lifetimes by its usual rules, it will default to using
+the `'static` lifetime. By way of example:
+
+[elision-nomicon]: https://doc.rust-lang.org/nomicon/lifetime-elision.html
+
+```rust,ignore
+// Resolved as `fn<'a>(&'a str) -> &'a str`.
+const RESOLVED_SINGLE: fn(&str) -> &str = ..
+
+// Resolved as `Fn<'a, 'b, 'c>(&'a Foo, &'b Bar, &'c Baz) -> usize`.
+const RESOLVED_MULTIPLE: Fn(&Foo, &Bar, &Baz) -> usize = ..
+
+// There is insufficient information to bound the return reference lifetime
+// relative to the argument lifetimes, so the signature is resolved as
+// `Fn(&'static Foo, &'static Bar) -> &'static Baz`.
+const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
+```
+
 ### Traits
 
 A _trait_ describes an abstract interface that types can
@@ -2079,7 +2104,9 @@ macro scope.
 
 ### Miscellaneous attributes
 
-- `deprecated` - mark the item as deprecated; the full attribute is `#[deprecated(since = "crate version", note = "...")`, where both arguments are optional.
+- `deprecated` - mark the item as deprecated; the full attribute is 
+  `#[deprecated(since = "crate version", note = "...")`, where both arguments 
+  are optional.
 - `export_name` - on statics and functions, this determines the name of the
   exported symbol.
 - `link_section` - on statics and functions, this specifies the section of the