about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-08-27 06:18:24 +0000
committerbors <bors@rust-lang.org>2019-08-27 06:18:24 +0000
commit7e0afdad28c4d1154176df6d35a14e738ec311af (patch)
treedb371f782f0f0a0170f0ce86d9da66b10276fd14
parent0444b9f66acb5da23dc816e0d8eb59623ba9ea50 (diff)
parent23116baff042880209c06e78a1fb48fb2b06c76a (diff)
downloadrust-7e0afdad28c4d1154176df6d35a14e738ec311af.tar.gz
rust-7e0afdad28c4d1154176df6d35a14e738ec311af.zip
Auto merge of #63940 - Centril:rollup-47qe9gn, r=Centril
Rollup of 4 pull requests

Successful merges:

 - #62600 (libtest: add --show-output flag to print stdout of successful tests)
 - #63698 (Fixed floating point issue with asinh function)
 - #63761 (Propagate spans and attributes from proc macro definitions)
 - #63917 (Error when generator trait is not found)

Failed merges:

r? @ghost
-rw-r--r--src/libproc_macro/lib.rs10
-rw-r--r--src/libproc_macro/quote.rs4
-rw-r--r--src/librustc_metadata/cstore.rs7
-rw-r--r--src/librustc_metadata/cstore_impl.rs14
-rw-r--r--src/librustc_metadata/decoder.rs49
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs12
-rw-r--r--src/librustc_resolve/macros.rs4
-rw-r--r--src/librustc_typeck/check/closure.rs4
-rw-r--r--src/librustdoc/markdown.rs2
-rw-r--r--src/librustdoc/test.rs2
-rw-r--r--src/libstd/f32.rs10
-rw-r--r--src/libstd/f64.rs33
-rw-r--r--src/libsyntax/ext/base.rs67
-rw-r--r--src/libsyntax/ext/proc_macro_server.rs7
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs70
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/libsyntax_ext/lib.rs8
-rw-r--r--src/libtest/formatters/json.rs71
-rw-r--r--src/libtest/formatters/mod.rs1
-rw-r--r--src/libtest/formatters/pretty.rs8
-rw-r--r--src/libtest/formatters/terse.rs8
-rw-r--r--src/libtest/lib.rs18
-rw-r--r--src/libtest/tests.rs11
-rw-r--r--src/test/run-make-fulldeps/libtest-json/Makefile12
-rw-r--r--src/test/run-make-fulldeps/libtest-json/f.rs3
-rw-r--r--src/test/run-make-fulldeps/libtest-json/output-default.json (renamed from src/test/run-make-fulldeps/libtest-json/output.json)2
-rw-r--r--src/test/run-make-fulldeps/libtest-json/output-stdout-success.json10
-rw-r--r--src/test/ui/auxiliary/cond_plugin.rs1
-rw-r--r--src/test/ui/auxiliary/proc_macro_def.rs1
-rw-r--r--src/test/ui/lang-item-missing-generator.rs19
-rw-r--r--src/test/ui/lang-item-missing-generator.stderr4
-rw-r--r--src/test/ui/macros/auxiliary/proc_macro_sequence.rs20
-rw-r--r--src/test/ui/macros/same-sequence-span.stderr12
-rw-r--r--src/test/ui/proc-macro/attributes-on-definitions.rs12
-rw-r--r--src/test/ui/proc-macro/attributes-on-definitions.stderr8
-rw-r--r--src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs23
-rw-r--r--src/test/ui/proc-macro/multispan.stderr133
-rw-r--r--src/test/ui/proc-macro/three-equals.stderr19
38 files changed, 468 insertions, 240 deletions
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index c0f7714ca21..d408fef7515 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -19,12 +19,15 @@
 
 #![feature(nll)]
 #![feature(staged_api)]
+#![feature(allow_internal_unstable)]
 #![feature(const_fn)]
+#![feature(decl_macro)]
 #![feature(extern_types)]
 #![feature(in_band_lifetimes)]
 #![feature(optin_builtin_traits)]
 #![feature(mem_take)]
 #![feature(non_exhaustive)]
+#![feature(rustc_attrs)]
 #![feature(specialization)]
 
 #![recursion_limit="256"]
