about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/asm.rs127
-rw-r--r--src/libsyntax_ext/assert.rs78
-rw-r--r--src/libsyntax_ext/cfg.rs45
-rw-r--r--src/libsyntax_ext/compile_error.rs12
-rw-r--r--src/libsyntax_ext/concat.rs17
-rw-r--r--src/libsyntax_ext/concat_idents.rs17
-rw-r--r--src/libsyntax_ext/deriving/bounds.rs10
-rw-r--r--src/libsyntax_ext/deriving/clone.rs10
-rw-r--r--src/libsyntax_ext/deriving/cmp/eq.rs10
-rw-r--r--src/libsyntax_ext/deriving/cmp/ord.rs10
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_eq.rs10
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_ord.rs10
-rw-r--r--src/libsyntax_ext/deriving/custom.rs10
-rw-r--r--src/libsyntax_ext/deriving/debug.rs10
-rw-r--r--src/libsyntax_ext/deriving/decodable.rs10
-rw-r--r--src/libsyntax_ext/deriving/default.rs14
-rw-r--r--src/libsyntax_ext/deriving/encodable.rs10
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs10
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs10
-rw-r--r--src/libsyntax_ext/deriving/hash.rs10
-rw-r--r--src/libsyntax_ext/deriving/mod.rs11
-rw-r--r--src/libsyntax_ext/diagnostics.rs10
-rw-r--r--src/libsyntax_ext/env.rs12
-rw-r--r--src/libsyntax_ext/format.rs224
-rw-r--r--src/libsyntax_ext/format_foreign.rs10
-rw-r--r--src/libsyntax_ext/global_asm.rs68
-rw-r--r--src/libsyntax_ext/lib.rs12
-rw-r--r--src/libsyntax_ext/log_syntax.rs13
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs10
-rw-r--r--src/libsyntax_ext/proc_macro_impl.rs11
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs18
-rw-r--r--src/libsyntax_ext/test.rs10
-rw-r--r--src/libsyntax_ext/test_case.rs10
-rw-r--r--src/libsyntax_ext/trace_macros.rs13
34 files changed, 373 insertions, 499 deletions
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 2ff9fb487c4..41ee6e91b3d 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -1,19 +1,10 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 // Inline assembly support.
 //
 use self::State::*;
 
 use rustc_data_structures::thin_vec::ThinVec;
 
+use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::ext::base;
 use syntax::ext::base::*;
@@ -59,9 +50,36 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_ASM);
-        return DummyResult::expr(sp);
     }
 
+    let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
+        Ok(Some(inline_asm)) => inline_asm,
+        Ok(None) => return DummyResult::expr(sp),
+        Err(mut err) => {
+            err.emit();
+            return DummyResult::expr(sp);
+        }
+    };
+
+    // If there are no outputs, the inline assembly is executed just for its side effects,
+    // so ensure that it is volatile
+    if inline_asm.outputs.is_empty() {
+        inline_asm.volatile = true;
+    }
+
+    MacEager::expr(P(ast::Expr {
+        id: ast::DUMMY_NODE_ID,
+        node: ast::ExprKind::InlineAsm(P(inline_asm)),
+        span: sp,
+        attrs: ThinVec::new(),
+    }))
+}
+
+fn parse_inline_asm<'a>(
+    cx: &mut ExtCtxt<'a>,
+    sp: Span,
+    tts: &[tokenstream::TokenTree],
+) -> Result<Option<ast::InlineAsm>, DiagnosticBuilder<'a>> {
     // Split the tts before the first colon, to avoid `asm!("x": y)`  being
     // parsed as `asm!(z)` with `z = "x": y` which is type ascription.
     let first_colon = tts.iter()
@@ -91,22 +109,33 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                 if asm_str_style.is_some() {
                     // If we already have a string with instructions,
                     // ending up in Asm state again is an error.
-                    span_err!(cx, sp, E0660, "malformed inline assembly");
-                    return DummyResult::expr(sp);
+                    return Err(struct_span_err!(
+                        cx.parse_sess.span_diagnostic,
+                        sp,
+                        E0660,
+                        "malformed inline assembly"
+                    ));
                 }
                 // Nested parser, stop before the first colon (see above).
                 let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]);
-                let (s, style) = match expr_to_string(cx,
-                                                      panictry!(p2.parse_expr()),
-                                                      "inline assembly must be a string literal") {
-                    Some((s, st)) => (s, st),
-                    // let compilation continue
-                    None => return DummyResult::expr(sp),
-                };
+
+                if p2.token == token::Eof {
+                    let mut err =
+                        cx.struct_span_err(sp, "macro requires a string literal as an argument");
+                    err.span_label(sp, "string literal required");
+                    return Err(err);
+                }
+
+                let expr = p2.parse_expr()?;
+                let (s, style) =
+                    match expr_to_string(cx, expr, "inline assembly must be a string literal") {
+                        Some((s, st)) => (s, st),
+                        None => return Ok(None),
+                    };
 
                 // This is most likely malformed.
                 if p2.token != token::Eof {
-                    let mut extra_tts = panictry!(p2.parse_all_token_trees());
+                    let mut extra_tts = p2.parse_all_token_trees()?;
                     extra_tts.extend(tts[first_colon..].iter().cloned());
                     p = parse::stream_to_parser(cx.parse_sess, extra_tts.into_iter().collect());
                 }
