From 1c12b1be330dd9c3de0b4fe599686d7c0c45e720 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 24 Jun 2019 22:58:53 +0200
Subject: [PATCH 1/9] call out explicitly that general read needs to be called
 with an initialized buffer

---
 src/libstd/io/mod.rs | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 917199f8ea8d0..7fba844897ffe 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -506,9 +506,18 @@ pub trait Read {
     ///
     /// No guarantees are provided about the contents of `buf` when this
     /// function is called, implementations cannot rely on any property of the
-    /// contents of `buf` being true. It is recommended that implementations
+    /// contents of `buf` being true. It is recommended that *implementations*
     /// only write data to `buf` instead of reading its contents.
     ///
+    /// Correspondingly, however, *users* of this trait may not assume any guarantees
+    /// about how the implementation uses `buf`. The trait is safe to implement,
+    /// so it is perfectly possible that the implementation might inspect that data.
+    /// As a caller, it is your responsibility to make sure that `buf` is initialized
+    /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one
+    /// obtains via [`MaybeUninit<T>`]) is not safe, and can lead to undefined behavior.
+    ///
+    /// [`MaybeUninit<T>`]: ../mem/union.MaybeUninit.html
+    ///
     /// # Errors
     ///
     /// If this function encounters any form of I/O or other error, an error

From c877989655d151972cd6a9c60450951a2efa0513 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Tue, 25 Jun 2019 04:00:03 +0200
Subject: [PATCH 2/9] Add some #[inline] attributes

---
 src/libsyntax_pos/symbol.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 756bc8c29d828..18c379f61f8d2 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1131,6 +1131,7 @@ impl LocalInternedString {
         }
     }
 