@@ -222,11 +225,10 @@ pub mod token_stream {
 ///
 /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
 /// To quote `$` itself, use `$$`.
-///
-/// This is a dummy macro, the actual implementation is in `quote::quote`.`
 #[unstable(feature = "proc_macro_quote", issue = "54722")]
-#[macro_export]
-macro_rules! quote { () => {} }
+#[allow_internal_unstable(proc_macro_def_site)]
+#[cfg_attr(not(bootstrap), rustc_builtin_macro)]
+pub macro quote ($($t:tt)*) { /* compiler built-in */ }
 
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
 #[doc(hidden)]
diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs
index e3d31b78f4a..144e2d6bac4 100644
--- a/src/libproc_macro/quote.rs
+++ b/src/libproc_macro/quote.rs
@@ -57,9 +57,9 @@ macro_rules! quote {
 }
 
 /// Quote a `TokenStream` into a `TokenStream`.
-/// This is the actual `quote!()` proc macro.
+/// This is the actual implementation of the `quote!()` proc macro.
 ///
-/// It is manually loaded in `CStore::load_macro_untracked`.
+/// It is loaded by the compiler in `register_builtin_macros`.
 #[unstable(feature = "proc_macro_quote", issue = "54722")]
 pub fn quote(stream: TokenStream) -> TokenStream {
     if stream.is_empty() {
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index efc77699313..5bf4067431f 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -95,11 +95,6 @@ pub struct CrateMetadata {
     pub raw_proc_macros: Option<&'static [ProcMacro]>,
 }
 
-pub struct FullProcMacro {
-    pub name: ast::Name,
-    pub ext: Lrc<SyntaxExtension>
-}
-
 pub struct CStore {
     metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
     /// Map from NodeId's of local extern crate statements to crate numbers
@@ -109,7 +104,7 @@ pub struct CStore {
 
 pub enum LoadedMacro {
     MacroDef(ast::Item),
-    ProcMacro(Lrc<SyntaxExtension>),
+    ProcMacro(SyntaxExtension),
 }
 
 impl CStore {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 7aeeef00ea9..5bfb315da47 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -30,11 +30,9 @@ use syntax::ast;
 use syntax::attr;
 use syntax::source_map;
 use syntax::edition::Edition;
-use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
-use syntax::ext::proc_macro::BangProcMacro;
 use syntax::parse::source_file_to_stream;
 use syntax::parse::parser::emit_unclosed_delims;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::Symbol;
 use syntax_pos::{Span, FileName};
 use rustc_data_structures::bit_set::BitSet;
 
@@ -436,15 +434,7 @@ impl cstore::CStore {
     pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         let data = self.get_crate_data(id.krate);
         if data.is_proc_macro_crate() {
-            return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext);
-        } else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote {
-            let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
-            let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }));
-            let ext = SyntaxExtension {
-                allow_internal_unstable: Some([sym::proc_macro_def_site][..].into()),
-                ..SyntaxExtension::default(kind, data.root.edition)
-            };
-            return LoadedMacro::ProcMacro(Lrc::new(ext));
+            return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
         }
 
         let def = data.get_macro(id.index);
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5b9cb966af2..c777b5ea409 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1,6 +1,6 @@
 // Decoding metadata from a single crate's metadata
 
-use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro};
+use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
 use crate::schema::*;
 
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -512,27 +512,8 @@ impl<'a, 'tcx> CrateMetadata {
         self.entry(index).span.decode((self, sess))
     }
 
-
-    pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro {
-        if sess.opts.debugging_opts.dual_proc_macros {
-            let host_lib = self.host_lib.as_ref().unwrap();
-            self.load_proc_macro(
-                &host_lib.metadata.get_root(),
-                id,
-                sess
-            )
-        } else {
-            self.load_proc_macro(&self.root, id, sess)
-        }
-    }
-
-    fn load_proc_macro(&self, root: &CrateRoot<'_>,
-                        id: DefIndex,
-                        sess: &Session)
-                        -> FullProcMacro {
-
-        let raw_macro = self.raw_proc_macro(id);
-        let (name, kind, helper_attrs) = match *raw_macro {
+    crate fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
+        let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
                 let helper_attrs =
                     attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
@@ -551,17 +532,21 @@ impl<'a, 'tcx> CrateMetadata {
                 name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
             )
         };
+        let edition = if sess.opts.debugging_opts.dual_proc_macros {
+            self.host_lib.as_ref().unwrap().metadata.get_root().edition
+        } else {
+            self.root.edition
+        };
 
-        let span = self.get_span(id, sess);
-
-        FullProcMacro {
-            name: Symbol::intern(name),
-            ext: Lrc::new(SyntaxExtension {
-                span,
-                helper_attrs,
-                ..SyntaxExtension::default(kind, root.edition)
-            })
-        }
+        SyntaxExtension::new(
+            &sess.parse_sess,
+            kind,
+            self.get_span(id, sess),
+            helper_attrs,
+            edition,
+            Symbol::intern(name),
+            &self.get_attributes(&self.entry(id), sess),
+        )
     }
 
     pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 9a794ade729..165a4c707bb 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -150,12 +150,12 @@ impl<'a> Resolver<'a> {
             return Some(ext.clone());
         }
 
-        let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) {
-            LoadedMacro::MacroDef(macro_def) => macro_def,
-            LoadedMacro::ProcMacro(ext) => return Some(ext),
-        };
+        let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) {
+            LoadedMacro::MacroDef(item) =>
+                self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)),
+            LoadedMacro::ProcMacro(ext) => ext,
+        });
 
-        let ext = self.compile_macro(&macro_def, self.cstore.crate_edition_untracked(def_id.krate));
         self.macro_map.insert(def_id, ext.clone());
         Some(ext)
     }