@@ -116,18 +145,17 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
             }
             Outputs => {
                 while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
-
                     if !outputs.is_empty() {
                         p.eat(&token::Comma);
                     }
 
-                    let (constraint, _str_style) = panictry!(p.parse_str());
+                    let (constraint, _) = p.parse_str()?;
 
                     let span = p.prev_span;
 
-                    panictry!(p.expect(&token::OpenDelim(token::Paren)));
-                    let out = panictry!(p.parse_expr());
-                    panictry!(p.expect(&token::CloseDelim(token::Paren)));
+                    p.expect(&token::OpenDelim(token::Paren))?;
+                    let expr = p.parse_expr()?;
+                    p.expect(&token::CloseDelim(token::Paren))?;
 
                     // Expands a read+write operand into two operands.
                     //
@@ -154,7 +182,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                     let is_indirect = constraint_str.contains("*");
                     outputs.push(ast::InlineAsmOutput {
                         constraint: output.unwrap_or(constraint),
-                        expr: out,
+                        expr,
                         is_rw,
                         is_indirect,
                     });
@@ -162,12 +190,11 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
             }
             Inputs => {
                 while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
-
                     if !inputs.is_empty() {
                         p.eat(&token::Comma);
                     }
 
-                    let (constraint, _str_style) = panictry!(p.parse_str());
+                    let (constraint, _) = p.parse_str()?;
 
                     if constraint.as_str().starts_with("=") {
                         span_err!(cx, p.prev_span, E0662,
@@ -177,21 +204,20 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                                                 "input operand constraint contains '+'");
                     }
 
-                    panictry!(p.expect(&token::OpenDelim(token::Paren)));
-                    let input = panictry!(p.parse_expr());
-                    panictry!(p.expect(&token::CloseDelim(token::Paren)));
+                    p.expect(&token::OpenDelim(token::Paren))?;
+                    let input = p.parse_expr()?;
+                    p.expect(&token::CloseDelim(token::Paren))?;
 
                     inputs.push((constraint, input));
                 }
             }
             Clobbers => {
                 while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
-
                     if !clobs.is_empty() {
                         p.eat(&token::Comma);
                     }
 
-                    let (s, _str_style) = panictry!(p.parse_str());
+                    let (s, _) = p.parse_str()?;
 
                     if OPTIONS.iter().any(|&opt| s == opt) {
                         cx.span_warn(p.prev_span, "expected a clobber, found an option");
@@ -204,7 +230,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                 }
             }
             Options => {
-                let (option, _str_style) = panictry!(p.parse_str());
+                let (option, _) = p.parse_str()?;
 
                 if option == "volatile" {
                     // Indicates that the inline assembly has side effects
@@ -245,26 +271,15 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
         }
     }
 
-    // If there are no outputs, the inline assembly is executed just for its side effects,
-    // so ensure that it is volatile
-    if outputs.is_empty() {
-        volatile = true;
-    }
-
-    MacEager::expr(P(ast::Expr {
-        id: ast::DUMMY_NODE_ID,
-        node: ast::ExprKind::InlineAsm(P(ast::InlineAsm {
-            asm,
-            asm_str_style: asm_str_style.unwrap(),
-            outputs,
-            inputs,
-            clobbers: clobs,
-            volatile,
-            alignstack,
-            dialect,
-            ctxt: cx.backtrace(),
-        })),
-        span: sp,
-        attrs: ThinVec::new(),
+    Ok(Some(ast::InlineAsm {
+        asm,
+        asm_str_style: asm_str_style.unwrap(),
+        outputs,
+        inputs,
+        clobbers: clobs,
+        volatile,
+        alignstack,
+        dialect,
+        ctxt: cx.backtrace(),
     }))
 }
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index a2384b59048..b27f495322a 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -1,19 +1,11 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast::*;
+use errors::DiagnosticBuilder;
+use syntax::ast::{self, *};
 use syntax::source_map::Spanned;
 use syntax::ext::base::*;
 use syntax::ext::build::AstBuilder;
 use syntax::parse::token;
 use syntax::print::pprust;
+use syntax::ptr::P;
 use syntax::symbol::Symbol;
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax_pos::{Span, DUMMY_SP};
@@ -23,33 +15,18 @@ pub fn expand_assert<'cx>(
     sp: Span,
     tts: &[TokenTree],
 ) -> Box<dyn MacResult + 'cx> {
-    let mut parser = cx.new_parser_from_tts(tts);
-
-    if parser.token == token::Eof {
-        cx.struct_span_err(sp, "macro requires a boolean expression as an argument")
-            .span_label(sp, "boolean expression required")
-            .emit();
-        return DummyResult::expr(sp);
-    }
-
-    let cond_expr = panictry!(parser.parse_expr());
-    let custom_msg_args = if parser.eat(&token::Comma) {
-        let ts = parser.parse_tokens();
-        if !ts.is_empty() {
-            Some(ts)
-        } else {
-            None
+    let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) {
+        Ok(assert) => assert,
+        Err(mut err) => {
+            err.emit();
+            return DummyResult::expr(sp);
         }
-    } else {
-        None
     };
 
     let sp = sp.apply_mark(cx.current_expansion.mark);
     let panic_call = Mac_ {
         path: Path::from_ident(Ident::new(Symbol::intern("panic"), sp)),
-        tts: if let Some(ts) = custom_msg_args {
-            ts.into()
-        } else {
+        tts: custom_message.unwrap_or_else(|| {
             TokenStream::from(TokenTree::Token(
                 DUMMY_SP,
                 token::Literal(
@@ -59,8 +36,8 @@ pub fn expand_assert<'cx>(
                     ))),
                     None,
                 ),
-            )).into()
-        },
+            ))
+        }).into(),
         delim: MacDelimiter::Parenthesis,
     };
     let if_expr = cx.expr_if(
@@ -77,3 +54,36 @@ pub fn expand_assert<'cx>(
     );
     MacEager::expr(if_expr)
 }
