From 51b655e58f334ba96d8bfb7057f7ffa3d4c40667 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 26 Dec 2016 15:19:27 -0800
Subject: [PATCH 01/15] std: Remove unused objects from compiler-builtins

We don't actually use trampoline_setup.c and all the `*tf3` business
seems related to f80/f128 business. Specifically this'll fix some
warnings showing up during builds on OSX.
---
 src/libcompiler_builtins/build.rs | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs
index 44aa08e245873..6a766fc02df3e 100644
--- a/src/libcompiler_builtins/build.rs
+++ b/src/libcompiler_builtins/build.rs
@@ -192,14 +192,12 @@ fn main() {
 
     if !target.contains("ios") {
         sources.extend(&["absvti2.c",
-                         "addtf3.c",
                          "addvti3.c",
                          "ashlti3.c",
                          "ashrti3.c",
                          "clzti2.c",
                          "cmpti2.c",
                          "ctzti2.c",
-                         "divtf3.c",
                          "divti3.c",
                          "ffsti2.c",
                          "fixdfti.c",
@@ -216,17 +214,13 @@ fn main() {
                          "floatuntixf.c",
                          "lshrti3.c",
                          "modti3.c",
-                         "multf3.c",
                          "multi3.c",
                          "mulvti3.c",
                          "negti2.c",
                          "negvti2.c",
                          "parityti2.c",
                          "popcountti2.c",
-                         "powitf2.c",
-                         "subtf3.c",
                          "subvti3.c",
-                         "trampoline_setup.c",
                          "ucmpti2.c",
                          "udivmodti4.c",
                          "udivti3.c",

From ca9b07bbc974414e2b9055c5e50e38a1973401d2 Mon Sep 17 00:00:00 2001
From: Andrew Paseltiner <apaseltiner@gmail.com>
Date: Wed, 28 Dec 2016 17:47:10 -0500
Subject: [PATCH 02/15] Replace uses of `#[unsafe_destructor_blind_to_params]`
 with `#[may_dangle]`

CC #34761
---
 src/liballoc/arc.rs                  | 3 +--
 src/liballoc/lib.rs                  | 3 ++-
 src/liballoc/raw_vec.rs              | 3 +--
 src/liballoc/rc.rs                   | 3 +--
 src/libarena/lib.rs                  | 7 +++----
 src/libcollections/btree/map.rs      | 3 +--
 src/libcollections/lib.rs            | 3 ++-
 src/libcollections/linked_list.rs    | 3 +--
 src/libcollections/vec.rs            | 6 ++----
 src/libcollections/vec_deque.rs      | 3 +--
 src/libstd/collections/hash/table.rs | 3 +--
 src/libstd/lib.rs                    | 3 ++-
 src/libstd/sync/mutex.rs             | 3 +--
 src/libstd/sync/rwlock.rs            | 3 +--
 14 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 1cad8f7f40788..393a6a315ca73 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -706,7 +706,7 @@ impl<T: ?Sized> Arc<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Drop for Arc<T> {
+unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
     /// Drops the `Arc`.
     ///
     /// This will decrement the strong reference count. If the strong reference
@@ -734,7 +734,6 @@ impl<T: ?Sized> Drop for Arc<T> {
     /// drop(foo);    // Doesn't print anything
     /// drop(foo2);   // Prints "dropped!"
     /// ```
-    #[unsafe_destructor_blind_to_params]
     #[inline]
     fn drop(&mut self) {
         // Because `fetch_sub` is already atomic, we do not need to synchronize
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index f9dfdc0e07536..3a487ca7b9df4 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -79,9 +79,10 @@
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(custom_attribute)]
-#![feature(dropck_parametricity)]
+#![feature(dropck_eyepatch)]
 #![cfg_attr(not(test), feature(exact_size_is_empty))]
 #![feature(fundamental)]
+#![feature(generic_param_attrs)]
 #![feature(lang_items)]
 #![feature(needs_allocator)]
 #![feature(optin_builtin_traits)]
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index f23ea0ea8bf71..357a2724e0020 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -539,8 +539,7 @@ impl<T> RawVec<T> {
     }
 }
 
-impl<T> Drop for RawVec<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T> Drop for RawVec<T> {
     /// Frees the memory owned by the RawVec *without* trying to Drop its contents.
     fn drop(&mut self) {
         let elem_size = mem::size_of::<T>();
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 86f8c746646aa..010e378ef2f48 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -644,7 +644,7 @@ impl<T: ?Sized> Deref for Rc<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Drop for Rc<T> {
+unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> {
     /// Drops the `Rc`.
     ///
     /// This will decrement the strong reference count. If the strong reference
@@ -672,7 +672,6 @@ impl<T: ?Sized> Drop for Rc<T> {
     /// drop(foo);    // Doesn't print anything
     /// drop(foo2);   // Prints "dropped!"
     /// ```
-    #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
         unsafe {
             let ptr = *self.ptr;
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 6044bec2c5af7..bf7333b4936ad 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -30,10 +30,10 @@
 
 #![feature(alloc)]
 #![feature(core_intrinsics)]
+#![feature(dropck_eyepatch)]
 #![feature(heap_api)]
-#![feature(heap_api)]
+#![feature(generic_param_attrs)]
 #![feature(staged_api)]
-#![feature(dropck_parametricity)]
 #![cfg_attr(test, feature(test))]
 
 #![allow(deprecated)]
@@ -258,8 +258,7 @@ impl<T> TypedArena<T> {
     }
 }
 
-impl<T> Drop for TypedArena<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
     fn drop(&mut self) {
         unsafe {
             // Determine how much was filled.
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 788236c24d063..98c71967f3c39 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -137,8 +137,7 @@ pub struct BTreeMap<K, V> {
 }
 
 #[stable(feature = "btree_drop", since = "1.7.0")]
-impl<K, V> Drop for BTreeMap<K, V> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
     fn drop(&mut self) {
         unsafe {
             for _ in ptr::read(self).into_iter() {
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 68b067012d3fa..9ca56d0aea675 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -35,10 +35,11 @@
 #![feature(box_syntax)]
 #![cfg_attr(not(test), feature(char_escape_debug))]
 #![feature(core_intrinsics)]
-#![feature(dropck_parametricity)]
+#![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
 #![feature(fused)]
+#![feature(generic_param_attrs)]
 #![feature(heap_api)]
 #![feature(inclusive_range)]
 #![feature(lang_items)]
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
index 310855090885c..7f913d4afe476 100644
--- a/src/libcollections/linked_list.rs
+++ b/src/libcollections/linked_list.rs
@@ -726,8 +726,7 @@ impl<T> LinkedList<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for LinkedList<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
     fn drop(&mut self) {
         while let Some(_) = self.pop_front_node() {}
     }
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index f2ef54f6e5679..48a432943d2be 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1763,8 +1763,7 @@ impl<T: Ord> Ord for Vec<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for Vec<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T> Drop for Vec<T> {
     fn drop(&mut self) {
         unsafe {
             // use drop for [T]
@@ -2033,8 +2032,7 @@ impl<T: Clone> Clone for IntoIter<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for IntoIter<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T> Drop for IntoIter<T> {
     fn drop(&mut self) {
         // destroy the remaining elements
         for _x in self.by_ref() {}
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 67621b860bf39..f3a95fa929169 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -69,8 +69,7 @@ impl<T: Clone> Clone for VecDeque<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for VecDeque<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T> Drop for VecDeque<T> {
     fn drop(&mut self) {
         let (front, back) = self.as_mut_slices();
         unsafe {
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 2cd9362a65791..1ab62130cd3dd 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -1061,8 +1061,7 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
     }
 }
 
-impl<K, V> Drop for RawTable<K, V> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
         if self.capacity == 0 {
             return;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index fc5c6968544e8..3f1975525e47e 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -250,13 +250,14 @@
 #![feature(const_fn)]
 #![feature(core_float)]
 #![feature(core_intrinsics)]
-#![feature(dropck_parametricity)]
+#![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(float_extras)]
 #![feature(float_from_str_radix)]
 #![feature(fn_traits)]
 #![feature(fnbox)]
 #![feature(fused)]
+#![feature(generic_param_attrs)]
 #![feature(hashmap_hasher)]
 #![feature(heap_api)]
 #![feature(inclusive_range)]
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index f6dbe01d7bdbf..f8426e3b5782f 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -280,8 +280,7 @@ impl<T: ?Sized> Mutex<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Drop for Mutex<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
         // this mutex (it's up to the user to arrange for a mutex to get
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 0a11c71706b7e..adbb98e4b1f4f 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -310,8 +310,7 @@ impl<T: ?Sized> RwLock<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Drop for RwLock<T> {
-    #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock<T> {
     fn drop(&mut self) {
         // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
         unsafe { self.inner.destroy() }

From ae23f036f0eacb7feea45b0df6611af1a4fde9ef Mon Sep 17 00:00:00 2001
From: Mina Naguib <minaguib@users.noreply.github.com>
Date: Tue, 3 Jan 2017 14:52:14 -0500
Subject: [PATCH 03/15] Doc fix

---
 src/libstd/net/tcp.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 63817c9f10f5f..e225aba2bf813 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -52,7 +52,7 @@ pub struct TcpStream(net_imp::TcpStream);
 ///     // ...
 /// }
 ///
-/// // accept connections and process them, spawning a new thread for each one
+/// // accept connections and process them serially
 /// for stream in listener.incoming() {
 ///     match stream {
 ///         Ok(stream) => {

From 07e844f95fb7894281c08f65f2d127a568525142 Mon Sep 17 00:00:00 2001
From: Manish Goregaokar <manishsmail@gmail.com>
Date: Tue, 3 Jan 2017 22:29:15 -0800
Subject: [PATCH 04/15] Add more docs for CoerceUnsized and Unsize

---
 src/doc/nomicon/coercions.md |  4 +++-
 src/libcore/marker.rs        | 15 ++++++++++++++-
 src/libcore/ops.rs           | 29 +++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/src/doc/nomicon/coercions.md b/src/doc/nomicon/coercions.md
index 6a9ebd6edf8fb..b699946cecaa2 100644
--- a/src/doc/nomicon/coercions.md
+++ b/src/doc/nomicon/coercions.md
@@ -17,6 +17,7 @@ Coercion is allowed between the following types:
     * `&T` to `*const T`
     * `&mut T` to `*mut T`
 * Unsizing: `T` to `U` if `T` implements `CoerceUnsized<U>`
+* Deref coercion: Expression `&x` of type `&T` to `&*x` of type `&U` if `T` derefs to `U` (i.e. `T: Deref<Target=U>`)
 
 `CoerceUnsized<Pointer<U>> for Pointer<T> where T: Unsize<U>` is implemented
 for all pointer types (including smart pointers like Box and Rc). Unsize is
@@ -27,8 +28,9 @@ only implemented automatically, and enables the following transformations:
 * `Foo<..., T, ...>` => `Foo<..., U, ...>` where:
     * `T: Unsize<U>`
     * `Foo` is a struct
-    * Only the last field of `Foo` has type `T`
+    * Only the last field of `Foo` has type involving `T`
     * `T` is not part of the type of any other fields
+    * `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
 
 Coercions occur at a *coercion site*. Any location that is explicitly typed
 will cause a coercion to its type. If inference is necessary, the coercion will
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 9af10966eda4b..a9e2bff5906f5 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -100,13 +100,26 @@ pub trait Sized {
 ///
 /// All implementations of `Unsize` are provided automatically by the compiler.
 ///
+/// `Unsize` is implemented for:
+///
+/// - `[T; N]` is `Unsize<[T]>`
+/// - `T` is `Unsize<Trait>` when `T: Trait`
+/// - `Foo<..., T, ...>` is `Unsize<Foo<..., U, ...>>` if:
+///   - `T: Unsize<U>`
+///   - Foo is a struct
+///   - Only the last field of `Foo` has a type involving `T`
+///   - `T` is not part of the type of any other fields
+///   - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
+///
 /// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow
 /// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized
-/// types. See the [DST coercion RFC][RFC982] for more details.
+/// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce]
+/// for more details.
 ///
 /// [coerceunsized]: ../ops/trait.CoerceUnsized.html
 /// [rc]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
+
 #[unstable(feature = "unsize", issue = "27732")]
 #[lang="unsize"]
 pub trait Unsize<T: ?Sized> {
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 07ae5b920b27b..7477195433338 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -2649,6 +2649,35 @@ mod impls {
 
 /// Trait that indicates that this is a pointer or a wrapper for one,
 /// where unsizing can be performed on the pointee.
+///
+/// See the [DST coercion RfC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
+/// for more details.
+///
+/// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
+/// by converting from a thin pointer to a fat pointer.
+///
+/// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>`
+/// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists.
+/// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata
+/// field involving `T`. If the type of that field is `Bar<T>`, an implementation
+/// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by
+/// by coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields
+/// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer
+/// field and coerce that.
+///
+/// Generally, for smart pointers you will implement
+/// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an
+/// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T`
+/// like `Cell<T>` and `RefCell<T>`, you
+/// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`.
+/// This will let coercions of types like `Cell<Box<T>>` work.
+///
+/// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind
+/// pointers. It is implemented automatically by the compiler.
+///
+/// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
+/// [unsize]: ../marker/trait.Unsize.html
+/// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 #[lang="coerce_unsized"]
 pub trait CoerceUnsized<T> {

From 1a4a6b9dfe828700278ed5ed7b7c9f4b30ca80ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 25 Dec 2016 12:50:28 -0800
Subject: [PATCH 05/15] Add test for correct span for type

Test for #27522.
---
 src/test/ui/span/issue-27522.rs     | 19 +++++++++++++++++++
 src/test/ui/span/issue-27522.stderr | 11 +++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 src/test/ui/span/issue-27522.rs
 create mode 100644 src/test/ui/span/issue-27522.stderr

diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs
new file mode 100644
index 0000000000000..81fcb007eb491
--- /dev/null
+++ b/src/test/ui/span/issue-27522.rs
@@ -0,0 +1,19 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Point at correct span for self type
+
+struct SomeType {}
+
+trait Foo {
+    fn handler(self: &SomeType);
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr
new file mode 100644
index 0000000000000..71130f4947a68
--- /dev/null
+++ b/src/test/ui/span/issue-27522.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched method receiver
+  --> $DIR/issue-27522.rs:16:22
+   |
+16 |     fn handler(self: &SomeType);
+   |                      ^^^^^^^^^ expected Self, found struct `SomeType`
+   |
+   = note: expected type `&Self`
+   = note:    found type `&SomeType`
+
+error: aborting due to previous error
+

From 8d076ce0a61bce94989834488f6d431aa9d32dfd Mon Sep 17 00:00:00 2001
From: Oliver Middleton <olliemail27@gmail.com>
Date: Thu, 5 Jan 2017 01:16:37 +0000
Subject: [PATCH 06/15] Fix typo in tuple docs

---
 src/libstd/primitive_docs.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 5981b482a9728..ced0288766bb1 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -502,7 +502,7 @@ mod prim_str { }
 /// [`Hash`]: hash/trait.Hash.html
 ///
 /// Due to a temporary restriction in Rust's type system, these traits are only
-/// implemented on tuples of arity 32 or less. In the future, this may change.
+/// implemented on tuples of arity 12 or less. In the future, this may change.
 ///
 /// # Examples
 ///

From 943c53bc772e102a4effa1c8388474705548c62b Mon Sep 17 00:00:00 2001
From: F001 <changchun.fan@qq.com>
Date: Thu, 5 Jan 2017 12:25:26 +0800
Subject: [PATCH 07/15] Update usage of rustc

Add proc_macro crate type
---
 src/librustc/session/config.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index b3cb5ace45bc0..85336b173e407 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1175,7 +1175,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
                              assumed.", "[KIND=]NAME"),
         opt::multi_s("", "crate-type", "Comma separated list of types of crates
                                     for the compiler to emit",
-                   "[bin|lib|rlib|dylib|cdylib|staticlib]"),
+                   "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]"),
         opt::opt_s("", "crate-name", "Specify the name of the crate being built",
                "NAME"),
         opt::multi_s("", "emit", "Comma separated list of types of output for \

From 4794f956839328cd813aceb2cba545c9318d4895 Mon Sep 17 00:00:00 2001
From: Corey Farwell <coreyf@rwell.org>
Date: Wed, 4 Jan 2017 22:47:23 -0500
Subject: [PATCH 08/15] Expand {Path,OsStr}::{to_str,to_string_lossy} doc
 examples.

---
 src/libstd/ffi/os_str.rs | 23 +++++++++++++++++++++++
 src/libstd/path.rs       | 13 +++++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 84b50f04463fe..175fe30db661c 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -259,6 +259,15 @@ impl OsStr {
     /// Yields a `&str` slice if the `OsStr` is valid Unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsStr;
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// assert_eq!(os_str.to_str(), Some("foo"));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_str(&self) -> Option<&str> {
         self.inner.to_str()
@@ -267,6 +276,20 @@ impl OsStr {
     /// Converts an `OsStr` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
+    ///
+    /// # Examples
+    ///
+    /// Calling `to_string_lossy` on an `OsStr` with valid unicode:
+    ///
+    /// ```
+    /// use std::ffi::OsStr;
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// assert_eq!(os_str.to_string_lossy(), "foo");
+    /// ```
+    ///
+    /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
+    /// have returned `"fo�"`.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index d13baea40a9ff..3f9bf70adde22 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1428,8 +1428,8 @@ impl Path {
     /// ```
     /// use std::path::Path;
     ///
-    /// let path_str = Path::new("foo.txt").to_str();
-    /// assert_eq!(path_str, Some("foo.txt"));
+    /// let path = Path::new("foo.txt");
+    /// assert_eq!(path.to_str(), Some("foo.txt"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_str(&self) -> Option<&str> {
@@ -1444,12 +1444,17 @@ impl Path {
     ///
     /// # Examples
     ///
+    /// Calling `to_string_lossy` on a `Path` with valid unicode:
+    ///
     /// ```
     /// use std::path::Path;
     ///
-    /// let path_str = Path::new("foo.txt").to_string_lossy();
-    /// assert_eq!(path_str, "foo.txt");
+    /// let path = Path::new("foo.txt");
+    /// assert_eq!(path.to_string_lossy(), "foo.txt");
     /// ```
+    ///
+    /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
+    /// have returned `"fo�.txt"`.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()

From 56e586769801d4b928bda57cb89b294578848da5 Mon Sep 17 00:00:00 2001
From: Michael Woerister <michaelwoerister@posteo.net>
Date: Thu, 5 Jan 2017 10:53:29 -0500
Subject: [PATCH 09/15] ICH: Add some more test cases for trait impls.

---
 src/test/incremental/hashes/trait_impls.rs | 152 +++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/src/test/incremental/hashes/trait_impls.rs b/src/test/incremental/hashes/trait_impls.rs
index 500aaf52324b0..15094492248e6 100644
--- a/src/test/incremental/hashes/trait_impls.rs
+++ b/src/test/incremental/hashes/trait_impls.rs
@@ -402,3 +402,155 @@ impl ChangeArgumentTypeTrait for Foo {
     fn method_name(&self, _x: char) { }
 }
 
+
+
+struct Bar<T>(T);
+
+// Add Type Parameter To Impl --------------------------------------------------
+trait AddTypeParameterToImpl<T> {
+    fn id(t: T) -> T;
+}
+
+#[cfg(cfail1)]
+impl AddTypeParameterToImpl<u32> for Bar<u32> {
+    fn id(t: u32) -> u32 { t }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl<T> AddTypeParameterToImpl<T> for Bar<T> {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    fn id(t: T) -> T { t }
+}
+
+
+
+// Change Self Type of Impl ----------------------------------------------------
+trait ChangeSelfTypeOfImpl {
+    fn id(self) -> Self;
+}
+
+#[cfg(cfail1)]
+impl ChangeSelfTypeOfImpl for u32 {
+    fn id(self) -> Self { self }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl ChangeSelfTypeOfImpl for u64 {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    fn id(self) -> Self { self }
+}
+
+
+
+// Add Lifetime Bound to Impl --------------------------------------------------
+trait AddLifetimeBoundToImplParameter {
+    fn id(self) -> Self;
+}
+
+#[cfg(cfail1)]
+impl<T> AddLifetimeBoundToImplParameter for T {
+    fn id(self) -> Self { self }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl<T: 'static> AddLifetimeBoundToImplParameter for T {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    fn id(self) -> Self { self }
+}
+
+
+
+// Add Trait Bound to Impl Parameter -------------------------------------------
+trait AddTraitBoundToImplParameter {
+    fn id(self) -> Self;
+}
+
+#[cfg(cfail1)]
+impl<T> AddTraitBoundToImplParameter for T {
+    fn id(self) -> Self { self }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl<T: Clone> AddTraitBoundToImplParameter for T {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    fn id(self) -> Self { self }
+}
+
+
+
+// Add #[no_mangle] to Method --------------------------------------------------
+trait AddNoMangleToMethod {
+    fn add_no_mangle_to_method(&self) { }
+}
+
+#[cfg(cfail1)]
+impl AddNoMangleToMethod for Foo {
+    fn add_no_mangle_to_method(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl AddNoMangleToMethod for Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    #[no_mangle]
+    fn add_no_mangle_to_method(&self) { }
+}
+
+
+// Make Method #[inline] -------------------------------------------------------
+trait MakeMethodInline {
+    fn make_method_inline(&self) -> u8 { 0 }
+}
+
+#[cfg(cfail1)]
+impl MakeMethodInline for Foo {
+    fn make_method_inline(&self) -> u8 { 0 }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl MakeMethodInline for Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    #[inline]
+    fn make_method_inline(&self) -> u8 { 0 }
+}

From 5cb37f6331cb97a0d644d3ff753e73dd7bf66604 Mon Sep 17 00:00:00 2001
From: derekdreery <rodododouk@hotmail.com>
Date: Fri, 6 Jan 2017 15:58:35 +0000
Subject: [PATCH 10/15] Update vec.rs

Add a warning not to convert  char* from c to Vec<u8> (I thought you could until I asked on irc)
---
 src/libcollections/vec.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index f2ef54f6e5679..3c9a9897fea5b 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -370,7 +370,8 @@ impl<T> Vec<T> {
     /// * `capacity` needs to be the capacity that the pointer was allocated with.
     ///
     /// Violating these may cause problems like corrupting the allocator's
-    /// internal datastructures.
+    /// internal datastructures. For example it is **not** safe
+    /// to build a `Vec<u8>` from a C pointer to a char array and a `size_t`.
     ///
     /// The ownership of `ptr` is effectively transferred to the
     /// `Vec<T>` which may then deallocate, reallocate or change the

From 0a85d5f7f355e7e04e97e27e2613c9831daa67a7 Mon Sep 17 00:00:00 2001
From: derekdreery <rodododouk@hotmail.com>
Date: Fri, 6 Jan 2017 18:17:18 +0000
Subject: [PATCH 11/15] Update vec.rs

Changed language to stress char is the C meaning (u8) not unicode.
---
 src/libcollections/vec.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 3c9a9897fea5b..12eac3c96eef1 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -371,7 +371,7 @@ impl<T> Vec<T> {
     ///
     /// Violating these may cause problems like corrupting the allocator's
     /// internal datastructures. For example it is **not** safe
-    /// to build a `Vec<u8>` from a C pointer to a char array and a `size_t`.
+    /// to build a `Vec<u8>` from a pointer to a C `char` array and a `size_t`.
     ///
     /// The ownership of `ptr` is effectively transferred to the
     /// `Vec<T>` which may then deallocate, reallocate or change the

From e72b203566bbb77b26410e5268967ddb451381dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 25 Dec 2016 13:00:06 -0800
Subject: [PATCH 12/15] Test for appropriate span on second custom derive

---
 src/test/ui/custom-derive/auxiliary/plugin.rs | 28 +++++++++++++++++++
 src/test/ui/custom-derive/issue-36935.rs      | 23 +++++++++++++++
 src/test/ui/custom-derive/issue-36935.stderr  |  8 ++++++
 3 files changed, 59 insertions(+)
 create mode 100644 src/test/ui/custom-derive/auxiliary/plugin.rs
 create mode 100644 src/test/ui/custom-derive/issue-36935.rs
 create mode 100644 src/test/ui/custom-derive/issue-36935.stderr

diff --git a/src/test/ui/custom-derive/auxiliary/plugin.rs b/src/test/ui/custom-derive/auxiliary/plugin.rs
new file mode 100644
index 0000000000000..c5ba2aa9413e7
--- /dev/null
+++ b/src/test/ui/custom-derive/auxiliary/plugin.rs
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro, proc_macro_lib)]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(Foo)]
+pub fn derive_foo(input: TokenStream) -> TokenStream {
+    input
+}
+
+#[proc_macro_derive(Bar)]
+pub fn derive_bar(input: TokenStream) -> TokenStream {
+    panic!("lolnope");
+}
diff --git a/src/test/ui/custom-derive/issue-36935.rs b/src/test/ui/custom-derive/issue-36935.rs
new file mode 100644
index 0000000000000..22d603563de17
--- /dev/null
+++ b/src/test/ui/custom-derive/issue-36935.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:plugin.rs
+
+#![feature(proc_macro)]
+
+#[macro_use] extern crate plugin;
+
+#[derive(Foo, Bar)]
+struct Baz {
+    a: i32,
+    b: i32,
+}
+
+fn main() {}
diff --git a/src/test/ui/custom-derive/issue-36935.stderr b/src/test/ui/custom-derive/issue-36935.stderr
new file mode 100644
index 0000000000000..213366a307d40
--- /dev/null
+++ b/src/test/ui/custom-derive/issue-36935.stderr
@@ -0,0 +1,8 @@
+error: custom derive attribute panicked
+  --> $DIR/issue-36935.rs:17:15
+   |
+17 | #[derive(Foo, Bar)]
+   |               ^^^
+   |
+   = help: message: lolnope
+

From c999221cf8c58cca1b1b718587c4d5d3f16e3fc1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 6 Jan 2017 18:18:47 -0800
Subject: [PATCH 13/15] Move check-ui to fulldeps so librustc is available

As per @alexcrichton's comment in #38607.
---
 src/bootstrap/step.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs
index bf815a817ed87..d2ac63e8ee08c 100644
--- a/src/bootstrap/step.rs
+++ b/src/bootstrap/step.rs
@@ -316,7 +316,6 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
               "codegen-units");
         suite("check-incremental", "src/test/incremental", "incremental",
               "incremental");
-        suite("check-ui", "src/test/ui", "ui", "ui");
     }
 
     if build.config.build.contains("msvc") {
@@ -363,6 +362,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
                  });
         };
 
+        suite("check-ui", "src/test/ui", "ui", "ui");
         suite("check-rpass-full", "src/test/run-pass-fulldeps",
               "run-pass", "run-pass-fulldeps");
         suite("check-rfail-full", "src/test/run-fail-fulldeps",

From 78e9093abbdedf2d29bf0b42c0cce2cfc2977894 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 7 Jan 2017 23:31:23 -0800
Subject: [PATCH 14/15] trying to figure out why this test failes, might need
 help

---
 src/bootstrap/step.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs
index d2ac63e8ee08c..62b47c1bac2e3 100644
--- a/src/bootstrap/step.rs
+++ b/src/bootstrap/step.rs
@@ -1397,7 +1397,6 @@ mod tests {
         assert!(plan.iter().all(|s| s.host == "A"));
         assert!(plan.iter().all(|s| s.target == "C"));
 
-        assert!(plan.iter().any(|s| s.name.contains("-ui")));
         assert!(plan.iter().any(|s| s.name.contains("cfail")));
         assert!(plan.iter().any(|s| s.name.contains("cfail")));
         assert!(!plan.iter().any(|s| s.name.contains("cfail-full")));

From d8b3a64b7587cf1c793e53b3a0f6cbea1ffd929e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 8 Jan 2017 21:10:08 -0800
Subject: [PATCH 15/15] review comment

---
 src/bootstrap/step.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs
index 62b47c1bac2e3..8ab4db2c30bfe 100644
--- a/src/bootstrap/step.rs
+++ b/src/bootstrap/step.rs
@@ -1364,7 +1364,6 @@ mod tests {
 
         assert!(plan.iter().any(|s| s.name.contains("-ui")));
         assert!(plan.iter().any(|s| s.name.contains("cfail")));
-        assert!(plan.iter().any(|s| s.name.contains("cfail")));
         assert!(plan.iter().any(|s| s.name.contains("cfail-full")));
         assert!(plan.iter().any(|s| s.name.contains("codegen-units")));
         assert!(plan.iter().any(|s| s.name.contains("debuginfo")));
@@ -1397,7 +1396,7 @@ mod tests {
         assert!(plan.iter().all(|s| s.host == "A"));
         assert!(plan.iter().all(|s| s.target == "C"));
 
-        assert!(plan.iter().any(|s| s.name.contains("cfail")));
+        assert!(!plan.iter().any(|s| s.name.contains("-ui")));
         assert!(plan.iter().any(|s| s.name.contains("cfail")));
         assert!(!plan.iter().any(|s| s.name.contains("cfail-full")));
         assert!(plan.iter().any(|s| s.name.contains("codegen-units")));