@@ -1104,7 +1104,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         let expansion = parent_scope.expansion;
         let (ext, ident, span, is_legacy) = match &item.node {
             ItemKind::MacroDef(def) => {
-                let ext = self.r.compile_macro(item, self.r.session.edition());
+                let ext = Lrc::new(self.r.compile_macro(item, self.r.session.edition()));
                 (ext, item.ident, item.span, def.legacy)
             }
             ItemKind::Fn(..) => match Self::proc_macro_stub(item) {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 719167eb057..cc78e928380 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -800,7 +800,7 @@ impl<'a> Resolver<'a> {
 
     /// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined
     /// extension partially or entirely for built-in macros and legacy plugin macros.
-    crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> Lrc<SyntaxExtension> {
+    crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension {
         let mut result = macro_rules::compile(
             &self.session.parse_sess, self.session.features_untracked(), item, edition
         );
@@ -822,6 +822,6 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        Lrc::new(result)
+        result
     }
 }
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index d2f2f89cf0b..06b1e7bfd4e 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -3,7 +3,7 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
-use crate::middle::region;
+use crate::middle::{lang_items, region};
 use rustc::hir::def_id::DefId;
 use rustc::infer::{InferOk, InferResult};
 use rustc::infer::LateBoundRegionConversionTime;
@@ -266,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let trait_ref = projection.to_poly_trait_ref(tcx);
 
         let is_fn = tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_some();
-        let gen_trait = tcx.lang_items().gen_trait().unwrap();
+        let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem);
         let is_gen = gen_trait == trait_ref.def_id();
         if !is_fn && !is_gen {
             debug!("deduce_sig_from_projection: not fn or generator");
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index eaaae3261c7..e735a9779c9 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -154,6 +154,6 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
 
     options.test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&options.test_args, collector.tests,
-                       testing::Options::new().display_output(options.display_warnings));
+                       Some(testing::Options::new().display_output(options.display_warnings)));
     0
 }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 83a8d3fc109..959587e7f53 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -120,7 +120,7 @@ pub fn run(options: Options) -> i32 {
     testing::test_main(
         &test_args,
         tests,
-        testing::Options::new().display_output(display_warnings)
+        Some(testing::Options::new().display_output(display_warnings))
     );
 
     0
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index e55afc2344f..795830a52c5 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -910,7 +910,7 @@ impl f32 {
         if self == NEG_INFINITY {
             NEG_INFINITY
         } else {
-            (self + ((self * self) + 1.0).sqrt()).ln()
+            (self + ((self * self) + 1.0).sqrt()).ln().copysign(self)
         }
     }
 
@@ -931,9 +931,10 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f32 {
-        match self {
-            x if x < 1.0 => crate::f32::NAN,
-            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        if self < 1.0 {
+            crate::f32::NAN
+        } else {
+            (self + ((self * self) - 1.0).sqrt()).ln()
         }
     }
 
@@ -1487,6 +1488,7 @@ mod tests {
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
+        assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
         assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
         assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
     }
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index b3571026300..44d25f1b476 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -244,7 +244,7 @@ impl f64 {
     pub fn div_euclid(self, rhs: f64) -> f64 {
         let q = (self / rhs).trunc();
         if self % rhs < 0.0 {
-            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
+            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
         }
         q
     }
@@ -437,9 +437,9 @@ impl f64 {
     pub fn log2(self) -> f64 {
         self.log_wrapper(|n| {
             #[cfg(target_os = "android")]
-            return crate::sys::android::log2f64(n);
+                return crate::sys::android::log2f64(n);
             #[cfg(not(target_os = "android"))]
-            return unsafe { intrinsics::log2f64(n) };
+                return unsafe { intrinsics::log2f64(n) };
         })
     }
 
@@ -481,16 +481,16 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     #[rustc_deprecated(since = "1.10.0",
-                       reason = "you probably meant `(self - other).abs()`: \
+    reason = "you probably meant `(self - other).abs()`: \
                                  this operation is `(self - other).max(0.0)` \
                                  except that `abs_sub` also propagates NaNs (also \
                                  known as `fdim` in C). If you truly need the positive \
                                  difference, consider using that expression or the C function \
                                  `fdim`, depending on how you wish to handle NaN (please consider \
                                  filing an issue describing your use-case too).")]
-     pub fn abs_sub(self, other: f64) -> f64 {
-         unsafe { cmath::fdim(self, other) }
-     }
+    pub fn abs_sub(self, other: f64) -> f64 {
+        unsafe { cmath::fdim(self, other) }
+    }
 
     /// Takes the cubic root of a number.
     ///
@@ -833,7 +833,7 @@ impl f64 {
         if self == NEG_INFINITY {
             NEG_INFINITY
         } else {
-            (self + ((self * self) + 1.0).sqrt()).ln()
+            (self + ((self * self) + 1.0).sqrt()).ln().copysign(self)
         }
     }
 
@@ -852,9 +852,10 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f64 {
-        match self {
-            x if x < 1.0 => NAN,
-            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        if self < 1.0 {
+            NAN
+        } else {
+            (self + ((self * self) - 1.0).sqrt()).ln()
         }
     }
 
@@ -1187,7 +1188,7 @@ mod tests {
         assert_eq!((-0f64).abs(), 0f64);
         assert_eq!((-1f64).abs(), 1f64);
         assert_eq!(NEG_INFINITY.abs(), INFINITY);
-        assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
+        assert_eq!((1f64 / NEG_INFINITY).abs(), 0f64);
         assert!(NAN.abs().is_nan());
     }
 
@@ -1199,7 +1200,7 @@ mod tests {
         assert_eq!((-0f64).signum(), -1f64);
         assert_eq!((-1f64).signum(), -1f64);
         assert_eq!(NEG_INFINITY.signum(), -1f64);
-        assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
+        assert_eq!((1f64 / NEG_INFINITY).signum(), -1f64);
         assert!(NAN.signum().is_nan());
     }
 
@@ -1211,7 +1212,7 @@ mod tests {
         assert!(!(-0f64).is_sign_positive());
         assert!(!(-1f64).is_sign_positive());
         assert!(!NEG_INFINITY.is_sign_positive());
-        assert!(!(1f64/NEG_INFINITY).is_sign_positive());
+        assert!(!(1f64 / NEG_INFINITY).is_sign_positive());
         assert!(NAN.is_sign_positive());
         assert!(!(-NAN).is_sign_positive());
     }
@@ -1224,7 +1225,7 @@ mod tests {
         assert!((-0f64).is_sign_negative());
         assert!((-1f64).is_sign_negative());
         assert!(NEG_INFINITY.is_sign_negative());
-        assert!((1f64/NEG_INFINITY).is_sign_negative());
+        assert!((1f64 / NEG_INFINITY).is_sign_negative());
         assert!(!NAN.is_sign_negative());
         assert!((-NAN).is_sign_negative());
     }
@@ -1433,6 +1434,8 @@ mod tests {
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
+        assert!((-0.0f64).asinh().is_sign_negative());
+        // issue 63271
         assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
         assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
     }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a63c4181d5e..10ff1b17285 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1,11 +1,11 @@
 use crate::ast::{self, NodeId, Attribute, Name, PatKind};
-use crate::attr::{HasAttrs, Stability, Deprecation};
+use crate::attr::{self, HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
 use crate::ext::expand::{self, AstFragment, Invocation};
 use crate::ext::hygiene::{ExpnId, Transparency};
 use crate::mut_visit::{self, MutVisitor};
-use crate::parse::{self, parser, DirectoryOwnership};
+use crate::parse::{self, parser, ParseSess, DirectoryOwnership};
 use crate::parse::token;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
@@ -601,6 +601,69 @@ impl SyntaxExtension {
         }
     }
 
+    /// Constructs a syntax extension with the given properties
+    /// and other properties converted from attributes.
+    pub fn new(
+        sess: &ParseSess,
+        kind: SyntaxExtensionKind,
+        span: Span,
+        helper_attrs: Vec<Symbol>,
+        edition: Edition,
+        name: Name,
+        attrs: &[ast::Attribute],
+    ) -> SyntaxExtension {
+        let allow_internal_unstable =
+            attr::find_by_name(attrs, sym::allow_internal_unstable).map(|attr| {
+                attr.meta_item_list()
+                    .map(|list| {
+                        list.iter()
+                            .filter_map(|it| {
+                                let name = it.ident().map(|ident| ident.name);
+                                if name.is_none() {
+                                    sess.span_diagnostic.span_err(
+                                        it.span(), "allow internal unstable expects feature names"
+                                    )
+                                }
+                                name
+                            })
+                            .collect::<Vec<Symbol>>()
+                            .into()
+                    })
+                    .unwrap_or_else(|| {
+                        sess.span_diagnostic.span_warn(
+                            attr.span,
+                            "allow_internal_unstable expects list of feature names. In the future \
+                             this will become a hard error. Please use `allow_internal_unstable(\
+                             foo, bar)` to only allow the `foo` and `bar` features",
+                        );
+                        vec![sym::allow_internal_unstable_backcompat_hack].into()
+                    })
+            });
+
+        let mut local_inner_macros = false;
+        if let Some(macro_export) = attr::find_by_name(attrs, sym::macro_export) {
+            if let Some(l) = macro_export.meta_item_list() {
+                local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
+            }
+        }
+
+        let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro);
+
+        SyntaxExtension {
+            kind,
+            span,
+            allow_internal_unstable,
+            allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe),
+            local_inner_macros,
+            stability: attr::find_stability(&sess, attrs, span),
+            deprecation: attr::find_deprecation(&sess, attrs, span),
+            helper_attrs,
+            edition,
+            is_builtin,
+            is_derive_copy: is_builtin && name == sym::Copy,
+        }
+    }
+
     pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
         fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
                          -> Box<dyn MacResult + 'cx> {
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index b1bbd2aaac9..1a26b17dac7 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -360,12 +360,11 @@ pub(crate) struct Rustc<'a> {
 
 impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
-        // No way to determine def location for a proc macro right now, so use call location.
-        let location = cx.current_expansion.id.expn_data().call_site;
+        let expn_data = cx.current_expansion.id.expn_data();
         Rustc {
             sess: cx.parse_sess,
-            def_site: cx.with_def_site_ctxt(location),
-            call_site: cx.with_call_site_ctxt(location),
+            def_site: cx.with_def_site_ctxt(expn_data.def_site),
+            call_site: cx.with_call_site_ctxt(expn_data.call_site),
         }
     }
 
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 37cb8467ff5..46ffa52f7f5 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,3 +1,5 @@
+use crate::ast;
+use crate::attr::{self, TransparencyError};
 use crate::edition::Edition;
 use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
 use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind};
@@ -15,7 +17,6 @@ use crate::parse::token::{self, NtTT, Token};
 use crate::parse::{Directory, ParseSess};
 use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
-use crate::{ast, attr, attr::TransparencyError};
 
 use errors::{DiagnosticBuilder, FatalError};
 use log::debug;
@@ -290,6 +291,7 @@ pub fn compile(
     def: &ast::Item,
     edition: Edition,
 ) -> SyntaxExtension {
+    let diag = &sess.span_diagnostic;
     let lhs_nm = ast::Ident::new(sym::lhs, def.span);
     let rhs_nm = ast::Ident::new(sym::rhs, def.span);
     let tt_spec = ast::Ident::new(sym::tt, def.span);
@@ -423,13 +425,9 @@ pub fn compile(
     let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
     match transparency_error {
         Some(TransparencyError::UnknownTransparency(value, span)) =>
-            sess.span_diagnostic.span_err(
-                span, &format!("unknown macro transparency: `{}`", value)
-            ),
+            diag.span_err(span, &format!("unknown macro transparency: `{}`", value)),
         Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) =>
-            sess.span_diagnostic.span_err(
-                vec![old_span, new_span], "multiple macro transparency attributes"
-            ),
+            diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"),
         None => {}
     }
 
@@ -437,57 +435,15 @@ pub fn compile(
         name: def.ident, span: def.span, transparency, lhses, rhses, valid
     });
 
-    let allow_internal_unstable =
-        attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
-            attr.meta_item_list()
-                .map(|list| {
-                    list.iter()
-                        .filter_map(|it| {
-                            let name = it.ident().map(|ident| ident.name);
-                            if name.is_none() {
-                                sess.span_diagnostic.span_err(
-                                    it.span(),
-                                    "allow internal unstable expects feature names",
-                                )
-                            }
-                            name
-                        })
-                        .collect::<Vec<Symbol>>()
-                        .into()
-                })
-                .unwrap_or_else(|| {
-                    sess.span_diagnostic.span_warn(
-                        attr.span,
-                        "allow_internal_unstable expects list of feature names. In the \
-                         future this will become a hard error. Please use `allow_internal_unstable(\
-                         foo, bar)` to only allow the `foo` and `bar` features",
-                    );
-                    vec![sym::allow_internal_unstable_backcompat_hack].into()
-                })
-        });
-
-    let mut local_inner_macros = false;
-    if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
-        if let Some(l) = macro_export.meta_item_list() {
-            local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
-        }
-    }
-
-    let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro);
-
-    SyntaxExtension {
-        kind: SyntaxExtensionKind::LegacyBang(expander),
-        span: def.span,
-        allow_internal_unstable,
-        allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
-        local_inner_macros,
-        stability: attr::find_stability(&sess, &def.attrs, def.span),
-        deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
-        helper_attrs: Vec::new(),
+    SyntaxExtension::new(
+        sess,
+        SyntaxExtensionKind::LegacyBang(expander),
+        def.span,
+        Vec::new(),
         edition,
-        is_builtin,
-        is_derive_copy: is_builtin && def.ident.name == sym::Copy,
-    }
+        def.ident.name,
+        &def.attrs,
+    )
 }
 
 fn check_lhs_nt_follows(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 25ad2d4404c..2b20cb88796 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -375,10 +375,11 @@ impl<'a> Parser<'a> {
         if let Some(directory) = directory {
             parser.directory = directory;
         } else if !parser.token.span.is_dummy() {
-            if let FileName::Real(mut path) =
-                    sess.source_map().span_to_unmapped_path(parser.token.span) {
-                path.pop();
-                parser.directory.path = Cow::from(path);
+            if let Some(FileName::Real(path)) =
+                    &sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path {
+                if let Some(directory_path) = path.parent() {
+                    parser.directory.path = Cow::from(directory_path.to_path_buf());
+                }
             }
         }
 
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 4add2261c6c..1a617691662 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -7,13 +7,18 @@
 #![feature(decl_macro)]
 #![feature(mem_take)]
 #![feature(nll)]
+#![feature(proc_macro_internals)]
+#![feature(proc_macro_quote)]
 #![feature(rustc_diagnostic_macros)]
 
+extern crate proc_macro;
+
 use crate::deriving::*;
 
 use syntax::ast::Ident;
 use syntax::edition::Edition;
 use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, MacroExpanderFn};
+use syntax::ext::proc_macro::BangProcMacro;
 use syntax::symbol::sym;
 
 mod error_codes;
@@ -100,4 +105,7 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
         RustcDecodable: decodable::expand_deriving_rustc_decodable,
         RustcEncodable: encodable::expand_deriving_rustc_encodable,
     }
+
+    let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
+    register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
 }
diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs
index a06497f9862..e0bea4ce545 100644
--- a/src/libtest/formatters/json.rs
+++ b/src/libtest/formatters/json.rs
@@ -9,44 +9,57 @@ impl<T: Write> JsonFormatter<T> {
         Self { out }
     }
 
-    fn write_message(&mut self, s: &str) -> io::Result<()> {
+    fn writeln_message(&mut self, s: &str) -> io::Result<()> {
         assert!(!s.contains('\n'));
 
         self.out.write_all(s.as_ref())?;
         self.out.write_all(b"\n")
     }
 
+    fn write_message(&mut self, s: &str) -> io::Result<()> {
+        assert!(!s.contains('\n'));
+
+        self.out.write_all(s.as_ref())
+    }
+
     fn write_event(
         &mut self,
         ty: &str,
         name: &str,
         evt: &str,
-        extra: Option<String>,
+        stdout: Option<Cow<'_, str>>,
+        extra: Option<&str>,
     ) -> io::Result<()> {
-        if let Some(extras) = extra {
+        self.write_message(&*format!(
+            r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
+            ty, name, evt
+        ))?;
+        if let Some(stdout) = stdout {
             self.write_message(&*format!(
-                r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#,
-                ty, name, evt, extras
-            ))
-        } else {
+                r#", "stdout": "{}""#,
+                EscapedString(stdout)
+            ))?;
+        }
+        if let Some(extra) = extra {
             self.write_message(&*format!(
-                r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#,
-                ty, name, evt
-            ))
+                r#", {}"#,
+                extra
+            ))?;
         }