+
+struct Assert {
+    cond_expr: P<ast::Expr>,
+    custom_message: Option<TokenStream>,
+}
+
+fn parse_assert<'a>(
+    cx: &mut ExtCtxt<'a>,
+    sp: Span,
+    tts: &[TokenTree]
+) -> Result<Assert, DiagnosticBuilder<'a>> {
+    let mut parser = cx.new_parser_from_tts(tts);
+
+    if parser.token == token::Eof {
+        let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument");
+        err.span_label(sp, "boolean expression required");
+        return Err(err);
+    }
+
+    Ok(Assert {
+        cond_expr: parser.parse_expr()?,
+        custom_message: if parser.eat(&token::Comma) {
+            let ts = parser.parse_tokens();
+            if !ts.is_empty() {
+                Some(ts)
+            } else {
+                None
+            }
+        } else {
+            None
+        },
+    })
+}
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 2384b6a796e..3b47b03cbe8 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -1,17 +1,9 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 /// The compiler code necessary to support the cfg! extension, which expands to
 /// a literal `true` or `false` based on whether the given cfg matches the
 /// current compilation environment.
 
+use errors::DiagnosticBuilder;
+use syntax::ast;
 use syntax::ext::base::*;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
@@ -25,16 +17,39 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
                        tts: &[tokenstream::TokenTree])
                        -> Box<dyn base::MacResult + 'static> {
     let sp = sp.apply_mark(cx.current_expansion.mark);
+
+    match parse_cfg(cx, sp, tts) {
+        Ok(cfg) => {
+            let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
+            MacEager::expr(cx.expr_bool(sp, matches_cfg))
+        }
+        Err(mut err) => {
+            err.emit();
+            DummyResult::expr(sp)
+        }
+    }
+}
+
+fn parse_cfg<'a>(
+    cx: &mut ExtCtxt<'a>,
+    sp: Span,
+    tts: &[tokenstream::TokenTree],
+) -> Result<ast::MetaItem, DiagnosticBuilder<'a>> {
     let mut p = cx.new_parser_from_tts(tts);
-    let cfg = panictry!(p.parse_meta_item());
+
+    if p.token == token::Eof {
+        let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument");
+        err.span_label(sp, "cfg-pattern required");
+        return Err(err);
+    }
+
+    let cfg = p.parse_meta_item()?;
 
     let _ = p.eat(&token::Comma);
 
     if !p.eat(&token::Eof) {
-        cx.span_err(sp, "expected 1 cfg-pattern");
-        return DummyResult::expr(sp);
+        return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern"));
     }
 
-    let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
-    MacEager::expr(cx.expr_bool(sp, matches_cfg))
+    Ok(cfg)
 }
diff --git a/src/libsyntax_ext/compile_error.rs b/src/libsyntax_ext/compile_error.rs
index ce7fb400bd5..8f7f5deb091 100644
--- a/src/libsyntax_ext/compile_error.rs
+++ b/src/libsyntax_ext/compile_error.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 // The compiler code necessary to support the compile_error! extension.
 
 use syntax::ext::base::*;
@@ -20,7 +10,7 @@ pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt,
                               tts: &[tokenstream::TokenTree])
                               -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
-        None => return DummyResult::expr(sp),
+        None => return DummyResult::any(sp),
         Some(v) => v,
     };
 
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index dcdd2c590e0..807f190cb6a 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use syntax::ast;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
@@ -28,6 +18,7 @@ pub fn expand_syntax_ext(
     };
     let mut accumulator = String::new();
     let mut missing_literal = vec![];
