about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorDenys Zariaiev <denys.zariaiev@gmail.com>2019-03-13 21:00:45 +0100
committerDenys Zariaiev <denys.zariaiev@gmail.com>2019-03-13 21:00:45 +0100
commiteeb5f171da2486c34e4e473c97a1468279d05e7c (patch)
treeb452442f799d5d62141419e7091de13c212de9ff /src/libsyntax
parent5c7ec6c421af26666d3ec1c5fe022d099133951c (diff)
parent8bf1f1c8f4100247c1f9b3d9b7aecea5c970263e (diff)
downloadrust-eeb5f171da2486c34e4e473c97a1468279d05e7c.tar.gz
rust-eeb5f171da2486c34e4e473c97a1468279d05e7c.zip
Merge remote-tracking branch 'upstream/master' into asm-compile-tests
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/Cargo.toml2
-rw-r--r--src/libsyntax/ast.rs8
-rw-r--r--src/libsyntax/attr/builtin.rs48
-rw-r--r--src/libsyntax/ext/build.rs4
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs2
-rw-r--r--src/libsyntax/ext/tt/quoted.rs18
-rw-r--r--src/libsyntax/feature_gate.rs38
-rw-r--r--src/libsyntax/mut_visit.rs19
-rw-r--r--src/libsyntax/parse/attr.rs22
-rw-r--r--src/libsyntax/parse/lexer/mod.rs20
-rw-r--r--src/libsyntax/parse/mod.rs15
-rw-r--r--src/libsyntax/parse/parser.rs264
-rw-r--r--src/libsyntax/parse/token.rs21
-rw-r--r--src/libsyntax/print/pprust.rs12
-rw-r--r--src/libsyntax/ptr.rs39
-rw-r--r--src/libsyntax/test_snippet.rs2
-rw-r--r--src/libsyntax/tokenstream.rs2
-rw-r--r--src/libsyntax/visit.rs17
18 files changed, 307 insertions, 246 deletions
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index 4a0bb0302ff..71c2ab82f65 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -13,7 +13,7 @@ crate-type = ["dylib"]
 bitflags = "1.0"
 serialize = { path = "../libserialize" }
 log = "0.4"