+        self.writeln_message(" }")
     }
 }
 
 impl<T: Write> OutputFormatter for JsonFormatter<T> {
     fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             r#"{{ "type": "suite", "event": "started", "test_count": {} }}"#,
             test_count
         ))
     }
 
     fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
             desc.name
         ))
@@ -57,34 +70,30 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
         desc: &TestDesc,
         result: &TestResult,
         stdout: &[u8],
+        state: &ConsoleTestState,
     ) -> io::Result<()> {
+        let stdout = if (state.options.display_output || *result != TrOk) && stdout.len() > 0 {
+            Some(String::from_utf8_lossy(stdout))
+        } else {
+            None
+        };
         match *result {
-            TrOk => self.write_event("test", desc.name.as_slice(), "ok", None),
-
-            TrFailed => {
-                let extra_data = if stdout.len() > 0 {
-                    Some(format!(
-                        r#""stdout": "{}""#,
-                        EscapedString(String::from_utf8_lossy(stdout))
-                    ))
-                } else {
-                    None
-                };
+            TrOk => self.write_event("test", desc.name.as_slice(), "ok", stdout, None),
 
-                self.write_event("test", desc.name.as_slice(), "failed", extra_data)
-            }
+            TrFailed => self.write_event("test", desc.name.as_slice(), "failed", stdout, None),
 
             TrFailedMsg(ref m) => self.write_event(
                 "test",
                 desc.name.as_slice(),
                 "failed",
-                Some(format!(r#""message": "{}""#, EscapedString(m))),
+                stdout,
+                Some(&*format!(r#""message": "{}""#, EscapedString(m))),
             ),
 
-            TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None),
+            TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", stdout, None),
 
             TrAllowedFail => {
-                self.write_event("test", desc.name.as_slice(), "allowed_failure", None)
+                self.write_event("test", desc.name.as_slice(), "allowed_failure", stdout, None)
             }
 
             TrBench(ref bs) => {
@@ -105,20 +114,20 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
                     desc.name, median, deviation, mbps
                 );
 
-                self.write_message(&*line)
+                self.writeln_message(&*line)
             }
         }
     }
 
     fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
             desc.name
         ))
     }
 
     fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             "{{ \"type\": \"suite\", \
              \"event\": \"{}\", \
              \"passed\": {}, \
diff --git a/src/libtest/formatters/mod.rs b/src/libtest/formatters/mod.rs
index be5f6a65039..cc30b06e5ec 100644
--- a/src/libtest/formatters/mod.rs
+++ b/src/libtest/formatters/mod.rs
@@ -17,6 +17,7 @@ pub(crate) trait OutputFormatter {
         desc: &TestDesc,
         result: &TestResult,
         stdout: &[u8],
+        state: &ConsoleTestState,
     ) -> io::Result<()>;
     fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool>;
 }
diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs
index 4af00428ca8..88331406a64 100644
--- a/src/libtest/formatters/pretty.rs
+++ b/src/libtest/formatters/pretty.rs
@@ -162,7 +162,13 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
         Ok(())
     }
 
-    fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
+    fn write_result(
+        &mut self,
+        desc: &TestDesc,
+        result: &TestResult,
+        _: &[u8],
+        _: &ConsoleTestState,
+    ) -> io::Result<()> {
         if self.is_multithreaded {
             self.write_test_name(desc)?;
         }
diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs
index 1400fba5d60..d10b0c5807d 100644
--- a/src/libtest/formatters/terse.rs
+++ b/src/libtest/formatters/terse.rs
@@ -170,7 +170,13 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
         Ok(())
     }
 
-    fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
+    fn write_result(
+        &mut self,
+        desc: &TestDesc,
+        result: &TestResult,
+        _: &[u8],
+        _: &ConsoleTestState,
+    ) -> io::Result<()> {
         match *result {
             TrOk => self.write_ok(),
             TrFailed | TrFailedMsg(_) => self.write_failed(),
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 5e0f19fe553..09d5fcc8952 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -274,7 +274,7 @@ impl Options {
 
 // The default console test runner. It accepts the command line
 // arguments and a vector of test_descs.
-pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
+pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Option<Options>) {
     let mut opts = match parse_opts(args) {
         Some(Ok(o)) => o,
         Some(Err(msg)) => {
@@ -283,8 +283,9 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
         }
         None => return,
     };
-
-    opts.options = options;
+    if let Some(options) = options {
+        opts.options = options;
+    }
     if opts.list {
         if let Err(e) = list_tests_console(&opts, tests) {
             eprintln!("error: io error when listing tests: {:?}", e);
@@ -325,7 +326,7 @@ pub fn test_main_static(tests: &[&TestDescAndFn]) {
             _ => panic!("non-static tests passed to test::test_main_static"),
         })
         .collect();
-    test_main(&args, owned_tests, Options::new())
+    test_main(&args, owned_tests, None)
 }
 
 /// Invoked when unit tests terminate. Should panic if the unit
@@ -448,6 +449,11 @@ fn optgroups() -> getopts::Options {
             json   = Output a json document",
             "pretty|terse|json",
         )
+        .optflag(
+            "",
+            "show-output",
+            "Show captured stdout of successful tests"
+        )
         .optopt(
             "Z",
             "",
@@ -647,7 +653,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         format,
         test_threads,
         skip: matches.opt_strs("skip"),
-        options: Options::new(),
+        options: Options::new().display_output(matches.opt_present("show-output")),
     };
 
     Some(Ok(test_opts))
@@ -880,7 +886,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
             TeTimeout(ref test) => out.write_timeout(test),
             TeResult(test, result, stdout) => {
                 st.write_log_result(&test, &result)?;
-                out.write_result(&test, &result, &*stdout)?;
+                out.write_result(&test, &result, &*stdout, &st)?;
                 match result {
                     TrOk => {
                         st.passed += 1;
diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs
index f574743e4b6..afc4217ec1b 100644
--- a/src/libtest/tests.rs
+++ b/src/libtest/tests.rs
@@ -181,6 +181,17 @@ fn parse_ignored_flag() {
 }
 
 #[test]
+fn parse_show_output_flag() {
+    let args = vec![
+        "progname".to_string(),
+        "filter".to_string(),
+        "--show-output".to_string(),
+    ];
+    let opts = parse_opts(&args).unwrap().unwrap();
+    assert!(opts.options.display_output);
+}
+
+#[test]
 fn parse_include_ignored_flag() {
     let args = vec![
         "progname".to_string(),
diff --git a/src/test/run-make-fulldeps/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile
index a0bc8cf6688..8339e230bbe 100644
--- a/src/test/run-make-fulldeps/libtest-json/Makefile
+++ b/src/test/run-make-fulldeps/libtest-json/Makefile
@@ -2,13 +2,17 @@
 
 # Test expected libtest's JSON output
 
-OUTPUT_FILE := $(TMPDIR)/libtest-json-output.json
+OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-json-output-default.json
+OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-json-output-stdout-success.json
 
 all:
 	$(RUSTC) --test f.rs
-	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE) || true
+	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE_DEFAULT) || true
+	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true
 
-	cat $(OUTPUT_FILE) | "$(PYTHON)" validate_json.py
+	cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_json.py
+	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_json.py
 
 	# Compare to output file
-	diff output.json $(OUTPUT_FILE)
+	diff output-default.json $(OUTPUT_FILE_DEFAULT)
+	diff output-stdout-success.json $(OUTPUT_FILE_STDOUT_SUCCESS)
diff --git a/src/test/run-make-fulldeps/libtest-json/f.rs b/src/test/run-make-fulldeps/libtest-json/f.rs
index f5e44c2c244..95ff36bd764 100644
--- a/src/test/run-make-fulldeps/libtest-json/f.rs
+++ b/src/test/run-make-fulldeps/libtest-json/f.rs
@@ -1,11 +1,12 @@
 #[test]
 fn a() {
+    println!("print from successful test");
     // Should pass
 }
 
 #[test]
 fn b() {
-    assert!(false)
+    assert!(false);
 }
 
 #[test]
diff --git a/src/test/run-make-fulldeps/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output-default.json
index 0caf268aa00..8046d722217 100644
--- a/src/test/run-make-fulldeps/libtest-json/output.json
+++ b/src/test/run-make-fulldeps/libtest-json/output-default.json
@@ -2,7 +2,7 @@
 { "type": "test", "event": "started", "name": "a" }
 { "type": "test", "name": "a", "event": "ok" }
 { "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
 { "type": "test", "event": "started", "name": "c" }
 { "type": "test", "name": "c", "event": "ok" }
 { "type": "test", "event": "started", "name": "d" }
diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
new file mode 100644
index 00000000000..303316278d8
--- /dev/null
+++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
@@ -0,0 +1,10 @@
+{ "type": "suite", "event": "started", "test_count": 4 }
+{ "type": "test", "event": "started", "name": "a" }
+{ "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" }
+{ "type": "test", "event": "started", "name": "b" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
+{ "type": "test", "event": "started", "name": "c" }
+{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
+{ "type": "test", "event": "started", "name": "d" }
+{ "type": "test", "name": "d", "event": "ignored" }
+{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0 }
diff --git a/src/test/ui/auxiliary/cond_plugin.rs b/src/test/ui/auxiliary/cond_plugin.rs
index 1f97b556a07..2819541bf69 100644
--- a/src/test/ui/auxiliary/cond_plugin.rs
+++ b/src/test/ui/auxiliary/cond_plugin.rs
@@ -3,6 +3,7 @@
 
 #![crate_type = "proc-macro"]
 #![feature(proc_macro_hygiene)]
+#![feature(proc_macro_quote)]
 
 extern crate proc_macro;
 
diff --git a/src/test/ui/auxiliary/proc_macro_def.rs b/src/test/ui/auxiliary/proc_macro_def.rs
index dfc5a42d19c..49cfb5518ba 100644
--- a/src/test/ui/auxiliary/proc_macro_def.rs
+++ b/src/test/ui/auxiliary/proc_macro_def.rs
@@ -3,6 +3,7 @@
 
 #![crate_type = "proc-macro"]
 #![feature(proc_macro_hygiene)]
+#![feature(proc_macro_quote)]
 
 extern crate proc_macro;
 
diff --git a/src/test/ui/lang-item-missing-generator.rs b/src/test/ui/lang-item-missing-generator.rs
new file mode 100644
index 00000000000..0c329542928
--- /dev/null
+++ b/src/test/ui/lang-item-missing-generator.rs
@@ -0,0 +1,19 @@
+// error-pattern: requires `generator` lang_item
+#![feature(no_core, lang_items, unboxed_closures)]
+#![no_core]
+
+#[lang = "sized"] pub trait Sized { }
+
+#[lang = "fn_once"]
+#[rustc_paren_sugar]
+pub trait FnOnce<Args> {
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub fn abc() -> impl FnOnce(f32) {
+    |_| {}
+}
+
+fn main() {}
diff --git a/src/test/ui/lang-item-missing-generator.stderr b/src/test/ui/lang-item-missing-generator.stderr
new file mode 100644
index 00000000000..d0cc4b81be6
--- /dev/null
+++ b/src/test/ui/lang-item-missing-generator.stderr
@@ -0,0 +1,4 @@
+error: requires `generator` lang_item
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
index b50ed7ca92a..c460db36f1a 100644
--- a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
+++ b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
@@ -6,7 +6,7 @@
 
 extern crate proc_macro;
 
-use proc_macro::{quote, Span, TokenStream};
+use proc_macro::{quote, Span, TokenStream, TokenTree};
 
 fn assert_same_span(a: Span, b: Span) {
     assert_eq!(a.start(), b.start());
@@ -24,12 +24,22 @@ pub fn make_foo(_: TokenStream) -> TokenStream {
     };
 
     // Check that all spans are equal.
-    let mut span = None;
+    // FIXME: `quote!` gives def-site spans to idents and literals,
+    // but leaves (default) call-site spans on groups and punctuation.
+    let mut span_call = None;
+    let mut span_def = None;
     for tt in result.clone() {
-        match span {
-            None => span = Some(tt.span()),
-            Some(span) => assert_same_span(tt.span(), span),
+        match tt {
+            TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def {
+                None => span_def = Some(tt.span()),
+                Some(span) => assert_same_span(tt.span(), span),
+            }
+            TokenTree::Punct(..) | TokenTree::Group(..) => match span_call {
+                None => span_call = Some(tt.span()),
+                Some(span) => assert_same_span(tt.span(), span),
+            }
         }
+
     }
 
     result
diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr
index 250773a1853..0eef4a2a678 100644
--- a/src/test/ui/macros/same-sequence-span.stderr
+++ b/src/test/ui/macros/same-sequence-span.stderr
@@ -17,11 +17,15 @@ LL |                $(= $z:tt)*
 error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
   --> $DIR/same-sequence-span.rs:20:1
    |
-LL | proc_macro_sequence::make_foo!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |   proc_macro_sequence::make_foo!();
+   |   ^--------------------------------
+   |   |
+   |  _in this macro invocation
    | |
-   | not allowed after `expr` fragments
-   | in this macro invocation
+LL | |
+LL | |
+LL | | fn main() {}
+...  |
    |
    = note: allowed there are: `=>`, `,` or `;`
 
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs
new file mode 100644
index 00000000000..055781d2c60
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-on-definitions.rs
@@ -0,0 +1,12 @@
+// check-pass
+// aux-build:attributes-on-definitions.rs
+
+#![forbid(unsafe_code)]
+
+extern crate attributes_on_definitions;
+
+attributes_on_definitions::with_attrs!();
+//~^ WARN use of deprecated item
+// No errors about the use of unstable and unsafe code inside the macro.
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr
new file mode 100644
index 00000000000..c61e043b229
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr
@@ -0,0 +1,8 @@
+warning: use of deprecated item 'attributes_on_definitions::with_attrs': test
+  --> $DIR/attributes-on-definitions.rs:8:1
+   |
+LL | attributes_on_definitions::with_attrs!();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
diff --git a/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs
new file mode 100644
index 00000000000..93a339840d6
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs
@@ -0,0 +1,23 @@
+// force-host
+// no-prefer-dynamic
+
+#![feature(allow_internal_unsafe)]
+#![feature(allow_internal_unstable)]
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+#[allow_internal_unstable(proc_macro_internals)]
+#[allow_internal_unsafe]
+#[deprecated(since = "1.0.0", note = "test")]
+pub fn with_attrs(_: TokenStream) -> TokenStream {
+    "
+    extern crate proc_macro;
+    use ::proc_macro::bridge;
+
+    fn contains_unsafe() { unsafe {} }
+    ".parse().unwrap()
+}
diff --git a/src/test/ui/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr
index a0c1f9cd5c0..e7f705c7feb 100644
--- a/src/test/ui/proc-macro/multispan.stderr
+++ b/src/test/ui/proc-macro/multispan.stderr
@@ -1,8 +1,19 @@
 error: hello to you, too!
-  --> $DIR/multispan.rs:14:5
-   |
-LL |     hello!(hi);
-   |     ^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:14:5
+   |
+LL |       hello!(hi);
+   |       ----------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:14:12
@@ -11,10 +22,21 @@ LL |     hello!(hi);
    |            ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:17:5
-   |
-LL |     hello!(hi hi);
-   |     ^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:17:5
+   |
+LL |       hello!(hi hi);
+   |       -------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:17:12
@@ -23,10 +45,21 @@ LL |     hello!(hi hi);
    |            ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:20:5
-   |
-LL |     hello!(hi hi hi);
-   |     ^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:20:5
+   |
+LL |       hello!(hi hi hi);
+   |       ----------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:20:12
@@ -35,10 +68,21 @@ LL |     hello!(hi hi hi);
    |            ^^ ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:23:5
-   |
-LL |     hello!(hi hey hi yo hi beep beep hi hi);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:23:5
+   |
+LL |       hello!(hi hey hi yo hi beep beep hi hi);
+   |       ---------------------------------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:23:12
@@ -47,10 +91,21 @@ LL |     hello!(hi hey hi yo hi beep beep hi hi);
    |            ^^     ^^    ^^           ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:24:5
-   |
-LL |     hello!(hi there, hi how are you? hi... hi.);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:24:5
+   |
+LL |       hello!(hi there, hi how are you? hi... hi.);
+   |       -------------------------------------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:24:12
@@ -59,10 +114,21 @@ LL |     hello!(hi there, hi how are you? hi... hi.);
    |            ^^        ^^              ^^    ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:25:5
-   |
-LL |     hello!(whoah. hi di hi di ho);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:25:5
+   |
+LL |       hello!(whoah. hi di hi di ho);
+   |       ------------------------------ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:25:19
@@ -71,10 +137,21 @@ LL |     hello!(whoah. hi di hi di ho);
    |                   ^^    ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:26:5
-   |
-LL |     hello!(hi good hi and good bye);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:26:5
+   |
+LL |       hello!(hi good hi and good bye);
+   |       -------------------------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:26:12
diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr
index 0a6cbe13098..0698b0f4754 100644
--- a/src/test/ui/proc-macro/three-equals.stderr
+++ b/src/test/ui/proc-macro/three-equals.stderr
@@ -1,8 +1,19 @@
 error: found 2 equal signs, need exactly 3
-  --> $DIR/three-equals.rs:15:5
-   |
-LL |     three_equals!(==);
-   |     ^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/three-equals.rs:42:1
+   |
+LL | / pub fn three_equals(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |         return TokenStream::new();
+...  |
+LL | |     "3".parse().unwrap()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/three-equals.rs:15:5
+   |
+LL |       three_equals!(==);
+   |       ------------------ in this macro invocation
    |
    = help: input must be: `===`