+    let mut has_errors = false;
     for e in es {
         match e.node {
             ast::ExprKind::Lit(ref lit) => match lit.node {
@@ -51,6 +42,9 @@ pub fn expand_syntax_ext(
                     cx.span_err(e.span, "cannot concatenate a byte string literal");
                 }
             },
+            ast::ExprKind::Err => {
+                has_errors = true;
+            }
             _ => {
                 missing_literal.push(e.span);
             }
@@ -60,6 +54,9 @@ pub fn expand_syntax_ext(
         let mut err = cx.struct_span_err(missing_literal, "expected a literal");
         err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
         err.emit();
+        return base::DummyResult::expr(sp);
+    } else if has_errors {
+        return base::DummyResult::expr(sp);
     }
     let sp = sp.apply_mark(cx.current_expansion.mark);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index c8cc11e4354..de96de4bdc2 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -1,13 +1,3 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use rustc_data_structures::thin_vec::ThinVec;
 
 use syntax::ast;
@@ -30,12 +20,11 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CONCAT_IDENTS);
-        return base::DummyResult::expr(sp);
     }
 
     if tts.is_empty() {
         cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
-        return DummyResult::expr(sp);
+        return DummyResult::any(sp);
     }
 
     let mut res_str = String::new();
@@ -45,7 +34,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
                 TokenTree::Token(_, token::Comma) => {}
                 _ => {
                     cx.span_err(sp, "concat_idents! expecting comma.");
-                    return DummyResult::expr(sp);
+                    return DummyResult::any(sp);
                 }
             }
         } else {
@@ -54,7 +43,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
                     res_str.push_str(&ident.as_str()),
                 _ => {
                     cx.span_err(sp, "concat_idents! requires ident args.");
-                    return DummyResult::expr(sp);
+                    return DummyResult::any(sp);
                 }
             }
         }
diff --git a/src/libsyntax_ext/deriving/bounds.rs b/src/libsyntax_ext/deriving/bounds.rs
index 41e980b3346..dcfc6ab0391 100644
--- a/src/libsyntax_ext/deriving/bounds.rs
+++ b/src/libsyntax_ext/deriving/bounds.rs
@@ -1,13 +1,3 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::path_std;
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index b9e0933331c..38d433e842c 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::path_std;
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index f202bc4e524..dbba8c3b7a0 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::path_std;
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs
index 117bedf453e..21bd56710ac 100644
--- a/src/libsyntax_ext/deriving/cmp/ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/ord.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::path_std;
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 24a3a7542fb..4ec24bce4cd 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::{path_local, path_std};
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 196cfa5fe35..9ef481edf51 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 pub use self::OrderingOp::*;
 
 use deriving::{path_local, pathvec_std, path_std};
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index cc2fa685687..2f20814ef3e 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -1,13 +1,3 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use errors::FatalError;
 use syntax::ast::{self, ItemKind, Attribute, Mac};
 use syntax::attr::{mark_used, mark_known};
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index df9c351ef1c..b3e5bd9283e 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -1,13 +1,3 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::path_std;
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index c2b92944999..89c630e9915 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more.
 
 use deriving::{self, pathvec_std};
diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs
index adbc5828b8f..32d02bec798 100644
--- a/src/libsyntax_ext/deriving/default.rs
+++ b/src/libsyntax_ext/deriving/default.rs
@@ -1,19 +1,9 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::path_std;
 use deriving::generic::*;
 use deriving::generic::ty::*;
 
 use syntax::ast::{Expr, MetaItem};
-use syntax::ext::base::{Annotatable, ExtCtxt};
+use syntax::ext::base::{Annotatable, DummyResult, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
@@ -79,7 +69,7 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur
             span_err!(cx, trait_span, E0665,
                       "`Default` cannot be derived for enums, only structs");
             // let compilation continue
-            cx.expr_usize(trait_span, 0)
+            DummyResult::raw_expr(trait_span, true)
         }
         _ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`"),
     };
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 5438c8b52af..c8935874158 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! The compiler code necessary to implement the `#[derive(Encodable)]`
 //! (and `Decodable`, in decodable.rs) extension.  The idea here is that
 //! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 443fd48120e..22643db5016 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1,13 +1,3 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! Some code that abstracts away much of the boilerplate of writing
 //! `derive` instances for traits. Among other things it manages getting
 //! access to the fields of the 4 different sorts of structs and enum
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 11689a98a79..83ec99b3573 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use
 //! when specifying impls to be derived.
 
diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs
index 950e8c84f17..4af2bd57b00 100644
--- a/src/libsyntax_ext/deriving/hash.rs
+++ b/src/libsyntax_ext/deriving/hash.rs
@@ -1,13 +1,3 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use deriving::{self, pathvec_std, path_std};
 use deriving::generic::*;
 use deriving::generic::ty::*;
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index ae47a028bc3..7548d43f184 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! The compiler code necessary to implement the `#[derive]` extensions.
 
 use rustc_data_structures::sync::Lrc;
@@ -163,6 +153,5 @@ fn call_intrinsic(cx: &ExtCtxt,
         id: ast::DUMMY_NODE_ID,
         rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
         span,
-        recovered: false,
     }))
 }