+    #[inline]
     pub fn get(&self) -> &str {
         // This returns a valid string since we ensure that `self` outlives the interner
         // by creating the interner on a thread which outlives threads which can access it.
@@ -1144,6 +1145,7 @@ impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
 where
     str: std::convert::AsRef<U>
 {
+    #[inline]
     fn as_ref(&self) -> &U {
         self.string.as_ref()
     }
@@ -1184,6 +1186,7 @@ impl !Sync for LocalInternedString {}
 
 impl std::ops::Deref for LocalInternedString {
     type Target = str;
+    #[inline]
     fn deref(&self) -> &str { self.string }
 }
 

From 11221d120f8f79ff8e6ad35256874f30a942908b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Tue, 25 Jun 2019 01:41:16 +0200
Subject: [PATCH 3/9] Inform the query system about properties of queries at
 compile time

---
 src/librustc/dep_graph/dep_node.rs |  4 ---
 src/librustc/ty/query/config.rs    |  7 +++-
 src/librustc/ty/query/mod.rs       |  2 +-
 src/librustc/ty/query/plumbing.rs  | 57 +++++++++++++++++++++++-------
 src/librustc_macros/src/query.rs   | 20 ++++-------
 5 files changed, 58 insertions(+), 32 deletions(-)

diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 82b0e50b50c48..3d5e7dd0af121 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -142,9 +142,6 @@ macro_rules! define_dep_nodes {
                 }
             }
 
-            // FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties
-            // of queries
-            #[inline(always)]
             pub fn is_anon(&self) -> bool {
                 match *self {
                     $(
@@ -163,7 +160,6 @@ macro_rules! define_dep_nodes {
             }
 
             #[allow(unreachable_code)]
-            #[inline(always)]
             pub fn has_params(&self) -> bool {
                 match *self {
                     $(
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 13d93f173e845..6ad4ecb3e980c 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -1,5 +1,5 @@
 use crate::dep_graph::SerializedDepNodeIndex;
-use crate::dep_graph::DepNode;
+use crate::dep_graph::{DepKind, DepNode};
 use crate::hir::def_id::{CrateNum, DefId};
 use crate::ty::TyCtxt;
 use crate::ty::query::queries;
@@ -28,6 +28,9 @@ pub trait QueryConfig<'tcx> {
 }
 
 pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
+    const ANON: bool;
+    const EVAL_ALWAYS: bool;
+
     fn query(key: Self::Key) -> Query<'tcx>;
 
     // Don't use this method to access query results, instead use the methods on TyCtxt
@@ -35,6 +38,8 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
 
     fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
 
+    fn dep_kind() -> DepKind;
+
     // Don't use this method to compute query results, instead use the methods on TyCtxt
     fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value;
 
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index e595b52876f4c..e788628bc58e2 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -101,6 +101,6 @@ pub use self::on_disk_cache::OnDiskCache;
 rustc_query_append! { [define_queries!][ <'tcx>
     Other {
         /// Runs analysis passes on the crate.
-        [] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
+        [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
     },
 ]}
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 7d5f984c1b6f2..553c701c3aaa0 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -376,15 +376,13 @@ impl<'tcx> TyCtxt<'tcx> {
             return self.force_query_with_job::<Q>(key, job, null_dep_node).0;
         }
 
-        let dep_node = Q::to_dep_node(self, &key);
-
-        if dep_node.kind.is_anon() {
+        if Q::ANON {
             profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
             self.sess.profiler(|p| p.start_query(Q::NAME));
 
             let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
                 self.start_query(job.job.clone(), diagnostics, |tcx| {
-                    tcx.dep_graph.with_anon_task(dep_node.kind, || {
+                    tcx.dep_graph.with_anon_task(Q::dep_kind(), || {
                         Q::compute(tcx.global_tcx(), key)
                     })
                 })
@@ -405,7 +403,9 @@ impl<'tcx> TyCtxt<'tcx> {
             return result;
         }
 
-        if !dep_node.kind.is_eval_always() {
+        let dep_node = Q::to_dep_node(self, &key);
+
+        if !Q::EVAL_ALWAYS {
             // The diagnostics for this query will be
             // promoted to the current session during
             // try_mark_green(), so we can ignore them here.
@@ -546,7 +546,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
             self.start_query(job.job.clone(), diagnostics, |tcx| {
-                if dep_node.kind.is_eval_always() {
+                if Q::EVAL_ALWAYS {
                     tcx.dep_graph.with_eval_always_task(dep_node,
                                                         tcx,
                                                         key,
@@ -569,8 +569,8 @@ impl<'tcx> TyCtxt<'tcx> {
             self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
         }
 
-        if dep_node.kind != crate::dep_graph::DepKind::Null {
-            if unlikely!(!diagnostics.is_empty()) {
+        if unlikely!(!diagnostics.is_empty()) {
+            if dep_node.kind != crate::dep_graph::DepKind::Null {
                 self.queries.on_disk_cache
                     .store_diagnostics(dep_node_index, diagnostics);
             }
@@ -589,15 +589,16 @@ impl<'tcx> TyCtxt<'tcx> {
     ///
     /// Note: The optimization is only available during incr. comp.
     pub(super) fn ensure_query<Q: QueryDescription<'tcx>>(self, key: Q::Key) -> () {
-        let dep_node = Q::to_dep_node(self, &key);
-
-        if dep_node.kind.is_eval_always() {
+        if Q::EVAL_ALWAYS {
             let _ = self.get_query::<Q>(DUMMY_SP, key);
             return;
         }
 
         // Ensuring an anonymous query makes no sense
-        assert!(!dep_node.kind.is_anon());
+        assert!(!Q::ANON);
+
+        let dep_node = Q::to_dep_node(self, &key);
+
         if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() {
             // A None return from `try_mark_green_and_read` means that this is either
             // a new dep node or that the dep node has already been marked red.
@@ -653,6 +654,30 @@ macro_rules! handle_cycle_error {
     };
 }
 
+macro_rules! is_anon {
+    ([]) => {{
+        false
+    }};
+    ([anon$(, $modifiers:ident)*]) => {{
+        true
+    }};
+    ([$other:ident$(, $modifiers:ident)*]) => {
+        is_anon!([$($modifiers),*])
+    };
+}
+
+macro_rules! is_eval_always {
+    ([]) => {{
+        false
+    }};
+    ([eval_always$(, $modifiers:ident)*]) => {{
+        true
+    }};
+    ([$other:ident$(, $modifiers:ident)*]) => {
+        is_eval_always!([$($modifiers),*])
+    };
+}
+
 macro_rules! hash_result {
     ([][$hcx:expr, $result:expr]) => {{
         dep_graph::hash_result($hcx, &$result)
@@ -933,6 +958,9 @@ macro_rules! define_queries_inner {
         }
 
         impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
+            const ANON: bool = is_anon!([$($modifiers)*]);
+            const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
+
             #[inline(always)]
             fn query(key: Self::Key) -> Query<'tcx> {
                 Query::$name(key)
@@ -951,6 +979,11 @@ macro_rules! define_queries_inner {
                 DepNode::new(tcx, $node(*key))
             }
 
+            #[inline(always)]
+            fn dep_kind() -> dep_graph::DepKind {
+                dep_graph::DepKind::$node
+            }
+
             #[inline]
             fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
                 __query_compute::$name(move || {
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
index 0474d2a2e3b3a..2cf364b562766 100644
--- a/src/librustc_macros/src/query.rs
+++ b/src/librustc_macros/src/query.rs
@@ -423,20 +423,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             if modifiers.no_hash {
                 attributes.push(quote! { no_hash });
             };
-
-            let mut attribute_stream = quote! {};
-
-            for e in attributes.into_iter().intersperse(quote! {,}) {
-                attribute_stream.extend(e);
-            }
-
-            // Add the query to the group
-            group_stream.extend(quote! {
-                [#attribute_stream] fn #name: #name(#arg) #result,
-            });
-
-            let mut attributes = Vec::new();
-
             // Pass on the anon modifier
             if modifiers.anon {
                 attributes.push(quote! { anon });
@@ -450,6 +436,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             for e in attributes.into_iter().intersperse(quote! {,}) {
                 attribute_stream.extend(e);
             }
+
+            // Add the query to the group
+            group_stream.extend(quote! {
+                [#attribute_stream] fn #name: #name(#arg) #result,
+            });
+
             // Create a dep node for the query
             dep_node_def_stream.extend(quote! {
                 [#attribute_stream] #name(#arg),

From 85ea4a1bf4a05ff18d6634db35eb41c3a6bca637 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Tue, 25 Jun 2019 23:09:25 +0900
Subject: [PATCH 4/9] Update new_debug_unreachable

---
 Cargo.lock | 26 ++++----------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index eaec52a7a150c..98dd10955d57d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1030,7 +1030,7 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1760,11 +1760,8 @@ dependencies = [
 
 [[package]]
 name = "new_debug_unreachable"
-version = "1.0.1"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "nodrop"
@@ -3450,7 +3447,7 @@ version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4038,14 +4035,6 @@ name = "unicode_categories"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "unreachable"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "unstable-book-gen"
 version = "0.1.0"
@@ -4124,11 +4113,6 @@ name = "version_check"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "void"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "vte"
 version = "0.3.3"
@@ -4388,7 +4372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
 "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
 "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
-"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
+"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
 "checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d"
 "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
@@ -4552,7 +4536,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
-"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
 "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
 "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c"
@@ -4562,7 +4545,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
 "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba"
 "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
-"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f42f536e22f7fcbb407639765c8fd78707a33109301f834a594758bedd6e8cf"
 "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"

From b75021b31e43d59eb2b91fe45cfffcb7d25fb141 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Tue, 25 Jun 2019 21:02:19 +0300
Subject: [PATCH 5/9] refactor lexer to use idiomatic borrowing

---
 src/libsyntax/parse/lexer/mod.rs | 225 ++++++++++++++-----------------
 1 file changed, 104 insertions(+), 121 deletions(-)

diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index ead5d543bec7d..7b9e3bc4d5102 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -321,33 +321,29 @@ impl<'a> StringReader<'a> {
         (pos - self.source_file.start_pos).to_usize()
     }
 
-    /// Calls `f` with a string slice of the source text spanning from `start`
-    /// up to but excluding `self.pos`, meaning the slice does not include
-    /// the character `self.ch`.
-    fn with_str_from<T, F>(&self, start: BytePos, f: F) -> T
-        where F: FnOnce(&str) -> T
+    /// Slice of the source text from `start` up to but excluding `self.pos`,
+    /// meaning the slice does not include the character `self.ch`.
+    fn str_from(&self, start: BytePos) -> &str
     {
-        self.with_str_from_to(start, self.pos, f)
+        self.str_from_to(start, self.pos)
     }
 
     /// Creates a Name from a given offset to the current offset.
     fn name_from(&self, start: BytePos) -> ast::Name {
         debug!("taking an ident from {:?} to {:?}", start, self.pos);
-        self.with_str_from(start, Symbol::intern)
+        Symbol::intern(self.str_from(start))
     }
 
     /// As name_from, with an explicit endpoint.
     fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
         debug!("taking an ident from {:?} to {:?}", start, end);
-        self.with_str_from_to(start, end, Symbol::intern)
+        Symbol::intern(self.str_from_to(start, end))
     }
 
-    /// Calls `f` with a string slice of the source text spanning from `start`
-    /// up to but excluding `end`.
-    fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T
-        where F: FnOnce(&str) -> T
+    /// Slice of the source text spanning from `start` up to but excluding `end`.
+    fn str_from_to(&self, start: BytePos, end: BytePos) -> &str
     {
-        f(&self.src[self.src_index(start)..self.src_index(end)])
+        &self.src[self.src_index(start)..self.src_index(end)]
     }
 
     /// Converts CRLF to LF in the given string, raising an error on bare CR.
@@ -456,8 +452,8 @@ impl<'a> StringReader<'a> {
             self.bump();
         }
 
-        self.with_str_from(start, |string| {
-            if string == "_" {
+        match self.str_from(start) {
+            "_" => {
                 self.sess.span_diagnostic
                     .struct_span_warn(self.mk_sp(start, self.pos),
                                       "underscore literal suffix is not allowed")
@@ -468,10 +464,9 @@ impl<'a> StringReader<'a> {
                           <https://github.com/rust-lang/rust/issues/42326>")
                     .emit();
                 None
-            } else {
-                Some(Symbol::intern(string))
             }
-        })
+            name => Some(Symbol::intern(name))
+        }
     }
 
     /// PRECONDITION: self.ch is not whitespace
@@ -513,9 +508,7 @@ impl<'a> StringReader<'a> {
                     }
 
                     let kind = if doc_comment {
-                        self.with_str_from(start_bpos, |string| {
-                            token::DocComment(Symbol::intern(string))
-                        })
+                        token::DocComment(self.name_from(start_bpos))
                     } else {
                         token::Comment
                     };
@@ -615,23 +608,22 @@ impl<'a> StringReader<'a> {
             self.bump();
         }
 
-        self.with_str_from(start_bpos, |string| {
-            // but comments with only "*"s between two "/"s are not
-            let kind = if is_block_doc_comment(string) {
-                let string = if has_cr {
-                    self.translate_crlf(start_bpos,
-                                        string,
-                                        "bare CR not allowed in block doc-comment")
-                } else {
-                    string.into()
-                };
-                token::DocComment(Symbol::intern(&string[..]))
+        let string = self.str_from(start_bpos);
+        // but comments with only "*"s between two "/"s are not
+        let kind = if is_block_doc_comment(string) {
+            let string = if has_cr {
+                self.translate_crlf(start_bpos,
+                                    string,
+                                    "bare CR not allowed in block doc-comment")
             } else {
-                token::Comment
+                string.into()
             };
+            token::DocComment(Symbol::intern(&string[..]))
+        } else {
+            token::Comment
+        };
 
-            Some(Token::new(kind, self.mk_sp(start_bpos, self.pos)))
-        })
+        Some(Token::new(kind, self.mk_sp(start_bpos, self.pos)))
     }
 
     /// Scan through any digits (base `scan_radix`) or underscores,
@@ -838,20 +830,17 @@ impl<'a> StringReader<'a> {
                     self.bump();
                 }
 
-                return Ok(self.with_str_from(start, |string| {
-                    // FIXME: perform NFKC normalization here. (Issue #2253)
-                    let name = ast::Name::intern(string);
-
-                    if is_raw_ident {
-                        let span = self.mk_sp(raw_start, self.pos);
-                        if !name.can_be_raw() {
-                            self.err_span(span, &format!("`{}` cannot be a raw identifier", name));
-                        }
-                        self.sess.raw_identifier_spans.borrow_mut().push(span);
+                // FIXME: perform NFKC normalization here. (Issue #2253)
+                let name = self.name_from(start);
+                if is_raw_ident {
+                    let span = self.mk_sp(raw_start, self.pos);
+                    if !name.can_be_raw() {
+                        self.err_span(span, &format!("`{}` cannot be a raw identifier", name));
                     }
+                    self.sess.raw_identifier_spans.borrow_mut().push(span);
+                }
 
-                    token::Ident(name, is_raw_ident)
-                }));
+                return Ok(token::Ident(name, is_raw_ident));
             }
         }
 
@@ -1300,101 +1289,95 @@ impl<'a> StringReader<'a> {
     }
 
     fn validate_char_escape(&self, start_with_quote: BytePos) {
-        self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| {
-            if let Err((off, err)) = unescape::unescape_char(lit) {
+        let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1));
+        if let Err((off, err)) = unescape::unescape_char(lit) {
+            emit_unescape_error(
+                &self.sess.span_diagnostic,
+                lit,
+                self.mk_sp(start_with_quote, self.pos),
+                unescape::Mode::Char,
+                0..off,
+                err,
+            )
+        }
+    }
+
+    fn validate_byte_escape(&self, start_with_quote: BytePos) {
+        let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1));
+        if let Err((off, err)) = unescape::unescape_byte(lit) {
+            emit_unescape_error(
+                &self.sess.span_diagnostic,
+                lit,
+                self.mk_sp(start_with_quote, self.pos),
+                unescape::Mode::Byte,
+                0..off,
+                err,
+            )
+        }
+    }
+
+    fn validate_str_escape(&self, start_with_quote: BytePos) {
+        let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1));
+        unescape::unescape_str(lit, &mut |range, c| {
+            if let Err(err) = c {
                 emit_unescape_error(
                     &self.sess.span_diagnostic,
                     lit,
                     self.mk_sp(start_with_quote, self.pos),
-                    unescape::Mode::Char,
-                    0..off,
+                    unescape::Mode::Str,
+                    range,
                     err,
                 )
             }
-        });
+        })
     }
 
-    fn validate_byte_escape(&self, start_with_quote: BytePos) {
-        self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| {
-            if let Err((off, err)) = unescape::unescape_byte(lit) {
+    fn validate_raw_str_escape(&self, content_start: BytePos, content_end: BytePos) {
+        let lit = self.str_from_to(content_start, content_end);
+        unescape::unescape_raw_str(lit, &mut |range, c| {
+            if let Err(err) = c {
                 emit_unescape_error(
                     &self.sess.span_diagnostic,
                     lit,
-                    self.mk_sp(start_with_quote, self.pos),
-                    unescape::Mode::Byte,
-                    0..off,
+                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
+                    unescape::Mode::Str,
+                    range,
                     err,
                 )
             }
-        });
-    }
-
-    fn validate_str_escape(&self, start_with_quote: BytePos) {
-        self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| {
-            unescape::unescape_str(lit, &mut |range, c| {
-                if let Err(err) = c {
-                    emit_unescape_error(
-                        &self.sess.span_diagnostic,
-                        lit,
-                        self.mk_sp(start_with_quote, self.pos),
-                        unescape::Mode::Str,
-                        range,
-                        err,
-                    )
-                }
-            })
-        });
-    }
-
-    fn validate_raw_str_escape(&self, content_start: BytePos, content_end: BytePos) {
-        self.with_str_from_to(content_start, content_end, |lit: &str| {
-            unescape::unescape_raw_str(lit, &mut |range, c| {
-                if let Err(err) = c {
-                    emit_unescape_error(
-                        &self.sess.span_diagnostic,
-                        lit,
-                        self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                        unescape::Mode::Str,
-                        range,
-                        err,
-                    )
-                }
-            })
-        });
+        })
     }
 
     fn validate_raw_byte_str_escape(&self, content_start: BytePos, content_end: BytePos) {
-        self.with_str_from_to(content_start, content_end, |lit: &str| {
-            unescape::unescape_raw_byte_str(lit, &mut |range, c| {
-                if let Err(err) = c {
-                    emit_unescape_error(
-                        &self.sess.span_diagnostic,
-                        lit,
-                        self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                        unescape::Mode::ByteStr,
-                        range,
-                        err,
-                    )
-                }
-            })
-        });
+        let lit = self.str_from_to(content_start, content_end);
+        unescape::unescape_raw_byte_str(lit, &mut |range, c| {
+            if let Err(err) = c {
+                emit_unescape_error(
+                    &self.sess.span_diagnostic,
+                    lit,
+                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
+                    unescape::Mode::ByteStr,
+                    range,
+                    err,
+                )
+            }
+        })
     }
 
     fn validate_byte_str_escape(&self, start_with_quote: BytePos) {
-        self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| {
-            unescape::unescape_byte_str(lit, &mut |range, c| {
-                if let Err(err) = c {
-                    emit_unescape_error(
-                        &self.sess.span_diagnostic,
-                        lit,
-                        self.mk_sp(start_with_quote, self.pos),
-                        unescape::Mode::ByteStr,
-                        range,
-                        err,
-                    )
-                }
-            })
-        });
+        let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1));
+        unescape::unescape_byte_str(lit, &mut |range, c| {
+            if let Err(err) = c {
+                emit_unescape_error(
+                    &self.sess.span_diagnostic,
+                    lit,
+                    self.mk_sp(start_with_quote, self.pos),
+                    unescape::Mode::ByteStr,
+                    range,
+                    err,
+                )
+            }
+        })
     }
 }
 

From 0f34d7a7e5f068683097e0e664249bd6a417032f Mon Sep 17 00:00:00 2001
From: Erin Power <xampprocky@gmail.com>
Date: Sun, 23 Jun 2019 11:45:06 +0200
Subject: [PATCH 6/9] Updated RELEASES.md for 1.36.0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-Authored-By: Taiki Endo <te316e89@gmail.com>
Co-Authored-By: Jonas Schievink <jonasschievink@gmail.com>
Co-Authored-By: Torbjørn Birch Moltu <t.b.moltu@lyse.net>
---
 RELEASES.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 1 deletion(-)

diff --git a/RELEASES.md b/RELEASES.md
index 91e3c5f721952..b6e2171f6eef9 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,104 @@
+Version 1.36.0 (2019-07-04)
+==========================
+
+Language
+--------
+- [Non-Lexical Lifetimes are now enabled on the 2015 edition.][59114]
+- [The order of traits in trait objects no longer affects the semantics of that
+  object.][59445] e.g. `dyn Send + fmt::Debug` is now equivalent to
+  `dyn fmt::Debug + Send`, where this was previously not the case.
+
+Libraries
+---------
+- [`HashMap`'s implementation has been replaced with `hashbrown::HashMap` implementation.][58623]
+- [`TryFromSliceError` now implements `From<Infallible>`.][60318]
+- [`mem::needs_drop` is now available as a const fn.][60364]
+- [`alloc::Layout::from_size_align_unchecked` is now available as a const fn.][60370]
+- [`String` now implements `BorrowMut<str>`.][60404]
+- [`io::Cursor` now implements `Default`.][60234]
+- [Both `NonNull::{dangling, cast}` are now const fns.][60244]
+- [The `alloc` crate is now stable.][59675] `alloc` allows you to use a subset
+  of `std` (e.g. `Vec`, `Box`, `Arc`) in `#![no_std]` environments if the
+  environment has access to heap memory allocation.
+- [`String` now implements `From<&String>`.][59825]
+- [You can now pass multiple arguments to the `dbg!` macro.][59826] `dbg!` will
+  return a tuple of each argument when there is multiple arguments.
+- [`Result::{is_err, is_ok}` are now `#[must_use]` and will produce a warning if
+  not used.][59648]
+
+Stabilized APIs
+---------------
+- [`VecDeque::rotate_left`]
+- [`VecDeque::rotate_right`]
+- [`Iterator::copied`]
+- [`io::IoSlice`]
+- [`io::IoSliceMut`]
+- [`Read::read_vectored`]
+- [`Write::write_vectored`]
+- [`str::as_mut_ptr`]
+- [`mem::MaybeUninit`]
+- [`pointer::align_offset`]
+- [`future::Future`]
+- [`task::Context`] 
+- [`task::RawWaker`]
+- [`task::RawWakerVTable`]
+- [`task::Waker`]
+- [`task::Poll`]
+
+Cargo
+-----
+- [Cargo will now produce an error if you attempt to use the name of a required dependency as a feature.][cargo/6860]
+- [You can now pass the `--offline` flag to run cargo without accessing the network.][cargo/6934]
+
+You can find further change's in [Cargo's 1.36.0 release notes][cargo-1-36-0].
+
+Clippy
+------
+There have been numerous additions and fixes to clippy, see [Clippy's 1.36.0 release notes][clippy-1-36-0] for more details.
+
+Misc
+----
+
+Compatibility Notes
+-------------------
+- With the stabilisation of `mem::MaybeUninit`, `mem::uninitialized` use is no
+  longer recommended, and will be deprecated in 1.38.0.
+
+[60318]: https://github.com/rust-lang/rust/pull/60318/
+[60364]: https://github.com/rust-lang/rust/pull/60364/
+[60370]: https://github.com/rust-lang/rust/pull/60370/
+[60404]: https://github.com/rust-lang/rust/pull/60404/
+[60234]: https://github.com/rust-lang/rust/pull/60234/
+[60244]: https://github.com/rust-lang/rust/pull/60244/
+[58623]: https://github.com/rust-lang/rust/pull/58623/
+[59648]: https://github.com/rust-lang/rust/pull/59648/
+[59675]: https://github.com/rust-lang/rust/pull/59675/
+[59825]: https://github.com/rust-lang/rust/pull/59825/
+[59826]: https://github.com/rust-lang/rust/pull/59826/
+[59445]: https://github.com/rust-lang/rust/pull/59445/
+[59114]: https://github.com/rust-lang/rust/pull/59114/
+[cargo/6860]: https://github.com/rust-lang/cargo/pull/6860/
+[cargo/6934]: https://github.com/rust-lang/cargo/pull/6934/
+[`VecDeque::rotate_left`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.rotate_left
+[`VecDeque::rotate_right`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.rotate_right
+[`Iterator::copied`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.copied
+[`io::IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html
+[`io::IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html
+[`Read::read_vectored`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_vectored
+[`Write::write_vectored`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_vectored
+[`str::as_mut_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_mut_ptr
+[`mem::MaybeUninit`]: https://doc.rust-lang.org/std/mem/union.MaybeUninit.html
+[`pointer::align_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.align_offset
+[`future::Future`]: https://doc.rust-lang.org/std/future/trait.Future.html
+[`task::Context`]: https://doc.rust-lang.org/beta/std/task/struct.Context.html
+[`task::RawWaker`]: https://doc.rust-lang.org/beta/std/task/struct.RawWaker.html
+[`task::RawWakerVTable`]: https://doc.rust-lang.org/beta/std/task/struct.RawWakerVTable.html
+[`task::Waker`]: https://doc.rust-lang.org/beta/std/task/struct.Waker.html
+[`task::Poll`]: https://doc.rust-lang.org/beta/std/task/enum.Poll.html
+[clippy-1-36-0]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-136
+[cargo-1-36-0]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-136-2019-07-04
+
+
 Version 1.35.0 (2019-05-23)
 ==========================
 
@@ -62,7 +163,7 @@ Cargo
 - [You can now set `cargo:rustc-cdylib-link-arg` at build time to pass custom
   linker arguments when building a `cdylib`.][cargo/6298] Its usage is highly
   platform specific.
-  
+
 Misc
 ----
 - [The Rust toolchain is now available natively for musl based distros.][58575]

From ba12e7862c58df2155011bb165a8ae1186828bc4 Mon Sep 17 00:00:00 2001
From: Taylor Cramer <cramertj@google.com>
Date: Mon, 24 Jun 2019 17:48:21 -0700
Subject: [PATCH 7/9] Add more tests for async/await

---
 src/test/ui/async-await/async-fn-nonsend.rs   | 59 ++++++++++++
 .../ui/async-await/async-fn-nonsend.stderr    | 87 ++++++++++++++++++
 .../async-await/async-fn-send-uses-nonsend.rs | 59 ++++++++++++
 .../ui/async-await/generics-and-bounds.rs     | 90 +++++++++++++++++++
 src/test/ui/async-await/no-async-const.rs     |  8 ++
 src/test/ui/async-await/no-async-const.stderr |  8 ++
 src/test/ui/async-await/no-const-async.rs     |  9 ++
 src/test/ui/async-await/no-const-async.stderr | 18 ++++
 8 files changed, 338 insertions(+)
 create mode 100644 src/test/ui/async-await/async-fn-nonsend.rs
 create mode 100644 src/test/ui/async-await/async-fn-nonsend.stderr
 create mode 100644 src/test/ui/async-await/async-fn-send-uses-nonsend.rs
 create mode 100644 src/test/ui/async-await/generics-and-bounds.rs
 create mode 100644 src/test/ui/async-await/no-async-const.rs
 create mode 100644 src/test/ui/async-await/no-async-const.stderr
 create mode 100644 src/test/ui/async-await/no-const-async.rs
 create mode 100644 src/test/ui/async-await/no-const-async.stderr

diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs
new file mode 100644
index 0000000000000..612c1e29d82bd
--- /dev/null
+++ b/src/test/ui/async-await/async-fn-nonsend.rs
@@ -0,0 +1,59 @@
+// compile-fail
+// edition:2018
+// compile-flags: --crate-type lib
+
+#![feature(async_await)]
+
+use std::{
+    cell::RefCell,
+    fmt::Debug,
+    rc::Rc,
+};
+
+fn non_sync() -> impl Debug { RefCell::new(()) }
+
+fn non_send() -> impl Debug { Rc::new(()) }
+
+fn take_ref<T>(_: &T) {}
+
+async fn fut() {}
+
+async fn fut_arg<T>(_: T) {}
+
+async fn local_dropped_before_await() {
+    // FIXME: it'd be nice for this to be allowed in a `Send` `async fn`
+    let x = non_send();
+    drop(x);
+    fut().await;
+}
+
+async fn non_send_temporary_in_match() {
+    // We could theoretically make this work as well (produce a `Send` future)
+    // for scrutinees / temporaries that can or will
+    // be dropped prior to the match body
+    // (e.g. `Copy` types).
+    match Some(non_send()) {
+        Some(_) => fut().await,
+        None => {}
+    }
+}
+
+async fn non_sync_with_method_call() {
+    // FIXME: it'd be nice for this to work.
+    let f: &mut std::fmt::Formatter = panic!();
+    if non_sync().fmt(f).unwrap() == () {
+        fut().await;
+    }
+}
+
+fn assert_send(_: impl Send) {}
+
+pub fn pass_assert() {
+    assert_send(local_dropped_before_await());
+    //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely
+    assert_send(non_send_temporary_in_match());
+    //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely
+    assert_send(non_sync_with_method_call());
+    //~^ ERROR `dyn std::fmt::Write` cannot be sent between threads safely
+    //~^^ ERROR `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
+}
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
new file mode 100644
index 0000000000000..7776a36a28f2b
--- /dev/null
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -0,0 +1,87 @@
+error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
+  --> $DIR/async-fn-nonsend.rs:52:5
+   |
+LL |     assert_send(local_dropped_before_await());
+   |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
+   |
+   = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
+   = note: required because it appears within the type `impl std::fmt::Debug`
+   = note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `impl std::future::Future`
+note: required by `assert_send`
+  --> $DIR/async-fn-nonsend.rs:49:1
+   |
+LL | fn assert_send(_: impl Send) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
+  --> $DIR/async-fn-nonsend.rs:54:5
+   |
+LL |     assert_send(non_send_temporary_in_match());
+   |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
+   |
+   = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
+   = note: required because it appears within the type `impl std::fmt::Debug`
+   = note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `impl std::future::Future`
+note: required by `assert_send`
+  --> $DIR/async-fn-nonsend.rs:49:1
+   |
+LL | fn assert_send(_: impl Send) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely
+  --> $DIR/async-fn-nonsend.rs:56:5
+   |
+LL |     assert_send(non_sync_with_method_call());
+   |     ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely
+   |
+   = help: the trait `std::marker::Send` is not implemented for `dyn std::fmt::Write`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `&mut dyn std::fmt::Write`
+   = note: required because it appears within the type `std::fmt::Formatter<'_>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
+   = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `impl std::future::Future`
+note: required by `assert_send`
+  --> $DIR/async-fn-nonsend.rs:49:1
+   |
+LL | fn assert_send(_: impl Send) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
+  --> $DIR/async-fn-nonsend.rs:56:5
+   |
+LL |     assert_send(non_sync_with_method_call());
+   |     ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
+   |
+   = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+   = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
+   = note: required because it appears within the type `core::fmt::Void`
+   = note: required because it appears within the type `&core::fmt::Void`
+   = note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `std::slice::Iter<'_, std::fmt::ArgumentV1<'_>>`
+   = note: required because it appears within the type `std::fmt::Formatter<'_>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
+   = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `impl std::future::Future`
+note: required by `assert_send`
+  --> $DIR/async-fn-nonsend.rs:49:1
+   |
+LL | fn assert_send(_: impl Send) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs
new file mode 100644
index 0000000000000..f07fc2fceb5b6
--- /dev/null
+++ b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs
@@ -0,0 +1,59 @@
+// compile-pass
+// edition:2018
+// compile-flags: --crate-type lib
+
+#![feature(async_await)]
+
+use std::{
+    cell::RefCell,
+    fmt::Debug,
+    rc::Rc,
+};
+
+fn non_sync() -> impl Debug { RefCell::new(()) }
+
+fn non_send() -> impl Debug { Rc::new(()) }
+
+fn take_ref<T>(_: &T) {}
+
+async fn fut() {}
+
+async fn fut_arg<T>(_: T) {}
+
+async fn still_send() {
+    fut().await;
+    println!("{:?} {:?}", non_send(), non_sync());
+    fut().await;
+    drop(non_send());
+    drop(non_sync());
+    fut().await;
+    fut_arg(non_sync()).await;
+
+    // Note: all temporaries in `if let` and `match` scrutinee
+    // are dropped at the *end* of the blocks, so using `non_send()`
+    // in either of those positions with an await in the middle will
+    // cause a `!Send` future. It might be nice in the future to allow
+    // this for `Copy` types, since they can be "dropped" early without
+    // affecting the end user.
+    if let Some(_) = Some(non_sync()) {
+        fut().await;
+    }
+    match Some(non_sync()) {
+        Some(_) => fut().await,
+        None => fut().await,
+    }
+
+    let _ = non_send();
+    fut().await;
+
+    {
+        let _x = non_send();
+    }
+    fut().await;
+}
+
+fn assert_send(_: impl Send) {}
+
+pub fn pass_assert() {
+    assert_send(still_send());
+}
diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs
new file mode 100644
index 0000000000000..913f1435c6adf
--- /dev/null
+++ b/src/test/ui/async-await/generics-and-bounds.rs
@@ -0,0 +1,90 @@
+// compile-pass
+// edition:2018
+// compile-flags: --crate-type lib
+
+#![feature(async_await)]
+
+use std::future::Future;
+
+pub async fn simple_generic<T>() {}
+
+pub trait Foo {
+    fn foo(&self) {}
+}
+
+struct FooType;
+impl Foo for FooType {}
+
+pub async fn call_generic_bound<F: Foo>(f: F) {
+    f.foo()
+}
+
+pub async fn call_where_clause<F>(f: F)
+where
+    F: Foo,
+{
+    f.foo()
+}
+
+pub async fn call_impl_trait(f: impl Foo) {
+    f.foo()
+}
+
+pub async fn call_with_ref(f: &impl Foo) {
+    f.foo()
+}
+
+pub fn async_fn_with_same_generic_params_unifies() {
+    let mut a = call_generic_bound(FooType);
+    a = call_generic_bound(FooType);
+
+    let mut b = call_where_clause(FooType);
+    b = call_where_clause(FooType);
+
+    let mut c = call_impl_trait(FooType);
+    c = call_impl_trait(FooType);
+
+    let f_one = FooType;
+    let f_two = FooType;
+    let mut d = call_with_ref(&f_one);
+    d = call_with_ref(&f_two);
+}
+
+pub fn simple_generic_block<T>() -> impl Future<Output = ()> {
+    async move {}
+}
+
+pub fn call_generic_bound_block<F: Foo>(f: F) -> impl Future<Output = ()> {
+    async move { f.foo() }
+}
+
+pub fn call_where_clause_block<F>(f: F) -> impl Future<Output = ()>
+where
+    F: Foo,
+{
+    async move { f.foo() }
+}
+
+pub fn call_impl_trait_block(f: impl Foo) -> impl Future<Output = ()> {
+    async move { f.foo() }
+}
+
+pub fn call_with_ref_block<'a>(f: &'a (impl Foo + 'a)) -> impl Future<Output = ()> + 'a {
+    async move { f.foo() }
+}
+
+pub fn async_block_with_same_generic_params_unifies() {
+    let mut a = call_generic_bound_block(FooType);
+    a = call_generic_bound_block(FooType);
+
+    let mut b = call_where_clause_block(FooType);
+    b = call_where_clause_block(FooType);
+
+    let mut c = call_impl_trait_block(FooType);
+    c = call_impl_trait_block(FooType);
+
+    let f_one = FooType;
+    let f_two = FooType;
+    let mut d = call_with_ref_block(&f_one);
+    d = call_with_ref_block(&f_two);
+}
diff --git a/src/test/ui/async-await/no-async-const.rs b/src/test/ui/async-await/no-async-const.rs
new file mode 100644
index 0000000000000..1db314a5aa208
--- /dev/null
+++ b/src/test/ui/async-await/no-async-const.rs
@@ -0,0 +1,8 @@
+// compile-fail
+// edition:2018
+// compile-flags: --crate-type lib
+
+#![feature(async_await)]
+
+pub async const fn x() {}
+//~^ ERROR expected one of `fn` or `unsafe`, found `const`
diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr
new file mode 100644
index 0000000000000..cdb1c6e2d7bd9
--- /dev/null
+++ b/src/test/ui/async-await/no-async-const.stderr
@@ -0,0 +1,8 @@
+error: expected one of `fn` or `unsafe`, found `const`
+  --> $DIR/no-async-const.rs:7:11
+   |
+LL | pub async const fn x() {}
+   |           ^^^^^ expected one of `fn` or `unsafe` here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs
new file mode 100644
index 0000000000000..9f09d2188c7c0
--- /dev/null
+++ b/src/test/ui/async-await/no-const-async.rs
@@ -0,0 +1,9 @@
+// compile-fail
+// edition:2018
+// compile-flags: --crate-type lib
+
+#![feature(async_await)]
+
+pub const async fn x() {}
+//~^ ERROR expected identifier, found reserved keyword `async`
+//~^^ expected `:`, found keyword `fn`
diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr
new file mode 100644
index 0000000000000..693fbf186f913
--- /dev/null
+++ b/src/test/ui/async-await/no-const-async.stderr
@@ -0,0 +1,18 @@
+error: expected identifier, found reserved keyword `async`
+  --> $DIR/no-const-async.rs:7:11
+   |
+LL | pub const async fn x() {}
+   |           ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | pub const r#async fn x() {}
+   |           ^^^^^^^
+
+error: expected `:`, found keyword `fn`
+  --> $DIR/no-const-async.rs:7:17
+   |
+LL | pub const async fn x() {}
+   |                 ^^ expected `:`
+
+error: aborting due to 2 previous errors
+

From 57db25e614dfc3ea3c407374a562501471eb1c5d Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Tue, 25 Jun 2019 21:37:25 +0300
Subject: [PATCH 8/9] cleanup: rename name_from to symbol_from

Lexer uses Symbols for a lot of stuff, not only for identifiers, so
the "name" terminology is just confusing.
---
 src/libsyntax/parse/lexer/mod.rs | 39 ++++++++++++++++----------------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 7b9e3bc4d5102..4e4fe4256c9b0 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,4 +1,3 @@
-use crate::ast;
 use crate::parse::ParseSess;
 use crate::parse::token::{self, Token, TokenKind};
 use crate::symbol::{sym, Symbol};
@@ -328,14 +327,14 @@ impl<'a> StringReader<'a> {
         self.str_from_to(start, self.pos)
     }
 
-    /// Creates a Name from a given offset to the current offset.
-    fn name_from(&self, start: BytePos) -> ast::Name {
+    /// Creates a Symbol from a given offset to the current offset.
+    fn symbol_from(&self, start: BytePos) -> Symbol {
         debug!("taking an ident from {:?} to {:?}", start, self.pos);
         Symbol::intern(self.str_from(start))
     }
 
-    /// As name_from, with an explicit endpoint.
-    fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
+    /// As symbol_from, with an explicit endpoint.
+    fn symbol_from_to(&self, start: BytePos, end: BytePos) -> Symbol {
         debug!("taking an ident from {:?} to {:?}", start, end);
         Symbol::intern(self.str_from_to(start, end))
     }
@@ -440,7 +439,7 @@ impl<'a> StringReader<'a> {
     }
 
     /// Eats <XID_start><XID_continue>*, if possible.
-    fn scan_optional_raw_name(&mut self) -> Option<ast::Name> {
+    fn scan_optional_raw_name(&mut self) -> Option<Symbol> {
         if !ident_start(self.ch) {
             return None;
         }
@@ -508,7 +507,7 @@ impl<'a> StringReader<'a> {
                     }
 
                     let kind = if doc_comment {
-                        token::DocComment(self.name_from(start_bpos))
+                        token::DocComment(self.symbol_from(start_bpos))
                     } else {
                         token::Comment
                     };
@@ -537,7 +536,7 @@ impl<'a> StringReader<'a> {
                         self.bump();
                     }
                     return Some(Token::new(
-                        token::Shebang(self.name_from(start)),
+                        token::Shebang(self.symbol_from(start)),
                         self.mk_sp(start, self.pos),
                     ));
                 }
@@ -719,17 +718,17 @@ impl<'a> StringReader<'a> {
             let pos = self.pos;
             self.check_float_base(start_bpos, pos, base);
 
-            (token::Float, self.name_from(start_bpos))
+            (token::Float, self.symbol_from(start_bpos))
         } else {
             // it might be a float if it has an exponent
             if self.ch_is('e') || self.ch_is('E') {
                 self.scan_float_exponent();
                 let pos = self.pos;
                 self.check_float_base(start_bpos, pos, base);
-                return (token::Float, self.name_from(start_bpos));
+                return (token::Float, self.symbol_from(start_bpos));
             }
             // but we certainly have an integer!
-            (token::Integer, self.name_from(start_bpos))
+            (token::Integer, self.symbol_from(start_bpos))
         }
     }
 
@@ -831,7 +830,7 @@ impl<'a> StringReader<'a> {
                 }
 
                 // FIXME: perform NFKC normalization here. (Issue #2253)
-                let name = self.name_from(start);
+                let name = self.symbol_from(start);
                 if is_raw_ident {
                     let span = self.mk_sp(raw_start, self.pos);
                     if !name.can_be_raw() {
@@ -1006,7 +1005,7 @@ impl<'a> StringReader<'a> {
                     // lifetimes shouldn't end with a single quote
                     // if we find one, then this is an invalid character literal
                     if self.ch_is('\'') {
-                        let symbol = self.name_from(start);
+                        let symbol = self.symbol_from(start);
                         self.bump();
                         self.validate_char_escape(start_with_quote);
                         return Ok(TokenKind::lit(token::Char, symbol, None));
@@ -1024,7 +1023,7 @@ impl<'a> StringReader<'a> {
                     // Include the leading `'` in the real identifier, for macro
                     // expansion purposes. See #12512 for the gory details of why
                     // this is necessary.
-                    return Ok(token::Lifetime(self.name_from(start_with_quote)));
+                    return Ok(token::Lifetime(self.symbol_from(start_with_quote)));
                 }
                 let msg = "unterminated character literal";
                 let symbol = self.scan_single_quoted_string(start_with_quote, msg);
@@ -1052,7 +1051,7 @@ impl<'a> StringReader<'a> {
                     },
                     Some('r') => {
                         let (start, end, hash_count) = self.scan_raw_string();
-                        let symbol = self.name_from_to(start, end);
+                        let symbol = self.symbol_from_to(start, end);
                         self.validate_raw_byte_str_escape(start, end);
 
                         (token::ByteStrRaw(hash_count), symbol)
@@ -1073,7 +1072,7 @@ impl<'a> StringReader<'a> {
             }
             'r' => {
                 let (start, end, hash_count) = self.scan_raw_string();
-                let symbol = self.name_from_to(start, end);
+                let symbol = self.symbol_from_to(start, end);
                 self.validate_raw_str_escape(start, end);
                 let suffix = self.scan_optional_raw_name();
 
@@ -1174,7 +1173,7 @@ impl<'a> StringReader<'a> {
 
     fn scan_single_quoted_string(&mut self,
                                  start_with_quote: BytePos,
-                                 unterminated_msg: &str) -> ast::Name {
+                                 unterminated_msg: &str) -> Symbol {
         // assumes that first `'` is consumed
         let start = self.pos;
         // lex `'''` as a single char, for recovery
@@ -1206,12 +1205,12 @@ impl<'a> StringReader<'a> {
             }
         }
 
-        let id = self.name_from(start);
+        let id = self.symbol_from(start);
         self.bump();
         id
     }
 
-    fn scan_double_quoted_string(&mut self, unterminated_msg: &str) -> ast::Name {
+    fn scan_double_quoted_string(&mut self, unterminated_msg: &str) -> Symbol {
         debug_assert!(self.ch_is('\"'));
         let start_with_quote = self.pos;
         self.bump();
@@ -1226,7 +1225,7 @@ impl<'a> StringReader<'a> {
             }
             self.bump();
         }
-        let id = self.name_from(start);
+        let id = self.symbol_from(start);
         self.bump();
         id
     }

From 390f717a0af5851271792da9ff235c95f3db2556 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 25 Jun 2019 22:59:00 +0200
Subject: [PATCH 9/9] tweak wording

---
 src/libstd/io/mod.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 7fba844897ffe..3d0568c16cdf6 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -509,10 +509,10 @@ pub trait Read {
     /// contents of `buf` being true. It is recommended that *implementations*
     /// only write data to `buf` instead of reading its contents.
     ///
-    /// Correspondingly, however, *users* of this trait may not assume any guarantees
+    /// Correspondingly, however, *callers* of this method may not assume any guarantees
     /// about how the implementation uses `buf`. The trait is safe to implement,
-    /// so it is perfectly possible that the implementation might inspect that data.
-    /// As a caller, it is your responsibility to make sure that `buf` is initialized
+    //  so it is possible that the code that's supposed to write to the buffer might also read
+    //  from it. It is your responsibility to make sure that `buf` is initialized
     /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one
     /// obtains via [`MaybeUninit<T>`]) is not safe, and can lead to undefined behavior.
     ///