-scoped-tls = "0.1"
+scoped-tls = "1.0"
 syntax_pos = { path = "../libsyntax_pos" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 9c4945d74db..a01a5bb0a36 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1643,6 +1643,8 @@ pub enum TyKind {
     Mac(Mac),
     /// Placeholder for a kind that has failed to be defined.
     Err,
+    /// Placeholder for a `va_list`.
+    CVarArgs,
 }
 
 impl TyKind {
@@ -1802,7 +1804,7 @@ impl Arg {
 pub struct FnDecl {
     pub inputs: Vec<Arg>,
     pub output: FunctionRetTy,
-    pub variadic: bool,
+    pub c_variadic: bool,
 }
 
 impl FnDecl {
@@ -2216,7 +2218,7 @@ impl Item {
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
-    pub asyncness: IsAsync,
+    pub asyncness: Spanned<IsAsync>,
     pub constness: Spanned<Constness>,
     pub abi: Abi,
 }
@@ -2225,7 +2227,7 @@ impl Default for FnHeader {
     fn default() -> FnHeader {
         FnHeader {
             unsafety: Unsafety::Normal,
-            asyncness: IsAsync::NotAsync,
+            asyncness: dummy_spanned(IsAsync::NotAsync),
             constness: dummy_spanned(Constness::NotConst),
             abi: Abi::Rust,
         }
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index e84adc01cf0..f7a000935ca 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -7,7 +7,7 @@ use crate::parse::ParseSess;
 use errors::{Applicability, Handler};
 use syntax_pos::{symbol::Symbol, Span};
 
-use super::{list_contains_name, mark_used, MetaItemKind};
+use super::{mark_used, MetaItemKind};
 
 enum AttrError {
     MultipleItem(Name),
@@ -79,40 +79,26 @@ pub enum UnwindAttr {
 
 /// Determine what `#[unwind]` attribute is present in `attrs`, if any.
 pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
-    let syntax_error = |attr: &Attribute| {
-        mark_used(attr);
-        diagnostic.map(|d| {
-            span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
-        });
-        None
-    };
-
     attrs.iter().fold(None, |ia, attr| {
-        if attr.path != "unwind" {
-            return ia;
-        }
-        let meta = match attr.meta() {
-            Some(meta) => meta.node,
-            None => return ia,
-        };
-        match meta {
-            MetaItemKind::Word => {
-                syntax_error(attr)
-            }
-            MetaItemKind::List(ref items) => {
-                mark_used(attr);
-                if items.len() != 1 {
-                    syntax_error(attr)
-                } else if list_contains_name(&items[..], "allowed") {
-                    Some(UnwindAttr::Allowed)
-                } else if list_contains_name(&items[..], "aborts") {
-                    Some(UnwindAttr::Aborts)
-                } else {
-                    syntax_error(attr)
+        if attr.check_name("unwind") {
+            if let Some(meta) = attr.meta() {
+                if let MetaItemKind::List(items) = meta.node {
+                    if items.len() == 1 {
+                        if items[0].check_name("allowed") {
+                            return Some(UnwindAttr::Allowed);
+                        } else if items[0].check_name("aborts") {
+                            return Some(UnwindAttr::Aborts);
+                        }
+                    }
+
+                    diagnostic.map(|d| {
+                        span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
+                    });
                 }
             }
-            _ => ia,
         }
+
+        ia
     })
 }
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 27b0cfb1630..e95f0589449 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -985,7 +985,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         P(ast::FnDecl {
             inputs,
             output,
-            variadic: false
+            c_variadic: false
         })
     }
 
@@ -1017,7 +1017,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                   ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)),
                               ast::FnHeader {
                                   unsafety: ast::Unsafety::Normal,
-                                  asyncness: ast::IsAsync::NotAsync,
+                                  asyncness: dummy_spanned(ast::IsAsync::NotAsync),
                                   constness: dummy_spanned(ast::Constness::NotConst),
                                   abi: Abi::Rust,
                               },
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index fe1cffb092b..1a419e7fada 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -761,7 +761,7 @@ pub fn parse(
         else if bb_items.is_empty() && next_items.is_empty() {
             return Failure(
                 parser.span,
-                parser.token,
+                parser.token.clone(),
                 "no rules expected this token in macro call",
             );
         }
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs
index 255795f28c7..b24edb57e52 100644
--- a/src/libsyntax/ext/tt/quoted.rs
+++ b/src/libsyntax/ext/tt/quoted.rs
@@ -475,11 +475,13 @@ where
                 // #1 is a separator and #2 should be a KleepeOp.
                 // (N.B. We need to advance the input iterator.)
                 match parse_kleene_op(input, span) {
-                    // #2 is `?`, which is not allowed as a Kleene op in 2015 edition.
+                    // #2 is `?`, which is not allowed as a Kleene op in 2015 edition,
+                    // but is allowed in the 2018 edition.
                     Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => {
                         sess.span_diagnostic
                             .struct_span_err(op2_span, "expected `*` or `+`")
-                            .note("`?` is not a macro repetition operator")
+                            .note("`?` is not a macro repetition operator in the 2015 edition, \
+                                 but is accepted in the 2018 edition")
                             .emit();
 
                         // Return a dummy
@@ -507,10 +509,12 @@ where
                     Err(_) => op1_span,
                 }
             } else {
-                // `?` is not allowed as a Kleene op in 2015
+                // `?` is not allowed as a Kleene op in 2015,
+                // but is allowed in the 2018 edition
                 sess.span_diagnostic
                     .struct_span_err(op1_span, "expected `*` or `+`")
-                    .note("`?` is not a macro repetition operator")
+                    .note("`?` is not a macro repetition operator in the 2015 edition, \
+                         but is accepted in the 2018 edition")
                     .emit();
 
                 // Return a dummy
@@ -520,11 +524,13 @@ where
 
         // #1 is a separator followed by #2, a KleeneOp
         Ok(Err((tok, span))) => match parse_kleene_op(input, span) {
-            // #2 is a `?`, which is not allowed as a Kleene op in 2015 edition.
+            // #2 is a `?`, which is not allowed as a Kleene op in 2015 edition,
+            // but is allowed in the 2018 edition
             Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => {
                 sess.span_diagnostic
                     .struct_span_err(op2_span, "expected `*` or `+`")
-                    .note("`?` is not a macro repetition operator")
+                    .note("`?` is not a macro repetition operator in the 2015 edition, \
+                        but is accepted in the 2018 edition")
                     .emit();
 
                 // Return a dummy
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index c9b441193b7..279e2089f5d 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -21,8 +21,9 @@ use crate::early_buffered_lints::BufferedEarlyLintId;
 use crate::source_map::Spanned;
 use crate::edition::{ALL_EDITIONS, Edition};
 use crate::visit::{self, FnKind, Visitor};
-use crate::parse::ParseSess;
+use crate::parse::{token, ParseSess};
 use crate::symbol::Symbol;
+use crate::tokenstream::TokenTree;
 
 use errors::{DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
@@ -232,8 +233,8 @@ declare_features! (
 
     // Allows `#[unwind(..)]`.
     //
-    // rustc internal for rust runtime
-    (active, unwind_attributes, "1.4.0", None, None),
+    // Permits specifying whether a function should permit unwinding or abort on unwind.
+    (active, unwind_attributes, "1.4.0", Some(58760), None),
 
     // Allows the use of `#[naked]` on functions.
     (active, naked_functions, "1.9.0", Some(32408), None),
@@ -431,9 +432,6 @@ declare_features! (
     // Added for testing E0705; perma-unstable.
     (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
 
-    // support for arbitrary delimited token streams in non-macro attributes
-    (active, unrestricted_attribute_tokens, "1.30.0", Some(55208), None),
-
     // Allows unsized rvalues at arguments and parameters.
     (active, unsized_locals, "1.30.0", Some(48055), None),
 
@@ -473,6 +471,9 @@ declare_features! (
 
     // #[repr(align(X))] on enums
     (active, repr_align_enum, "1.34.0", Some(57996), None),
+
+    // Allows the use of C-variadics
+    (active, c_variadic, "1.34.0", Some(44930), None),
 );
 
 declare_features! (
@@ -700,6 +701,8 @@ declare_features! (
     (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
     // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`.
     (accepted, extern_crate_self, "1.34.0", Some(56409), None),
+    // support for arbitrary delimited token streams in non-macro attributes
+    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
 );
 
 // If you change this, please modify `src/doc/unstable-book` as well. You must
@@ -1173,7 +1176,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
            "dropck_eyepatch",
            "may_dangle has unstable semantics and may be removed in the future",
            cfg_fn!(dropck_eyepatch))),
-    ("unwind", Whitelisted, template!(List: "allowed"), Gated(Stability::Unstable,
+    ("unwind", Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
                                   "unwind_attributes",
                                   "#[unwind] is experimental",
                                   cfg_fn!(unwind_attributes))),
@@ -1660,13 +1663,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
         match BUILTIN_ATTRIBUTES.iter().find(|(name, ..)| attr.path == name) {
             Some(&(name, _, template, _)) => self.check_builtin_attribute(attr, name, template),
-            None => if !self.context.features.unrestricted_attribute_tokens {
-                // Unfortunately, `parse_meta` cannot be called speculatively
-                // because it can report errors by itself, so we have to call it
-                // only if the feature is disabled.
-                if let Err(mut err) = attr.parse_meta(self.context.parse_sess) {
-                    err.help("try enabling `#![feature(unrestricted_attribute_tokens)]`").emit()
-                }
+            None => if let Some(TokenTree::Token(_, token::Eq)) = attr.tokens.trees().next() {
+                // All key-value attributes are restricted to meta-item syntax.
+                attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok();
             }
         }
     }
@@ -1902,9 +1901,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match fn_kind {
             FnKind::ItemFn(_, header, _, _) => {
                 // Check for const fn and async fn declarations.
-                if header.asyncness.is_async() {
+                if header.asyncness.node.is_async() {
                     gate_feature_post!(&self, async_await, span, "async fn is unstable");
                 }
+
+                if fn_decl.c_variadic {
+                    gate_feature_post!(&self, c_variadic, span,
+                                       "C-varaidic functions are unstable");
+                }
                 // Stability of const fn methods are covered in
                 // `visit_trait_item` and `visit_impl_item` below; this is
                 // because default methods don't pass through this point.
@@ -1933,6 +1937,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 if block.is_none() {
                     self.check_abi(sig.header.abi, ti.span);
                 }
+                if sig.decl.c_variadic {
+                    gate_feature_post!(&self, c_variadic, ti.span,
+                                       "C-varaidic functions are unstable");
+                }
                 if sig.header.constness.node == ast::Constness::Const {
                     gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
                 }
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 86849f580d0..802b7808695 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -21,6 +21,7 @@ use syntax_pos::Span;
 
 use rustc_data_structures::sync::Lrc;
 use std::ops::DerefMut;
+use std::{panic, process, ptr};
 
 pub trait ExpectOne<A: Array> {
     fn expect_one(self, err: &'static str) -> A::Item;
@@ -305,11 +306,18 @@ pub trait MutVisitor: Sized {
 
 /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
 /// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
-/// method.
+/// method. Abort the program if the closure panics.
 //
 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
 pub fn visit_clobber<T, F>(t: &mut T, f: F) where F: FnOnce(T) -> T {
-    unsafe { std::ptr::write(t, f(std::ptr::read(t))); }
+    unsafe {
+        // Safe because `t` is used in a read-only fashion by `read()` before
+        // being overwritten by `write()`.
+        let old_t = ptr::read(t);
+        let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t)))
+            .unwrap_or_else(|_| process::abort());
+        ptr::write(t, new_t);
+    }
 }
 
 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
@@ -401,7 +409,8 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
     let Ty { id, node, span } = ty.deref_mut();
     vis.visit_id(id);
     match node {
-        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never => {}
+        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err |
+            TyKind::Never | TyKind::CVarArgs => {}
         TyKind::Slice(ty) => vis.visit_ty(ty),
         TyKind::Ptr(mt) => vis.visit_mt(mt),
         TyKind::Rptr(lt, mt) => {
@@ -672,7 +681,7 @@ pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T)
 }
 
 pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) {
-    let FnDecl { inputs, output, variadic: _ } = decl.deref_mut();
+    let FnDecl { inputs, output, c_variadic: _ } = decl.deref_mut();
     visit_vec(inputs, |input| vis.visit_arg(input));
     match output {
         FunctionRetTy::Default(span) => vis.visit_span(span),
@@ -926,7 +935,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
 
 pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
     let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header;
-    vis.visit_asyncness(asyncness);
+    vis.visit_asyncness(&mut asyncness.node);
 }
 
 pub fn noop_visit_mod<T: MutVisitor>(Mod { inner, items, inline: _ }: &mut Mod, vis: &mut T) {
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 9020c8c6a2d..e93e15f9012 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -158,11 +158,21 @@ impl<'a> Parser<'a> {
                    self.parse_token_tree().into()
             } else if self.eat(&token::Eq) {
                 let eq = TokenTree::Token(self.prev_span, token::Eq);
-                let tree = match self.token {
-                    token::CloseDelim(_) | token::Eof => self.unexpected()?,
-                    _ => self.parse_token_tree(),
+                let mut is_interpolated_expr = false;
+                if let token::Interpolated(nt) = &self.token {
+                    if let token::NtExpr(..) = **nt {
+                        is_interpolated_expr = true;
+                    }
+                }
+                let tokens = if is_interpolated_expr {
+                    // We need to accept arbitrary interpolated expressions to continue
+                    // supporting things like `doc = $expr` that work on stable.
+                    // Non-literal interpolated expressions are rejected after expansion.
+                    self.parse_token_tree().into()
+                } else {
+                    self.parse_unsuffixed_lit()?.tokens()
                 };
-                TokenStream::new(vec![eq.into(), tree.into()])
+                TokenStream::from_streams(vec![eq.into(), tokens])
             } else {
                 TokenStream::empty()
             };
@@ -275,8 +285,8 @@ impl<'a> Parser<'a> {
         }
 
         let found = self.this_token_to_string();
-        let msg = format!("expected unsuffixed literal or identifier, found {}", found);
-        Err(self.diagnostic().struct_span_err(lo, &msg))
+        let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
+        Err(self.diagnostic().struct_span_err(self.span, &msg))
     }
 
     /// matches meta_seq = ( COMMASEP(meta_item_inner) )
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index a7cde5fbb92..01e3b292903 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1423,15 +1423,17 @@ impl<'a> StringReader<'a> {
 
                 // If the character is an ident start not followed by another single
                 // quote, then this is a lifetime name:
-                if ident_start(Some(c2)) && !self.ch_is('\'') {
+                if (ident_start(Some(c2)) || c2.is_numeric()) && !self.ch_is('\'') {
                     while ident_continue(self.ch) {
                         self.bump();
                     }
                     // lifetimes shouldn't end with a single quote
                     // if we find one, then this is an invalid character literal
                     if self.ch_is('\'') {
-                        self.err_span_(start_with_quote, self.next_pos,
-                                "character literal may only contain one codepoint");
+                        self.err_span_(
+                            start_with_quote,
+                            self.next_pos,
+                            "character literal may only contain one codepoint");
                         self.bump();
                         return Ok(token::Literal(token::Err(Symbol::intern("??")), None))
 
@@ -1444,6 +1446,15 @@ impl<'a> StringReader<'a> {
                         self.mk_ident(&format!("'{}", lifetime_name))
                     });
 
+                    if c2.is_numeric() {
+                        // this is a recovered lifetime written `'1`, error but accept it
+                        self.err_span_(
+                            start_with_quote,
+                            self.pos,
+                            "lifetimes cannot start with a number",
+                        );
+                    }
+
                     return Ok(token::Lifetime(ident));
                 }
 
@@ -1873,6 +1884,7 @@ fn is_block_doc_comment(s: &str) -> bool {
     res
 }
 
+/// Determine whether `c` is a valid start for an ident.
 fn ident_start(c: Option<char>) -> bool {
     let c = match c {
         Some(c) => c,
@@ -1920,7 +1932,7 @@ mod tests {
                                                           false,
                                                           false);
         ParseSess {
-            span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)),
+            span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)),
             unstable_features: UnstableFeatures::from_environment(),
             config: CrateConfig::default(),
             included_mod_stack: Lock::new(Vec::new()),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b2d4d97d57d..371e8fe5cf6 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -6,6 +6,7 @@ use crate::source_map::{SourceMap, FilePathMapping};
 use crate::feature_gate::UnstableFeatures;
 use crate::parse::parser::Parser;
 use crate::symbol::Symbol;
+use crate::syntax::parse::parser::emit_unclosed_delims;
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::diagnostics::plugin::ErrorMap;
 use crate::print::pprust::token_to_string;
@@ -53,7 +54,7 @@ impl ParseSess {
         let cm = Lrc::new(SourceMap::new(file_path_mapping));
         let handler = Handler::with_tty_emitter(ColorConfig::Auto,
                                                 true,
-                                                false,
+                                                None,
                                                 Some(cm.clone()));
         ParseSess::with_span_handler(handler, cm)
     }
@@ -141,8 +142,14 @@ pub fn parse_stream_from_source_str(
     source: String,
     sess: &ParseSess,
     override_span: Option<Span>,
-) -> (TokenStream, Vec<lexer::UnmatchedBrace>) {
-    source_file_to_stream(sess, sess.source_map().new_source_file(name, source), override_span)
+) -> TokenStream {
+    let (stream, mut errors) = source_file_to_stream(
+        sess,
+        sess.source_map().new_source_file(name, source),
+        override_span,
+    );
+    emit_unclosed_delims(&mut errors, &sess.span_diagnostic);
+    stream
 }
 
 /// Creates a new parser from a source string.
@@ -178,7 +185,7 @@ pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path)
 /// Given a session, a crate config, a path, and a span, add
 /// the file at the given path to the source_map, and return a parser.
 /// On an error, use the given span as the source of the problem.
-crate fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
+pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
                                     path: &Path,
                                     directory_ownership: DirectoryOwnership,
                                     module_name: Option<String>,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 7e900dfeb1e..fe31311094b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -46,7 +46,7 @@ use crate::ThinVec;
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
 use crate::symbol::{Symbol, keywords};
 
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{Span, MultiSpan, BytePos, FileName};
 use log::{debug, trace};
@@ -256,8 +256,15 @@ pub struct Parser<'a> {
     /// it gets removed from here. Every entry left at the end gets emitted as an independent
     /// error.
     crate unclosed_delims: Vec<UnmatchedBrace>,
+    last_unexpected_token_span: Option<Span>,
 }
 
+impl<'a> Drop for Parser<'a> {
+    fn drop(&mut self) {
+        let diag = self.diagnostic();
+        emit_unclosed_delims(&mut self.unclosed_delims, diag);
+    }
+}
 
 #[derive(Clone)]
 struct TokenCursor {
@@ -582,6 +589,7 @@ impl<'a> Parser<'a> {
             unmatched_angle_bracket_count: 0,
             max_angle_bracket_count: 0,
             unclosed_delims: Vec::new(),
+            last_unexpected_token_span: None,
         };
 
         let tok = parser.next_tok();
@@ -775,6 +783,8 @@ impl<'a> Parser<'a> {
         } else if inedible.contains(&self.token) {
             // leave it in the input
             Ok(false)
+        } else if self.last_unexpected_token_span == Some(self.span) {
+            FatalError.raise();
         } else {
             let mut expected = edible.iter()
                 .map(|x| TokenType::Token(x.clone()))
@@ -802,6 +812,7 @@ impl<'a> Parser<'a> {
                  (self.sess.source_map().next_point(self.prev_span),
                   format!("expected {} here", expect)))
             };
+            self.last_unexpected_token_span = Some(self.span);
             let mut err = self.fatal(&msg_exp);
             if self.token.is_ident_named("and") {
                 err.span_suggestion_short(
@@ -1457,12 +1468,12 @@ impl<'a> Parser<'a> {
         };
 
         self.expect_keyword(keywords::Fn)?;
-        let (inputs, variadic) = self.parse_fn_args(false, true)?;
+        let (inputs, c_variadic) = self.parse_fn_args(false, true)?;
         let ret_ty = self.parse_ret_ty(false)?;
         let decl = P(FnDecl {
             inputs,
             output: ret_ty,
-            variadic,
+            c_variadic,
         });
         Ok(TyKind::BareFn(P(BareFnTy {
             abi,
@@ -1497,9 +1508,13 @@ impl<'a> Parser<'a> {
     pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
         maybe_whole!(self, NtTraitItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
+        let mut unclosed_delims = vec![];
         let (mut item, tokens) = self.collect_tokens(|this| {
-            this.parse_trait_item_(at_end, attrs)
+            let item = this.parse_trait_item_(at_end, attrs);
+            unclosed_delims.append(&mut this.unclosed_delims);
+            item
         })?;
+        self.unclosed_delims.append(&mut unclosed_delims);
         // See `parse_item` for why this clause is here.
         if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
             item.tokens = Some(tokens);
@@ -1543,7 +1558,7 @@ impl<'a> Parser<'a> {
                 // definition...
 
                 // We don't allow argument names to be left off in edition 2018.
-                p.parse_arg_general(p.span.rust_2018(), true)
+                p.parse_arg_general(p.span.rust_2018(), true, false)
             })?;
             generics.where_clause = self.parse_where_clause()?;
 
@@ -1613,7 +1628,7 @@ impl<'a> Parser<'a> {
     /// Parses an optional return type `[ -> TY ]` in a function declaration.
     fn parse_ret_ty(&mut self, allow_plus: bool) -> PResult<'a, FunctionRetTy> {
         if self.eat(&token::RArrow) {
-            Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true)?))
+            Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true, false)?))
         } else {
             Ok(FunctionRetTy::Default(self.span.shrink_to_lo()))
         }
@@ -1621,7 +1636,7 @@ impl<'a> Parser<'a> {
 
     /// Parses a type.
     pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
-        self.parse_ty_common(true, true)
+        self.parse_ty_common(true, true, false)
     }
 
     /// Parses a type in restricted contexts where `+` is not permitted.
@@ -1631,11 +1646,11 @@ impl<'a> Parser<'a> {
     /// Example 2: `value1 as TYPE + value2`
     ///     `+` is prohibited to avoid interactions with expression grammar.
     fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
-        self.parse_ty_common(false, true)
+        self.parse_ty_common(false, true, false)
     }
 
-    fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
-                       -> PResult<'a, P<Ty>> {
+    fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool,
+                       allow_c_variadic: bool) -> PResult<'a, P<Ty>> {
         maybe_whole!(self, NtTy, |x| x);
 
         let lo = self.span;
@@ -1772,6 +1787,15 @@ impl<'a> Parser<'a> {
                     TyKind::Path(None, path)
                 }
             }
+        } else if self.check(&token::DotDotDot) {
+            if allow_c_variadic {
+                self.eat(&token::DotDotDot);
+                TyKind::CVarArgs
+            } else {
+                return Err(self.fatal(
+                    "only foreign functions are allowed to be C-variadic"
+                ));
+            }
         } else {
             let msg = format!("expected type, found {}", self.this_token_descr());
             return Err(self.fatal(&msg));
@@ -1794,7 +1818,7 @@ impl<'a> Parser<'a> {
         let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
         if parse_plus {
             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
-            bounds.append(&mut self.parse_generic_bounds(None)?);
+            bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?);
         }
         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
     }
@@ -1959,7 +1983,8 @@ impl<'a> Parser<'a> {
     }
 
     /// This version of parse arg doesn't necessarily require identifier names.
-    fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool) -> PResult<'a, Arg> {
+    fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool,
+                         allow_c_variadic: bool) -> PResult<'a, Arg> {
         maybe_whole!(self, NtArg, |x| x);
 
         if let Ok(Some(_)) = self.parse_self_arg() {
@@ -2008,12 +2033,12 @@ impl<'a> Parser<'a> {
             }
 
             self.eat_incorrect_doc_comment("a method argument's type");
-            (pat, self.parse_ty()?)
+            (pat, self.parse_ty_common(true, true, allow_c_variadic)?)
         } else {
             debug!("parse_arg_general ident_to_pat");
             let parser_snapshot_before_ty = self.clone();
             self.eat_incorrect_doc_comment("a method argument's type");
-            let mut ty = self.parse_ty();
+            let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
             if ty.is_ok() && self.token != token::Comma &&
                self.token != token::CloseDelim(token::Paren) {
                 // This wasn't actually a type, but a pattern looking like a type,
@@ -2032,6 +2057,11 @@ impl<'a> Parser<'a> {
                     (pat, ty)
                 }
                 Err(mut err) => {
+                    // If this is a C-variadic argument and we hit an error, return the
+                    // error.
+                    if self.token == token::DotDotDot {
+                        return Err(err);
+                    }
                     // Recover from attempting to parse the argument as a type without pattern.
                     err.cancel();
                     mem::replace(self, parser_snapshot_before_ty);
@@ -2068,7 +2098,7 @@ impl<'a> Parser<'a> {
 
     /// Parses a single function argument.
     crate fn parse_arg(&mut self) -> PResult<'a, Arg> {
-        self.parse_arg_general(true, false)
+        self.parse_arg_general(true, false, false)
     }
 
     /// Parses an argument in a lambda header (e.g., `|arg, arg|`).
@@ -2406,7 +2436,7 @@ impl<'a> Parser<'a> {
                 }
                 let span = lo.to(self.prev_span);
                 let output = if self.eat(&token::RArrow) {
-                    Some(self.parse_ty_common(false, false)?)
+                    Some(self.parse_ty_common(false, false, false)?)
                 } else {
                     None
                 };
@@ -5001,6 +5031,11 @@ impl<'a> Parser<'a> {
         )
     }
 
+    fn is_async_fn(&mut self) -> bool {
+        self.token.is_keyword(keywords::Async) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
+    }
+
     fn is_do_catch_block(&mut self) -> bool {
         self.token.is_keyword(keywords::Do) &&
         self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
@@ -5133,7 +5168,8 @@ impl<'a> Parser<'a> {
                   !self.is_union_item() &&
                   !self.is_crate_vis() &&
                   !self.is_existential_type_decl() &&
-                  !self.is_auto_trait_item() {
+                  !self.is_auto_trait_item() &&
+                  !self.is_async_fn() {
             let pth = self.parse_path(PathStyle::Expr)?;
 
             if !self.eat(&token::Not) {
@@ -5502,6 +5538,7 @@ impl<'a> Parser<'a> {
         let mut bounds = Vec::new();
         let mut negative_bounds = Vec::new();
         let mut last_plus_span = None;
+        let mut was_negative = false;
         loop {
             // This needs to be synchronized with `Token::can_begin_bound`.
             let is_bound_start = self.check_path() || self.check_lifetime() ||
@@ -5546,9 +5583,10 @@ impl<'a> Parser<'a> {
                     }
                     let poly_span = lo.to(self.prev_span);
                     if is_negative {
-                        negative_bounds.push(
-                            last_plus_span.or(colon_span).unwrap()
-                                .to(poly_span));
+                        was_negative = true;
+                        if let Some(sp) = last_plus_span.or(colon_span) {
+                            negative_bounds.push(sp.to(poly_span));
+                        }
                     } else {
                         let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span);
                         let modifier = if question.is_some() {
@@ -5570,26 +5608,28 @@ impl<'a> Parser<'a> {
             }
         }
 
-        if !negative_bounds.is_empty() {
+        if !negative_bounds.is_empty() || was_negative {
             let plural = negative_bounds.len() > 1;
             let mut err = self.struct_span_err(negative_bounds,
                                                "negative trait bounds are not supported");
-            let bound_list = colon_span.unwrap().to(self.prev_span);
-            let mut new_bound_list = String::new();
-            if !bounds.is_empty() {
-                let mut snippets = bounds.iter().map(|bound| bound.span())
-                    .map(|span| self.sess.source_map().span_to_snippet(span));
-                while let Some(Ok(snippet)) = snippets.next() {
-                    new_bound_list.push_str(" + ");
-                    new_bound_list.push_str(&snippet);
-                }
-                new_bound_list = new_bound_list.replacen(" +", ":", 1);
-            }
-            err.span_suggestion_short(bound_list,
-                                      &format!("remove the trait bound{}",
-                                              if plural { "s" } else { "" }),
-                                      new_bound_list,
-                                      Applicability::MachineApplicable);
+            if let Some(bound_list) = colon_span {
+                let bound_list = bound_list.to(self.prev_span);
+                let mut new_bound_list = String::new();
+                if !bounds.is_empty() {
+                    let mut snippets = bounds.iter().map(|bound| bound.span())
+                        .map(|span| self.sess.source_map().span_to_snippet(span));
+                    while let Some(Ok(snippet)) = snippets.next() {
+                        new_bound_list.push_str(" + ");
+                        new_bound_list.push_str(&snippet);
+                    }
+                    new_bound_list = new_bound_list.replacen(" +", ":", 1);
+                }
+                err.span_suggestion_short(bound_list,
+                                        &format!("remove the trait bound{}",
+                                                if plural { "s" } else { "" }),
+                                        new_bound_list,
+                                        Applicability::MachineApplicable);
+            }
             err.emit();
         }
 
@@ -5625,7 +5665,7 @@ impl<'a> Parser<'a> {
 
         // Parse optional colon and param bounds.
         let bounds = if self.eat(&token::Colon) {
-            self.parse_generic_bounds(None)?
+            self.parse_generic_bounds(Some(self.prev_span))?
         } else {
             Vec::new()
         };
@@ -6070,7 +6110,7 @@ impl<'a> Parser<'a> {
                 // or with mandatory equality sign and the second type.
                 let ty = self.parse_ty()?;
                 if self.eat(&token::Colon) {
-                    let bounds = self.parse_generic_bounds(None)?;
+                    let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
                     where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
                         ast::WhereBoundPredicate {
                             span: lo.to(self.prev_span),
@@ -6107,55 +6147,49 @@ impl<'a> Parser<'a> {
         Ok(where_clause)
     }
 
-    fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
+    fn parse_fn_args(&mut self, named_args: bool, allow_c_variadic: bool)
                      -> PResult<'a, (Vec<Arg> , bool)> {
         self.expect(&token::OpenDelim(token::Paren))?;
 
         let sp = self.span;
-        let mut variadic = false;
+        let mut c_variadic = false;
         let (args, recovered): (Vec<Option<Arg>>, bool) =
             self.parse_seq_to_before_end(
                 &token::CloseDelim(token::Paren),
                 SeqSep::trailing_allowed(token::Comma),
                 |p| {
-                    if p.token == token::DotDotDot {
-                        p.bump();
-                        variadic = true;
-                        if allow_variadic {
-                            if p.token != token::CloseDelim(token::Paren) {
-                                let span = p.span;
-                                p.span_err(span,
-                                    "`...` must be last in argument list for variadic function");
-                            }
-                            Ok(None)
-                        } else {
-                            let span = p.prev_span;
-                            if p.token == token::CloseDelim(token::Paren) {
-                                // continue parsing to present any further errors
-                                p.struct_span_err(
-                                    span,
-                                    "only foreign functions are allowed to be variadic"
-                                ).emit();
-                                Ok(Some(dummy_arg(span)))
-                           } else {
-                               // this function definition looks beyond recovery, stop parsing
-                                p.span_err(span,
-                                           "only foreign functions are allowed to be variadic");
-                                Ok(None)
-                            }
-                        }
+                    // If the argument is a C-variadic argument we should not
+                    // enforce named arguments.
+                    let enforce_named_args = if p.token == token::DotDotDot {
+                        false
                     } else {
-                        match p.parse_arg_general(named_args, false) {
-                            Ok(arg) => Ok(Some(arg)),
-                            Err(mut e) => {
-                                e.emit();
-                                let lo = p.prev_span;
-                                // Skip every token until next possible arg or end.
-                                p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
-                                // Create a placeholder argument for proper arg count (#34264).
-                                let span = lo.to(p.prev_span);
-                                Ok(Some(dummy_arg(span)))
+                        named_args
+                    };
+                    match p.parse_arg_general(enforce_named_args, false,
+                                              allow_c_variadic) {
+                        Ok(arg) => {
+                            if let TyKind::CVarArgs = arg.ty.node {
+                                c_variadic = true;
+                                if p.token != token::CloseDelim(token::Paren) {
+                                    let span = p.span;
+                                    p.span_err(span,
+                                        "`...` must be the last argument of a C-variadic function");
+                                    Ok(None)
+                                } else {
+                                    Ok(Some(arg))
+                                }
+                            } else {
+                                Ok(Some(arg))
                             }
+                        },
+                        Err(mut e) => {
+                            e.emit();
+                            let lo = p.prev_span;
+                            // Skip every token until next possible arg or end.
+                            p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
+                            // Create a placeholder argument for proper arg count (issue #34264).
+                            let span = lo.to(p.prev_span);
+                            Ok(Some(dummy_arg(span)))
                         }
                     }
                 }
@@ -6167,24 +6201,24 @@ impl<'a> Parser<'a> {
 
         let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
 
-        if variadic && args.is_empty() {
+        if c_variadic && args.is_empty() {
             self.span_err(sp,
-                          "variadic function must be declared with at least one named argument");
+                          "C-variadic function must be declared with at least one named argument");
         }
 
-        Ok((args, variadic))
+        Ok((args, c_variadic))
     }
 
     /// Parses the argument list and result type of a function declaration.
-    fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> {
+    fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
 
-        let (args, variadic) = self.parse_fn_args(true, allow_variadic)?;
+        let (args, c_variadic) = self.parse_fn_args(true, allow_c_variadic)?;
         let ret_ty = self.parse_ret_ty(true)?;
 
         Ok(P(FnDecl {
             inputs: args,
             output: ret_ty,
-            variadic,
+            c_variadic,
         }))
     }
 
@@ -6318,7 +6352,10 @@ impl<'a> Parser<'a> {
                 fn_inputs.append(&mut input);
                 (fn_inputs, recovered)
             } else {
-                return self.unexpected();
+                match self.expect_one_of(&[], &[]) {
+                    Err(err) => return Err(err),
+                    Ok(recovered) => (vec![self_arg], recovered),
+                }
             }
         } else {
             self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
@@ -6331,7 +6368,7 @@ impl<'a> Parser<'a> {
         Ok(P(FnDecl {
             inputs: fn_inputs,
             output: self.parse_ret_ty(true)?,
-            variadic: false
+            c_variadic: false
         }))
     }
 
@@ -6357,7 +6394,7 @@ impl<'a> Parser<'a> {
         Ok(P(FnDecl {
             inputs: inputs_captures,
             output,
-            variadic: false
+            c_variadic: false
         }))
     }
 
@@ -6384,12 +6421,13 @@ impl<'a> Parser<'a> {
     /// Parses an item-position function declaration.
     fn parse_item_fn(&mut self,
                      unsafety: Unsafety,
-                     asyncness: IsAsync,
+                     asyncness: Spanned<IsAsync>,
                      constness: Spanned<Constness>,
                      abi: Abi)
                      -> PResult<'a, ItemInfo> {
         let (ident, mut generics) = self.parse_fn_header()?;
-        let decl = self.parse_fn_decl(false)?;
+        let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
+        let decl = self.parse_fn_decl(allow_c_variadic)?;
         generics.where_clause = self.parse_where_clause()?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
         let header = FnHeader { unsafety, asyncness, constness, abi };
@@ -6416,7 +6454,7 @@ impl<'a> Parser<'a> {
         -> PResult<'a, (
             Spanned<Constness>,
             Unsafety,
-            IsAsync,
+            Spanned<IsAsync>,
             Abi
         )>
     {
@@ -6424,6 +6462,7 @@ impl<'a> Parser<'a> {
         let const_span = self.prev_span;
         let unsafety = self.parse_unsafety();
         let asyncness = self.parse_asyncness();
+        let asyncness = respan(self.prev_span, asyncness);
         let (constness, unsafety, abi) = if is_const_fn {
             (respan(const_span, Constness::Const), unsafety, Abi::Rust)
         } else {
@@ -6442,9 +6481,13 @@ impl<'a> Parser<'a> {
     pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
         maybe_whole!(self, NtImplItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
+        let mut unclosed_delims = vec![];
         let (mut item, tokens) = self.collect_tokens(|this| {
-            this.parse_impl_item_(at_end, attrs)
+            let item = this.parse_impl_item_(at_end, attrs);
+            unclosed_delims.append(&mut this.unclosed_delims);
+            item
         })?;
+        self.unclosed_delims.append(&mut unclosed_delims);
 
         // See `parse_item` for why this clause is here.
         if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
@@ -7626,7 +7669,7 @@ impl<'a> Parser<'a> {
         tps.where_clause = self.parse_where_clause()?;
         let alias = if existential {
             self.expect(&token::Colon)?;
-            let bounds = self.parse_generic_bounds(None)?;
+            let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
             AliasKind::Existential(bounds)
         } else {
             self.expect(&token::Eq)?;
@@ -7764,9 +7807,13 @@ impl<'a> Parser<'a> {
         macros_allowed: bool,
         attributes_allowed: bool,
     ) -> PResult<'a, Option<P<Item>>> {
+        let mut unclosed_delims = vec![];
         let (ret, tokens) = self.collect_tokens(|this| {
-            this.parse_item_implementation(attrs, macros_allowed, attributes_allowed)
+            let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
+            unclosed_delims.append(&mut this.unclosed_delims);
+            item
         })?;
+        self.unclosed_delims.append(&mut unclosed_delims);
 
         // Once we've parsed an item and recorded the tokens we got while
         // parsing we may want to store `tokens` into the item we're about to
@@ -7834,7 +7881,7 @@ impl<'a> Parser<'a> {
                 let abi = opt_abi.unwrap_or(Abi::C);
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(Unsafety::Normal,
-                                       IsAsync::NotAsync,
+                                       respan(fn_span, IsAsync::NotAsync),
                                        respan(fn_span, Constness::NotConst),
                                        abi)?;
                 let prev_span = self.prev_span;
@@ -7878,7 +7925,7 @@ impl<'a> Parser<'a> {
                 self.bump();
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(unsafety,
-                                       IsAsync::NotAsync,
+                                       respan(const_span, IsAsync::NotAsync),
                                        respan(const_span, Constness::Const),
                                        Abi::Rust)?;
                 let prev_span = self.prev_span;
@@ -7926,14 +7973,15 @@ impl<'a> Parser<'a> {
             // ASYNC FUNCTION ITEM
             let unsafety = self.parse_unsafety();
             self.expect_keyword(keywords::Async)?;
+            let async_span = self.prev_span;
             self.expect_keyword(keywords::Fn)?;
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(unsafety,
-                                   IsAsync::Async {
+                                   respan(async_span, IsAsync::Async {
                                        closure_id: ast::DUMMY_NODE_ID,
                                        return_impl_trait_id: ast::DUMMY_NODE_ID,
-                                   },
+                                   }),
                                    respan(fn_span, Constness::NotConst),
                                    Abi::Rust)?;
             let prev_span = self.prev_span;
@@ -7942,6 +7990,13 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
+            if self.span.rust_2015() {
+                self.diagnostic().struct_span_err_with_code(
+                    async_span,
+                    "`async fn` is not permitted in the 2015 edition",
+                    DiagnosticId::Error("E0670".into())
+                ).emit();
+            }
             return Ok(Some(item));
         }
         if self.check_keyword(keywords::Unsafe) &&
@@ -7989,7 +8044,7 @@ impl<'a> Parser<'a> {
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(Unsafety::Normal,
-                                   IsAsync::NotAsync,
+                                   respan(fn_span, IsAsync::NotAsync),
                                    respan(fn_span, Constness::NotConst),
                                    Abi::Rust)?;
             let prev_span = self.prev_span;
@@ -8015,7 +8070,7 @@ impl<'a> Parser<'a> {
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(Unsafety::Unsafe,
-                                   IsAsync::NotAsync,
+                                   respan(fn_span, IsAsync::NotAsync),
                                    respan(fn_span, Constness::NotConst),
                                    abi)?;
             let prev_span = self.prev_span;
@@ -8282,7 +8337,8 @@ impl<'a> Parser<'a> {
         lo: Span,
         visibility: Visibility
     ) -> PResult<'a, Option<P<Item>>> {
-        if macros_allowed && self.token.is_path_start() {
+        if macros_allowed && self.token.is_path_start() &&
+                !(self.is_async_fn() && self.span.rust_2015()) {
             // MACRO INVOCATION ITEM
 
             let prev_span = self.prev_span;
@@ -8337,7 +8393,8 @@ impl<'a> Parser<'a> {
     fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
                                at_end: &mut bool) -> PResult<'a, Option<Mac>>
     {
-        if self.token.is_path_start() {
+        if self.token.is_path_start() &&
+                !(self.is_async_fn() && self.span.rust_2015()) {
             let prev_span = self.prev_span;
             let lo = self.span;
             let pth = self.parse_path(PathStyle::Mod)?;
@@ -8512,8 +8569,6 @@ impl<'a> Parser<'a> {
             module: self.parse_mod_items(&token::Eof, lo)?,
             span: lo.to(self.span),
         });
-        emit_unclosed_delims(&self.unclosed_delims, self.diagnostic());
-        self.unclosed_delims.clear();
         krate
     }
 
@@ -8544,8 +8599,8 @@ impl<'a> Parser<'a> {
     }
 }
 
-pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors::Handler) {
-    for unmatched in unclosed_delims {
+pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
+    for unmatched in unclosed_delims.iter() {
         let mut err = handler.struct_span_err(unmatched.found_span, &format!(
             "incorrect close delimiter: `{}`",
             pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
@@ -8559,4 +8614,5 @@ pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors
         }
         err.emit();
     }
+    unclosed_delims.clear();
 }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index eec422d6266..2fa4f5263fb 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -10,7 +10,6 @@ use crate::print::pprust;
 use crate::ptr::P;
 use crate::symbol::keywords;
 use crate::syntax::parse::parse_stream_from_source_str;
-use crate::syntax::parse::parser::emit_unclosed_delims;
 use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
 
 use syntax_pos::symbol::{self, Symbol};
@@ -675,9 +674,7 @@ impl Nonterminal {
         // FIXME(#43081): Avoid this pretty-print + reparse hack
         let source = pprust::nonterminal_to_string(self);
         let filename = FileName::macro_expansion_source_code(&source);
-        let (tokens_for_real, errors) =
-            parse_stream_from_source_str(filename, source, sess, Some(span));
-        emit_unclosed_delims(&errors, &sess.span_diagnostic);
+        let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
 
         // During early phases of the compiler the AST could get modified
         // directly (e.g., attributes added or removed) and the internal cache
@@ -740,13 +737,7 @@ fn prepend_attrs(sess: &ParseSess,
         let source = pprust::attr_to_string(attr);
         let macro_filename = FileName::macro_expansion_source_code(&source);
         if attr.is_sugared_doc {
-            let (stream, errors) = parse_stream_from_source_str(
-                macro_filename,
-                source,
-                sess,
-                Some(span),
-            );
-            emit_unclosed_delims(&errors, &sess.span_diagnostic);
+            let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
             builder.push(stream);
             continue
         }
@@ -763,13 +754,7 @@ fn prepend_attrs(sess: &ParseSess,
         // ... and for more complicated paths, fall back to a reparse hack that
         // should eventually be removed.
         } else {
-            let (stream, errors) = parse_stream_from_source_str(
-                macro_filename,
-                source,
-                sess,
-                Some(span),
-            );
-            emit_unclosed_delims(&errors, &sess.span_diagnostic);
+            let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
             brackets.push(stream);
         }
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index dcf9815f6d1..49e3fad4af0 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1118,6 +1118,9 @@ impl<'a> State<'a> {
             ast::TyKind::Mac(ref m) => {
                 self.print_mac(m)?;
             }
+            ast::TyKind::CVarArgs => {
+                self.s.word("...")?;
+            }
         }
         self.end()
     }
@@ -2811,9 +2814,6 @@ impl<'a> State<'a> {
         -> io::Result<()> {
         self.popen()?;
         self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
-        if decl.variadic {
-            self.s.word(", ...")?;
-        }
         self.pclose()?;
 
         self.print_fn_output(decl)
@@ -3195,7 +3195,7 @@ impl<'a> State<'a> {
             ast::Constness::Const => self.word_nbsp("const")?
         }
 
-        self.print_asyncness(header.asyncness)?;
+        self.print_asyncness(header.asyncness.node)?;
         self.print_unsafety(header.unsafety)?;
 
         if header.abi != Abi::Rust {
@@ -3238,7 +3238,7 @@ mod tests {
             let decl = ast::FnDecl {
                 inputs: Vec::new(),
                 output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP),
-                variadic: false
+                c_variadic: false
             };
             let generics = ast::Generics::default();
             assert_eq!(
@@ -3247,7 +3247,7 @@ mod tests {
                     ast::FnHeader {
                         unsafety: ast::Unsafety::Normal,
                         constness: source_map::dummy_spanned(ast::Constness::NotConst),
-                        asyncness: ast::IsAsync::NotAsync,
+                        asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
                         abi: Abi::Rust,
                     },
                     abba_ident,
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index bc43630ae59..9afcb7c4621 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -29,7 +29,7 @@
 use std::fmt::{self, Display, Debug};
 use std::iter::FromIterator;
 use std::ops::{Deref, DerefMut};
-use std::{mem, ptr, slice, vec};
+use std::{slice, vec};
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
@@ -66,45 +66,18 @@ impl<T: 'static> P<T> {
     pub fn map<F>(mut self, f: F) -> P<T> where
         F: FnOnce(T) -> T,
     {
-        let p: *mut T = &mut *self.ptr;
+        let x = f(*self.ptr);
+        *self.ptr = x;
 
-        // Leak self in case of panic.
-        // FIXME(eddyb) Use some sort of "free guard" that
-        // only deallocates, without dropping the pointee,
-        // in case the call the `f` below ends in a panic.
-        mem::forget(self);
-
-        unsafe {
-            ptr::write(p, f(ptr::read(p)));
-
-            // Recreate self from the raw pointer.
-            P { ptr: Box::from_raw(p) }
-        }
+        self
     }
 
     /// Optionally produce a new `P<T>` from `self` without reallocating.
     pub fn filter_map<F>(mut self, f: F) -> Option<P<T>> where
         F: FnOnce(T) -> Option<T>,
     {
-        let p: *mut T = &mut *self.ptr;
-
-        // Leak self in case of panic.
-        // FIXME(eddyb) Use some sort of "free guard" that
-        // only deallocates, without dropping the pointee,
-        // in case the call the `f` below ends in a panic.
-        mem::forget(self);
-
-        unsafe {
-            if let Some(v) = f(ptr::read(p)) {
-                ptr::write(p, v);
-
-                // Recreate self from the raw pointer.
-                Some(P { ptr: Box::from_raw(p) })
-            } else {
-                drop(Box::from_raw(p));
-                None
-            }
-        }
+        *self.ptr = f(*self.ptr)?;
+        Some(self)
     }
 }
 
diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs
index cf39090e188..2b3d18835d5 100644
--- a/src/libsyntax/test_snippet.rs
+++ b/src/libsyntax/test_snippet.rs
@@ -58,7 +58,7 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
                                         Some(source_map.clone()),
                                         false,
                                         false);
-        let handler = Handler::with_emitter(true, false, Box::new(emitter));
+        let handler = Handler::with_emitter(true, None, Box::new(emitter));
         handler.span_err(msp, "foo");
 
         assert!(expected_output.chars().next() == Some('\n'),
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 283679e758b..4ce308d015c 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -254,7 +254,7 @@ impl TokenStream {
         }
     }
 
-    fn from_streams(mut streams: Vec<TokenStream>) -> TokenStream {
+    pub(crate) fn from_streams(mut streams: Vec<TokenStream>) -> TokenStream {
         match streams.len() {
             0 => TokenStream::empty(),
             1 => streams.pop().unwrap(),
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a002394c710..6b3a30ccb54 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -22,7 +22,7 @@ use syntax_pos::Span;
 #[derive(Copy, Clone)]
 pub enum FnKind<'a> {
     /// fn foo() or extern "Abi" fn foo()
-    ItemFn(Ident, FnHeader, &'a Visibility, &'a Block),
+    ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block),
 
     /// fn foo(&self)
     Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block),
@@ -149,6 +149,9 @@ pub trait Visitor<'ast>: Sized {
     fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FunctionRetTy) {
         walk_fn_ret_ty(self, ret_ty)
     }
+    fn visit_fn_header(&mut self, _header: &'ast FnHeader) {
+        // Nothing to do
+    }
 }
 
 #[macro_export]
@@ -225,8 +228,9 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             visitor.visit_expr(expr);
         }
-        ItemKind::Fn(ref declaration, header, ref generics, ref body) => {
+        ItemKind::Fn(ref declaration, ref header, ref generics, ref body) => {
             visitor.visit_generics(generics);
+            visitor.visit_fn_header(header);
             visitor.visit_fn(FnKind::ItemFn(item.ident, header,
                                             &item.vis, body),
                              declaration,
@@ -315,7 +319,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
             walk_list!(visitor, visit_lifetime, opt_lifetime);
             visitor.visit_ty(&mutable_type.ty)
         }
-        TyKind::Never => {},
+        TyKind::Never | TyKind::CVarArgs => {}
         TyKind::Tup(ref tuple_element_types) => {
             walk_list!(visitor, visit_ty, tuple_element_types);
         }
@@ -539,11 +543,13 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl
     where V: Visitor<'a>,
 {
     match kind {
-        FnKind::ItemFn(_, _, _, body) => {
+        FnKind::ItemFn(_, header, _, body) => {
+            visitor.visit_fn_header(header);
             walk_fn_decl(visitor, declaration);
             visitor.visit_block(body);
         }
-        FnKind::Method(_, _, _, body) => {
+        FnKind::Method(_, sig, _, body) => {
+            visitor.visit_fn_header(&sig.header);
             walk_fn_decl(visitor, declaration);
             visitor.visit_block(body);
         }
@@ -564,6 +570,7 @@ pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, trait_item: &'a Trai
             walk_list!(visitor, visit_expr, default);
         }
         TraitItemKind::Method(ref sig, None) => {
+            visitor.visit_fn_header(&sig.header);
             walk_fn_decl(visitor, &sig.decl);
         }
         TraitItemKind::Method(ref sig, Some(ref body)) => {