diff --git a/src/libsyntax_ext/diagnostics.rs b/src/libsyntax_ext/diagnostics.rs
index f99a6c3c216..e8ad4af6850 100644
--- a/src/libsyntax_ext/diagnostics.rs
+++ b/src/libsyntax_ext/diagnostics.rs
@@ -1,13 +1,3 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 #![allow(non_snake_case)]
 
 // Error messages for EXXXX errors.
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 8f26b2402aa..16fb64a5f39 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 // The compiler code necessary to support the env! extension.  Eventually this
 // should all get sucked into either the compiler syntax extension plugin
 // interface.
@@ -89,7 +79,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt,
     let e = match env::var(&*var.as_str()) {
         Err(_) => {
             cx.span_err(sp, &msg.as_str());
-            cx.expr_usize(sp, 0)
+            return DummyResult::expr(sp);
         }
         Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
     };
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 41799eede9e..61722ba5516 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -1,18 +1,9 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use self::ArgumentType::*;
 use self::Position::*;
 
 use fmt_macros as parse;
 
+use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::ext::base::{self, *};
 use syntax::ext::build::AstBuilder;
@@ -122,7 +113,7 @@ struct Context<'a, 'b: 'a> {
     is_literal: bool,
 }
 
-/// Parses the arguments from the given list of tokens, returning None
+/// Parses the arguments from the given list of tokens, returning the diagnostic
 /// if there's a parse error so we can continue parsing other format!
 /// expressions.
 ///
@@ -131,27 +122,26 @@ struct Context<'a, 'b: 'a> {
 /// ```text
 /// Some((fmtstr, parsed arguments, index map for named arguments))
 /// ```
-fn parse_args(ecx: &mut ExtCtxt,
-              sp: Span,
-              tts: &[tokenstream::TokenTree])
-              -> Option<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<String, usize>)> {
+fn parse_args<'a>(
+    ecx: &mut ExtCtxt<'a>,
+    sp: Span,
+    tts: &[tokenstream::TokenTree]
+) -> Result<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<String, usize>), DiagnosticBuilder<'a>> {
     let mut args = Vec::<P<ast::Expr>>::new();
     let mut names = FxHashMap::<String, usize>::default();
 
     let mut p = ecx.new_parser_from_tts(tts);
 
     if p.token == token::Eof {
-        ecx.span_err(sp, "requires at least a format string argument");
-        return None;
+        return Err(ecx.struct_span_err(sp, "requires at least a format string argument"));
     }
 
-    let fmtstr = panictry!(p.parse_expr());
+    let fmtstr = p.parse_expr()?;
     let mut named = false;
 
     while p.token != token::Eof {
         if !p.eat(&token::Comma) {
-            ecx.span_err(p.span, "expected token: `,`");
-            return None;
+            return Err(ecx.struct_span_err(p.span, "expected token: `,`"));
         }
         if p.token == token::Eof {
             break;
@@ -162,16 +152,15 @@ fn parse_args(ecx: &mut ExtCtxt,
                 p.bump();
                 i
             } else {
-                ecx.span_err(
+                return Err(ecx.struct_span_err(
                     p.span,
                     "expected ident, positional arguments cannot follow named arguments",
-                );
-                return None;
+                ));
             };
             let name: &str = &ident.as_str();
 
-            panictry!(p.expect(&token::Eq));
-            let e = panictry!(p.parse_expr());
+            p.expect(&token::Eq).unwrap();
+            let e = p.parse_expr()?;
             if let Some(prev) = names.get(name) {
                 ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name))
                     .span_note(args[*prev].span, "previously here")
@@ -187,10 +176,11 @@ fn parse_args(ecx: &mut ExtCtxt,
             names.insert(name.to_string(), slot);
             args.push(e);
         } else {
-            args.push(panictry!(p.parse_expr()));
+            let e = p.parse_expr()?;
+            args.push(e);
         }
     }
-    Some((fmtstr, args, names))
+    Ok((fmtstr, args, names))
 }
 
 impl<'a, 'b> Context<'a, 'b> {
@@ -676,7 +666,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     "X" => "UpperHex",
                     _ => {
                         ecx.span_err(sp, &format!("unknown format trait `{}`", *tyname));
-                        "Dummy"
+                        return DummyResult::raw_expr(sp, true);
                     }
                 }
             }
@@ -699,10 +689,13 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
                                -> Box<dyn base::MacResult + 'cx> {
     sp = sp.apply_mark(ecx.current_expansion.mark);
     match parse_args(ecx, sp, tts) {
-        Some((efmt, args, names)) => {
+        Ok((efmt, args, names)) => {
             MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false))
         }
-        None => DummyResult::expr(sp),
+        Err(mut err) => {
+            err.emit();
+            DummyResult::expr(sp)
+        }
     }
 }
 
@@ -723,14 +716,16 @@ pub fn expand_format_args_nl<'cx>(
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_FORMAT_ARGS_NL);
-        return base::DummyResult::expr(sp);
     }
     sp = sp.apply_mark(ecx.current_expansion.mark);
     match parse_args(ecx, sp, tts) {
-        Some((efmt, args, names)) => {
+        Ok((efmt, args, names)) => {
             MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true))
         }
-        None => DummyResult::expr(sp),
+        Err(mut err) => {
+            err.emit();
+            DummyResult::expr(sp)
+        }
     }
 }
 
@@ -759,34 +754,137 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
             fmt
         }
         Ok(fmt) => fmt,
-        Err(mut err) => {
-            let sugg_fmt = match args.len() {
-                0 => "{}".to_string(),
-                _ => format!("{}{{}}", "{} ".repeat(args.len())),
-            };
-            err.span_suggestion_with_applicability(
-                fmt_sp.shrink_to_lo(),
-                "you might be missing a string literal to format with",
-                format!("\"{}\", ", sugg_fmt),
-                Applicability::MaybeIncorrect,
-            );
-            err.emit();
-            return DummyResult::raw_expr(sp);
+        Err(err) => {
+            if let Some(mut err) = err {
+                let sugg_fmt = match args.len() {
+                    0 => "{}".to_string(),
+                    _ => format!("{}{{}}", "{} ".repeat(args.len())),
+                };
+                err.span_suggestion_with_applicability(
+                    fmt_sp.shrink_to_lo(),
+                    "you might be missing a string literal to format with",
+                    format!("\"{}\", ", sugg_fmt),
+                    Applicability::MaybeIncorrect,
+                );
+                err.emit();
+            }
+            return DummyResult::raw_expr(sp, true);
         }
     };
 
-    let is_literal = match ecx.source_map().span_to_snippet(fmt_sp) {
-        Ok(ref s) if s.starts_with("\"") || s.starts_with("r#") => true,
-        _ => false,
+    let (is_literal, fmt_snippet) = match ecx.source_map().span_to_snippet(fmt_sp) {
+        Ok(s) => (s.starts_with("\"") || s.starts_with("r#"), Some(s)),
+        _ => (false, None),
     };
 
-    let fmt_str = &*fmt.node.0.as_str();
     let str_style = match fmt.node.1 {
         ast::StrStyle::Cooked => None,
-        ast::StrStyle::Raw(raw) => Some(raw as usize),
+        ast::StrStyle::Raw(raw) => {
+            Some(raw as usize)
+        },
+    };
+
+    /// Find the indices of all characters that have been processed and differ between the actual
+    /// written code (code snippet) and the `InternedString` that get's processed in the `Parser`
+    /// in order to properly synthethise the intra-string `Span`s for error diagnostics.
+    fn find_skips(snippet: &str, is_raw: bool) -> Vec<usize> {
+        let mut eat_ws = false;
+        let mut s = snippet.chars().enumerate().peekable();
+        let mut skips = vec![];
+        while let Some((pos, c)) = s.next() {
+            match (c, s.peek()) {
+                // skip whitespace and empty lines ending in '\\'
+                ('\\', Some((next_pos, '\n'))) if !is_raw => {
+                    eat_ws = true;
+                    skips.push(pos);
+                    skips.push(*next_pos);
+                    let _ = s.next();
+                }
+                ('\\', Some((next_pos, '\n'))) |
+                ('\\', Some((next_pos, 'n'))) |
+                ('\\', Some((next_pos, 't'))) if eat_ws => {
+                    skips.push(pos);
+                    skips.push(*next_pos);
+                    let _ = s.next();
+                }
+                (' ', _) |
+                ('\n', _) |
+                ('\t', _) if eat_ws => {
+                    skips.push(pos);
+                }
+                ('\\', Some((next_pos, 'n'))) |
+                ('\\', Some((next_pos, 't'))) |
+                ('\\', Some((next_pos, '0'))) |
+                ('\\', Some((next_pos, '\\'))) |
+                ('\\', Some((next_pos, '\''))) |
+                ('\\', Some((next_pos, '\"'))) => {
+                    skips.push(*next_pos);
+                    let _ = s.next();
+                }
+                ('\\', Some((_, 'x'))) if !is_raw => {
+                    for _ in 0..3 {  // consume `\xAB` literal
+                        if let Some((pos, _)) = s.next() {
+                            skips.push(pos);
+                        } else {
+                            break;
+                        }
+                    }
+                }
+                ('\\', Some((_, 'u'))) if !is_raw => {
+                    if let Some((pos, _)) = s.next() {
+                        skips.push(pos);
+                    }
+                    if let Some((next_pos, next_c)) = s.next() {
+                        if next_c == '{' {
+                            skips.push(next_pos);
+                            let mut i = 0;  // consume up to 6 hexanumeric chars + closing `}`
+                            while let (Some((next_pos, c)), true) = (s.next(), i < 7) {
+                                if c.is_digit(16) {
+                                    skips.push(next_pos);
+                                } else if c == '}' {
+                                    skips.push(next_pos);
+                                    break;
+                                } else {
+                                    break;
+                                }
+                                i += 1;
+                            }
+                        } else if next_c.is_digit(16) {
+                            skips.push(next_pos);
+                            // We suggest adding `{` and `}` when appropriate, accept it here as if
+                            // it were correct
+                            let mut i = 0;  // consume up to 6 hexanumeric chars
+                            while let (Some((next_pos, c)), _) = (s.next(), i < 6) {
+                                if c.is_digit(16) {
+                                    skips.push(next_pos);
+                                } else {
+                                    break;
+                                }
+                                i += 1;
+                            }
+                        }
+                    }
+                }
+                _ if eat_ws => {  // `take_while(|c| c.is_whitespace())`
+                    eat_ws = false;
+                }
+                _ => {}
+            }
+        }
+        skips
+    }
+
+    let skips = if let (true, Some(ref snippet)) = (is_literal, fmt_snippet.as_ref()) {
+        let r_start = str_style.map(|r| r + 1).unwrap_or(0);
+        let r_end = str_style.map(|r| r).unwrap_or(0);
+        let s = &snippet[r_start + 1..snippet.len() - r_end - 1];
+        find_skips(s, str_style.is_some())
+    } else {
+        vec![]
     };
 
-    let mut parser = parse::Parser::new(fmt_str, str_style);
+    let fmt_str = &*fmt.node.0.as_str();  // for the suggestions below
+    let mut parser = parse::Parser::new(fmt_str, str_style, skips.clone(), append_newline);
 
     let mut unverified_pieces = Vec::new();
     while let Some(piece) = parser.next() {
@@ -799,18 +897,25 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
 
     if !parser.errors.is_empty() {
         let err = parser.errors.remove(0);
-        let sp = fmt.span.from_inner_byte_pos(err.start, err.end);
-        let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", err.description));
+        let sp = fmt.span.from_inner_byte_pos(err.start.unwrap(), err.end.unwrap());
+        let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}",
+                                                     err.description));
         e.span_label(sp, err.label + " in format string");
         if let Some(note) = err.note {
             e.note(&note);
         }
+        if let Some((label, start, end)) = err.secondary_label {
+            let sp = fmt.span.from_inner_byte_pos(start.unwrap(), end.unwrap());
+            e.span_label(sp, label);
+        }
         e.emit();
-        return DummyResult::raw_expr(sp);
+        return DummyResult::raw_expr(sp, true);
     }
 
     let arg_spans = parser.arg_places.iter()
-        .map(|&(start, end)| fmt.span.from_inner_byte_pos(start, end))
+        .map(|&(parse::SpanIndex(start), parse::SpanIndex(end))| {
+            fmt.span.from_inner_byte_pos(start, end)
+        })
         .collect();
 
     let mut cx = Context {
@@ -904,13 +1009,18 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
         let mut diag = {
             if errs_len == 1 {
                 let (sp, msg) = errs.into_iter().next().unwrap();
-                cx.ecx.struct_span_err(sp, msg)
+                let mut diag = cx.ecx.struct_span_err(sp, msg);
+                diag.span_label(sp, msg);
+                diag
             } else {
                 let mut diag = cx.ecx.struct_span_err(
                     errs.iter().map(|&(sp, _)| sp).collect::<Vec<Span>>(),
                     "multiple unused formatting arguments",
                 );
                 diag.span_label(cx.fmtsp, "multiple missing formatting specifiers");
+                for (sp, msg) in errs {
+                    diag.span_label(sp, msg);
+                }
                 diag
             }
         };
diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs
index 9c854019de6..8ac6d460ec3 100644
--- a/src/libsyntax_ext/format_foreign.rs
+++ b/src/libsyntax_ext/format_foreign.rs
@@ -1,13 +1,3 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 pub mod printf {
     use super::strcursor::StrCursor as Cur;
 
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 000bede7348..0a12e27c4fc 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -1,13 +1,3 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 /// Module-level assembly support.
 ///
 /// The macro defined here allows you to specify "top-level",
@@ -18,11 +8,13 @@
 /// LLVM's `module asm "some assembly here"`. All of LLVM's caveats
 /// therefore apply.
 
+use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::source_map::respan;
 use syntax::ext::base;
 use syntax::ext::base::*;
 use syntax::feature_gate;
+use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
@@ -39,27 +31,49 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_GLOBAL_ASM);
-        return DummyResult::any(sp);
     }
 
+    match parse_global_asm(cx, sp, tts) {
+        Ok(Some(global_asm)) => {
+            MacEager::items(smallvec![P(ast::Item {
+                ident: ast::Ident::with_empty_ctxt(Symbol::intern("")),
+                attrs: Vec::new(),
+                id: ast::DUMMY_NODE_ID,
+                node: ast::ItemKind::GlobalAsm(P(global_asm)),
+                vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
+                span: sp,
+                tokens: None,
+            })])
+        }
+        Ok(None) => DummyResult::any(sp),
+        Err(mut err) => {
+            err.emit();
+            DummyResult::any(sp)
+        }
+    }
+}
+
+fn parse_global_asm<'a>(
+    cx: &mut ExtCtxt<'a>,
+    sp: Span,
+    tts: &[tokenstream::TokenTree]
+) -> Result<Option<ast::GlobalAsm>, DiagnosticBuilder<'a>> {
     let mut p = cx.new_parser_from_tts(tts);
-    let (asm, _) = match expr_to_string(cx,
-                                        panictry!(p.parse_expr()),
-                                        "inline assembly must be a string literal") {
+
+    if p.token == token::Eof {
+        let mut err = cx.struct_span_err(sp, "macro requires a string literal as an argument");
+        err.span_label(sp, "string literal required");
+        return Err(err);
+    }
+
+    let expr = p.parse_expr()?;
+    let (asm, _) = match expr_to_string(cx, expr, "inline assembly must be a string literal") {
         Some((s, st)) => (s, st),
-        None => return DummyResult::any(sp),
+        None => return Ok(None),
     };
 
-    MacEager::items(smallvec![P(ast::Item {
-        ident: ast::Ident::with_empty_ctxt(Symbol::intern("")),
-        attrs: Vec::new(),
-        id: ast::DUMMY_NODE_ID,
-        node: ast::ItemKind::GlobalAsm(P(ast::GlobalAsm {
-            asm,
-            ctxt: cx.backtrace(),
-        })),
-        vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
-        span: sp,
-        tokens: None,
-    })])
+    Ok(Some(ast::GlobalAsm {
+        asm,
+        ctxt: cx.backtrace(),
+    }))
 }
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index c49d5772531..17996f23691 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -1,13 +1,3 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! Syntax extensions in the Rust compiler.
 
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
@@ -24,6 +14,8 @@
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 
+#![recursion_limit="256"]
+
 extern crate fmt_macros;
 #[macro_use]
 extern crate syntax;
diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs
index 7b76b1e8914..a143186b945 100644
--- a/src/libsyntax_ext/log_syntax.rs
+++ b/src/libsyntax_ext/log_syntax.rs
@@ -1,13 +1,3 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use syntax::ext::base;
 use syntax::feature_gate;
 use syntax::print;
@@ -24,11 +14,10 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_LOG_SYNTAX);
-        return base::DummyResult::any(sp);
     }
 
     println!("{}", print::pprust::tts_to_string(tts));
 
     // any so that `log_syntax` can be invoked as an expression and item.
-    base::DummyResult::any(sp)
+    base::DummyResult::any_valid(sp)
 }
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index f4ff0989b5d..38f7ca500b2 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -1,13 +1,3 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use std::mem;
 
 use errors;
diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs
index 43ef31a00ba..60d167d01ee 100644
--- a/src/libsyntax_ext/proc_macro_impl.rs
+++ b/src/libsyntax_ext/proc_macro_impl.rs
@@ -1,14 +1,3 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
 use errors::FatalError;
 
 use syntax::source_map::Span;
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index ca960cbe41b..afd86a4f746 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -1,13 +1,3 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use errors::{self, Diagnostic, DiagnosticBuilder};
 use std::panic;
 
@@ -21,7 +11,7 @@ use syntax::ast;
 use syntax::ext::base::ExtCtxt;
 use syntax::parse::lexer::comments;
 use syntax::parse::{self, token, ParseSess};
-use syntax::tokenstream::{self, DelimSpan, TokenStream};
+use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream};
 use syntax_pos::hygiene::{SyntaxContext, Transparency};
 use syntax_pos::symbol::{keywords, Symbol};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
@@ -278,11 +268,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
         };
 
         let tree = tokenstream::TokenTree::Token(span, token);
-        if joint {
-            tree.joint()
-        } else {
-            tree.into()
-        }
+        TokenStream::Tree(tree, if joint { Joint } else { NonJoint })
     }
 }
 
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 1f2e6fc81c8..cf842dddeb3 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -1,13 +1,3 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 /// The expansion from a test function to the appropriate test struct for libtest
 /// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
 
diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs
index 0128db7dd78..04e33671872 100644
--- a/src/libsyntax_ext/test_case.rs
+++ b/src/libsyntax_ext/test_case.rs
@@ -1,13 +1,5 @@
-
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
 
 // #[test_case] is used by custom test authors to mark tests
 // When building for test, it needs to make the item public and gensym the name
@@ -39,8 +31,6 @@ pub fn expand(
                                        attr_sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
-
-        return vec![anno_item];
     }
 
     if !ecx.ecfg.should_test { return vec![]; }
diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs
index 256b525b8be..638d7b5568b 100644
--- a/src/libsyntax_ext/trace_macros.rs
+++ b/src/libsyntax_ext/trace_macros.rs
@@ -1,13 +1,3 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 use syntax::ext::base::ExtCtxt;
 use syntax::ext::base;
 use syntax::feature_gate;
@@ -25,7 +15,6 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_TRACE_MACROS);
-        return base::DummyResult::any(sp);
     }
 
     match (tt.len(), tt.first()) {
@@ -38,5 +27,5 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
         _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"),
     }
 
-    base::DummyResult::any(sp)
+    base::DummyResult::any_valid(sp)
 }