about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorDjzin <djzin@users.noreply.github.com>2017-05-27 14:31:47 +0100
committerDjzin <djzin@users.noreply.github.com>2017-05-27 14:31:47 +0100
commit74751358e625878306aa193fed788e79aa53d4fa (patch)
tree1ba9b336d1ddb45d9f688d69f5bd4ede028db622 /src/libsyntax_ext
parentc6307a2fa55c3d62c06b85b349257a8194093442 (diff)
parent3e7908f616745573a11ad7dfad245f12be0069da (diff)
downloadrust-74751358e625878306aa193fed788e79aa53d4fa.tar.gz
rust-74751358e625878306aa193fed788e79aa53d4fa.zip
Merge remote-tracking branch 'upstream/master' into fast-swap
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/Cargo.toml2
-rw-r--r--src/libsyntax_ext/asm.rs12
-rw-r--r--src/libsyntax_ext/concat_idents.rs2
-rw-r--r--src/libsyntax_ext/deriving/clone.rs2
-rw-r--r--src/libsyntax_ext/deriving/cmp/eq.rs2
-rw-r--r--src/libsyntax_ext/deriving/custom.rs8
-rw-r--r--src/libsyntax_ext/deriving/debug.rs4
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs17
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs12
-rw-r--r--src/libsyntax_ext/deriving/mod.rs40
-rw-r--r--src/libsyntax_ext/env.rs7
-rw-r--r--src/libsyntax_ext/format.rs22
-rw-r--r--src/libsyntax_ext/global_asm.rs65
-rw-r--r--src/libsyntax_ext/lib.rs9
-rw-r--r--src/libsyntax_ext/proc_macro_registrar.rs20
15 files changed, 130 insertions, 94 deletions
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 960db792a62..bdcec26cb83 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 fmt_macros = { path = "../libfmt_macros" }
-log = { path = "../liblog" }
+log = "0.3"
 proc_macro = { path = "../libproc_macro" }
 rustc_errors = { path = "../librustc_errors" }
 syntax = { path = "../libsyntax" }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 767ec94a0ce..923e8072f43 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -13,7 +13,6 @@
 use self::State::*;
 
 use syntax::ast;
-use syntax::codemap;
 use syntax::ext::base;
 use syntax::ext::base::*;
 use syntax::feature_gate;
@@ -240,15 +239,6 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
         }
     }
 
-    let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
-        call_site: sp,
-        callee: codemap::NameAndSpan {
-            format: codemap::MacroBang(Symbol::intern("asm")),
-            span: None,
-            allow_internal_unstable: false,
-        },
-    });
-
     MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprKind::InlineAsm(P(ast::InlineAsm {
@@ -260,7 +250,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
             volatile: volatile,
             alignstack: alignstack,
             dialect: dialect,
-            expn_id: expn_id,
+            ctxt: cx.backtrace(),
         })),
         span: sp,
         attrs: ast::ThinVec::new(),
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 1fc1bdff593..dc4b8eb24cd 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -61,7 +61,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
         fn path(&self) -> ast::Path {
             ast::Path {
                 span: self.span,
-                segments: vec![self.ident.into()],
+                segments: vec![ast::PathSegment::from_ident(self.ident, self.span)],
             }
         }
     }
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index d14b59d6c70..1993d6ebe5b 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -111,7 +111,7 @@ fn cs_clone_shallow(name: &str,
                         ty: P<ast::Ty>, span: Span, helper_name: &str) {
         // Generate statement `let _: helper_name<ty>;`,
         // set the expn ID so we can use the unstable struct.
-        let span = super::allow_unstable(cx, span, "derive(Clone)");
+        let span = Span { ctxt: cx.backtrace(), ..span};
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&["clone", helper_name]),
                                         vec![], vec![ty], vec![]);
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 6ab5987a159..eef21492deb 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -58,7 +58,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
                         ty: P<ast::Ty>, span: Span, helper_name: &str) {
         // Generate statement `let _: helper_name<ty>;`,
         // set the expn ID so we can use the unstable struct.
-        let span = super::allow_unstable(cx, span, "derive(Eq)");
+        let span = Span { ctxt: cx.backtrace(), ..span };
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&["cmp", helper_name]),
                                         vec![], vec![ty], vec![]);
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index a7e2d82bb97..b01ef65e5fe 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -23,9 +23,11 @@ struct MarkAttrs<'a>(&'a [ast::Name]);
 
 impl<'a> Visitor<'a> for MarkAttrs<'a> {
     fn visit_attribute(&mut self, attr: &Attribute) {
-        if self.0.contains(&attr.name()) {
-            mark_used(attr);
-            mark_known(attr);
+        if let Some(name) = attr.name() {
+            if self.0.contains(&name) {
+                mark_used(attr);
+                mark_known(attr);
+            }
         }
     }
 
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index a767716466c..ec4cb815960 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -66,8 +66,8 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E
         StaticEnum(..) => cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`"),
     };
 
-    // We want to make sure we have the expn_id set so that we can use unstable methods
-    let span = Span { expn_id: cx.backtrace(), ..span };
+    // We want to make sure we have the ctxt set so that we can use unstable methods
+    let span = Span { ctxt: cx.backtrace(), ..span };
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
     let builder = Ident::from_str("builder");
     let builder_expr = cx.expr_ident(span, builder.clone());
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index fe492bd7fc8..be7883cad5f 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -375,7 +375,7 @@ fn find_type_parameters(ty: &ast::Ty,
         }
 
         fn visit_mac(&mut self, mac: &ast::Mac) {
-            let span = Span { expn_id: self.span.expn_id, ..mac.span };
+            let span = Span { ctxt: self.span.ctxt, ..mac.span };
             self.cx.span_err(span, "`derive` cannot be used on items with type macros");
         }
     }
@@ -439,7 +439,7 @@ impl<'a> TraitDef<'a> {
                 attrs.extend(item.attrs
                     .iter()
                     .filter(|a| {
-                        match &*a.name().as_str() {
+                        a.name().is_some() && match &*a.name().unwrap().as_str() {
                             "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
                             _ => false,
                         }
@@ -658,6 +658,7 @@ impl<'a> TraitDef<'a> {
                 a,
                 ast::ItemKind::Impl(unsafety,
                                     ast::ImplPolarity::Positive,
+                                    ast::Defaultness::Final,
                                     trait_generics,
                                     opt_trait_ref,
                                     self_type,
@@ -773,7 +774,7 @@ fn find_repr_type_name(diagnostic: &Handler, type_attrs: &[ast::Attribute]) -> &
     for a in type_attrs {
         for r in &attr::find_repr_attrs(diagnostic, a) {
             repr_type_name = match *r {
-                attr::ReprPacked | attr::ReprSimd => continue,
+                attr::ReprPacked | attr::ReprSimd | attr::ReprAlign(_) => continue,
                 attr::ReprExtern => "i32",
 
                 attr::ReprInt(attr::SignedInt(ast::IntTy::Is)) => "isize",
@@ -1458,7 +1459,7 @@ impl<'a> MethodDef<'a> {
             .iter()
             .map(|v| {
                 let ident = v.node.name;
-                let sp = Span { expn_id: trait_.span.expn_id, ..v.span };
+                let sp = Span { ctxt: trait_.span.ctxt, ..v.span };
                 let summary = trait_.summarise_struct(cx, &v.node.data);
                 (ident, sp, summary)
             })
@@ -1478,7 +1479,7 @@ impl<'a> TraitDef<'a> {
         let mut named_idents = Vec::new();
         let mut just_spans = Vec::new();
         for field in struct_def.fields() {
-            let sp = Span { expn_id: self.span.expn_id, ..field.span };
+            let sp = Span { ctxt: self.span.ctxt, ..field.span };
             match field.ident {
                 Some(ident) => named_idents.push((ident, sp)),
                 _ => just_spans.push(sp),
@@ -1523,7 +1524,7 @@ impl<'a> TraitDef<'a> {
         let mut paths = Vec::new();
         let mut ident_exprs = Vec::new();
         for (i, struct_field) in struct_def.fields().iter().enumerate() {
-            let sp = Span { expn_id: self.span.expn_id, ..struct_field.span };
+            let sp = Span { ctxt: self.span.ctxt, ..struct_field.span };
             let ident = cx.ident_of(&format!("{}_{}", prefix, i));
             paths.push(codemap::Spanned {
                 span: sp,
@@ -1544,7 +1545,7 @@ impl<'a> TraitDef<'a> {
                             cx.span_bug(sp, "a braced struct with unnamed fields in `derive`");
                         }
                         codemap::Spanned {
-                            span: Span { expn_id: self.span.expn_id, ..pat.span },
+                            span: Span { ctxt: self.span.ctxt, ..pat.span },
                             node: ast::FieldPat {
                                 ident: ident.unwrap(),
                                 pat: pat,
@@ -1576,7 +1577,7 @@ impl<'a> TraitDef<'a> {
          mutbl: ast::Mutability)
          -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
         let variant_ident = variant.node.name;
-        let sp = Span { expn_id: self.span.expn_id, ..variant.span };
+        let sp = Span { ctxt: self.span.ctxt, ..variant.span };
         let variant_path = cx.path(sp, vec![enum_ident, variant_ident]);
         self.create_struct_pattern(cx, variant_path, &variant.node.data, prefix, mutbl)
     }
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index cfd52381538..9c89f99cbb5 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -118,14 +118,14 @@ pub fn nil_ty<'r>() -> Ty<'r> {
 
 fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
     match *lt {
-        Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
+        Some(s) => Some(cx.lifetime(span, Ident::from_str(s))),
         None => None,
     }
 }
 
 fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
     match *lt {
-        Some(ref s) => vec![cx.lifetime(span, cx.ident_of(*s).name)],
+        Some(s) => vec![cx.lifetime(span, Ident::from_str(s))],
         None => vec![],
     }
 }
@@ -243,11 +243,11 @@ impl<'a> LifetimeBounds<'a> {
                        -> Generics {
         let lifetimes = self.lifetimes
             .iter()
-            .map(|&(ref lt, ref bounds)| {
+            .map(|&(lt, ref bounds)| {
                 let bounds = bounds.iter()
-                    .map(|b| cx.lifetime(span, cx.ident_of(*b).name))
+                    .map(|b| cx.lifetime(span, Ident::from_str(b)))
                     .collect();
-                cx.lifetime_def(span, cx.ident_of(*lt).name, vec![], bounds)
+                cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds)
             })
             .collect();
         let ty_params = self.bounds
@@ -277,7 +277,7 @@ pub fn get_explicit_self(cx: &ExtCtxt,
                 respan(span,
                        match *ptr {
                            Borrowed(ref lt, mutbl) => {
-                               let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
+                               let lt = lt.map(|s| cx.lifetime(span, Ident::from_str(s)));
                                SelfKind::Region(lt, mutbl)
                            }
                            Raw(_) => {
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index b51591bf89d..00dcfc7a587 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -12,9 +12,9 @@
 
 use std::rc::Rc;
 use syntax::ast;
-use syntax::codemap;
 use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver};
 use syntax::ext::build::AstBuilder;
+use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
@@ -25,12 +25,6 @@ macro_rules! pathvec {
     )
 }
 
-macro_rules! path {
-    ($($x:tt)*) => (
-        ::ext::deriving::generic::ty::Path::new( pathvec![ $($x)* ] )
-    )
-}
-
 macro_rules! path_local {
     ($x:ident) => (
         ::deriving::generic::ty::Path::new_local(stringify!($x))
@@ -74,20 +68,6 @@ pub mod ord;
 
 pub mod generic;
 
-fn allow_unstable(cx: &mut ExtCtxt, span: Span, attr_name: &str) -> Span {
-    Span {
-        expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
-            call_site: span,
-            callee: codemap::NameAndSpan {
-                format: codemap::MacroAttribute(Symbol::intern(attr_name)),
-                span: Some(span),
-                allow_internal_unstable: true,
-            },
-        }),
-        ..span
-    }
-}
-
 macro_rules! derive_traits {
     ($( $name:expr => $func:path, )+) => {
         pub fn is_builtin_trait(name: ast::Name) -> bool {
@@ -177,15 +157,15 @@ fn call_intrinsic(cx: &ExtCtxt,
                   intrinsic: &str,
                   args: Vec<P<ast::Expr>>)
                   -> P<ast::Expr> {
-    span.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
-        call_site: span,
-        callee: codemap::NameAndSpan {
-            format: codemap::MacroAttribute(Symbol::intern("derive")),
-            span: Some(span),
-            allow_internal_unstable: true,
-        },
-    });
-
+    if cx.current_expansion.mark.expn_info().unwrap().callee.allow_internal_unstable {
+        span.ctxt = cx.backtrace();
+    } else { // Avoid instability errors with user defined curstom derives, cc #36316
+        let mut info = cx.current_expansion.mark.expn_info().unwrap();
+        info.callee.allow_internal_unstable = true;
+        let mark = Mark::fresh(Mark::root());
+        mark.set_expn_info(info);
+        span.ctxt = SyntaxContext::empty().apply_mark(mark);
+    }
     let path = cx.std_path(&["intrinsics", intrinsic]);
     let call = cx.expr_call_global(span, path, args);
 
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index ecf0a8f377e..affebbabbbd 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -13,7 +13,7 @@
 // interface.
 //
 
-use syntax::ast;
+use syntax::ast::{self, Ident};
 use syntax::ext::base::*;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
@@ -39,10 +39,9 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
                                      cx.std_path(&["option", "Option", "None"]),
                                      Vec::new(),
                                      vec![cx.ty_rptr(sp,
-                                                     cx.ty_ident(sp, cx.ident_of("str")),
+                                                     cx.ty_ident(sp, Ident::from_str("str")),
                                                      Some(cx.lifetime(sp,
-                                                                      cx.ident_of("'static")
-                                                                          .name)),
+                                                                      Ident::from_str("'static"))),
                                                      ast::Mutability::Immutable)],
                                      Vec::new()))
         }
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index d2afa08cada..24c1dfe289b 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -508,7 +508,7 @@ impl<'a, 'b> Context<'a, 'b> {
         let sp = piece_ty.span;
         let ty = ecx.ty_rptr(sp,
                              ecx.ty(sp, ast::TyKind::Slice(piece_ty)),
-                             Some(ecx.lifetime(sp, keywords::StaticLifetime.name())),
+                             Some(ecx.lifetime(sp, keywords::StaticLifetime.ident())),
                              ast::Mutability::Immutable);
         let slice = ecx.expr_vec_slice(sp, pieces);
         // static instead of const to speed up codegen by not requiring this to be inlined
@@ -536,7 +536,7 @@ impl<'a, 'b> Context<'a, 'b> {
 
         // First, build up the static array which will become our precompiled
         // format "string"
-        let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.name());
+        let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.ident());
         let piece_ty = self.ecx.ty_rptr(self.fmtsp,
                                         self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
                                         Some(static_lifetime),
@@ -559,11 +559,7 @@ impl<'a, 'b> Context<'a, 'b> {
             let name = self.ecx.ident_of(&format!("__arg{}", i));
             pats.push(self.ecx.pat_ident(DUMMY_SP, name));
             for ref arg_ty in self.arg_unique_types[i].iter() {
-                locals.push(Context::format_arg(self.ecx,
-                                                self.macsp,
-                                                e.span,
-                                                arg_ty,
-                                                self.ecx.expr_ident(e.span, name)));
+                locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
             }
             heads.push(self.ecx.expr_addr_of(e.span, e));
         }
@@ -576,11 +572,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 Exact(i) => spans_pos[i],
                 _ => panic!("should never happen"),
             };
-            counts.push(Context::format_arg(self.ecx,
-                                            self.macsp,
-                                            span,
-                                            &Count,
-                                            self.ecx.expr_ident(span, name)));
+            counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count, name));
         }
 
         // Now create a vector containing all the arguments
@@ -641,10 +633,12 @@ impl<'a, 'b> Context<'a, 'b> {
 
     fn format_arg(ecx: &ExtCtxt,
                   macsp: Span,
-                  sp: Span,
+                  mut sp: Span,
                   ty: &ArgumentType,
-                  arg: P<ast::Expr>)
+                  arg: ast::Ident)
                   -> P<ast::Expr> {
+        sp.ctxt = sp.ctxt.apply_mark(ecx.current_expansion.mark);
+        let arg = ecx.expr_ident(sp, arg);
         let trait_ = match *ty {
             Placeholder(ref tyname) => {
                 match &tyname[..] {
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
new file mode 100644
index 00000000000..dc67e1c45f6
--- /dev/null
+++ b/src/libsyntax_ext/global_asm.rs
@@ -0,0 +1,65 @@
+// 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",
+/// "file-scoped", or "module-level" assembly. These synonyms
+/// all correspond to LLVM's module-level inline assembly instruction.
+///
+/// For example, `global_asm!("some assembly here")` translates to
+/// LLVM's `module asm "some assembly here"`. All of LLVM's caveats
+/// therefore apply.
+
+use syntax::ast;
+use syntax::ext::base;
+use syntax::ext::base::*;
+use syntax::feature_gate;
+use syntax::ptr::P;
+use syntax::symbol::Symbol;
+use syntax_pos::Span;
+use syntax::tokenstream;
+
+use syntax::util::small_vector::SmallVector;
+
+pub const MACRO: &'static str = "global_asm";
+
+pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
+                              sp: Span,
+                              tts: &[tokenstream::TokenTree]) -> Box<base::MacResult + 'cx> {
+    if !cx.ecfg.enable_global_asm() {
+        feature_gate::emit_feature_err(&cx.parse_sess,
+                                       MACRO,
+                                       sp,
+                                       feature_gate::GateIssue::Language,
+                                       feature_gate::EXPLAIN_GLOBAL_ASM);
+        return DummyResult::any(sp);
+    }
+
+    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") {
+        Some((s, st)) => (s, st),
+        None => return DummyResult::any(sp),
+    };
+
+    MacEager::items(SmallVector::one(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: asm,
+            ctxt: cx.backtrace(),
+        })),
+        vis: ast::Visibility::Inherited,
+        span: sp,
+    })))
+}
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 1e9b112b6df..60f5d24ac97 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -11,7 +11,6 @@
 //! Syntax extensions in the Rust compiler.
 
 #![crate_name = "syntax_ext"]
-#![unstable(feature = "rustc_private", issue = "27812")]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
@@ -20,8 +19,10 @@
 #![deny(warnings)]
 
 #![feature(proc_macro_internals)]
-#![feature(rustc_private)]
-#![feature(staged_api)]
+
+#![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
+#![cfg_attr(stage0, feature(rustc_private))]
+#![cfg_attr(stage0, feature(staged_api))]
 
 extern crate fmt_macros;
 extern crate log;
@@ -38,6 +39,7 @@ mod concat_idents;
 mod env;
 mod format;
 mod format_foreign;
+mod global_asm;
 mod log_syntax;
 mod trace_macros;
 
@@ -99,6 +101,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver,
         module_path: expand_mod,
 
         asm: asm::expand_asm,
+        global_asm: global_asm::expand_global_asm,
         cfg: cfg::expand_cfg,
         concat: concat::expand_syntax_ext,
         concat_idents: concat_idents::expand_syntax_ext,
diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs
index 5adaf470f23..ab6d73e5061 100644
--- a/src/libsyntax_ext/proc_macro_registrar.rs
+++ b/src/libsyntax_ext/proc_macro_registrar.rs
@@ -17,6 +17,7 @@ use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute};
 use syntax::ext::base::ExtCtxt;
 use syntax::ext::build::AstBuilder;
 use syntax::ext::expand::ExpansionConfig;
+use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::fold::Folder;
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
@@ -248,7 +249,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
     fn visit_item(&mut self, item: &'a ast::Item) {
         if let ast::ItemKind::MacroDef(..) = item.node {
             if self.is_proc_macro_crate &&
-               item.attrs.iter().any(|attr| attr.name() == "macro_export") {
+               item.attrs.iter().any(|attr| attr.path == "macro_export") {
                 let msg =
                     "cannot export macro_rules! macros from a `proc-macro` crate type currently";
                 self.handler.span_err(item.span, msg);
@@ -270,12 +271,12 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         for attr in &item.attrs {
             if is_proc_macro_attr(&attr) {
                 if let Some(prev_attr) = found_attr {
-                    let msg = if attr.name() == prev_attr.name() {
+                    let msg = if attr.path == prev_attr.path {
                         format!("Only one `#[{}]` attribute is allowed on any given function",
-                                attr.name())
+                                attr.path)
                     } else {
                         format!("`#[{}]` and `#[{}]` attributes cannot both be applied \
-                                to the same function", attr.name(), prev_attr.name())
+                                to the same function", attr.path, prev_attr.path)
                     };
 
                     self.handler.struct_span_err(attr.span(), &msg)
@@ -299,7 +300,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
 
         if !is_fn {
             let msg = format!("the `#[{}]` attribute may only be used on bare functions",
-                              attr.name());
+                              attr.path);
 
             self.handler.span_err(attr.span(), &msg);
             return;
@@ -311,7 +312,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
 
         if !self.is_proc_macro_crate {
             let msg = format!("the `#[{}]` attribute is only usable with crates of the \
-                              `proc-macro` crate type", attr.name());
+                              `proc-macro` crate type", attr.path);
 
             self.handler.span_err(attr.span(), &msg);
             return;
@@ -328,7 +329,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         visit::walk_item(self, item);
     }
 
-    fn visit_mod(&mut self, m: &'a ast::Mod, _s: Span, id: NodeId) {
+    fn visit_mod(&mut self, m: &'a ast::Mod, _s: Span, _a: &[ast::Attribute], id: NodeId) {
         let mut prev_in_root = self.in_root;
         if id != ast::CRATE_NODE_ID {
             prev_in_root = mem::replace(&mut self.in_root, false);
@@ -360,7 +361,8 @@ fn mk_registrar(cx: &mut ExtCtxt,
                 custom_derives: &[ProcMacroDerive],
                 custom_attrs: &[ProcMacroDef],
                 custom_macros: &[ProcMacroDef]) -> P<ast::Item> {
-    let eid = cx.codemap().record_expansion(ExpnInfo {
+    let mark = Mark::fresh(Mark::root());
+    mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         callee: NameAndSpan {
             format: MacroAttribute(Symbol::intern("proc_macro")),
@@ -368,7 +370,7 @@ fn mk_registrar(cx: &mut ExtCtxt,
             allow_internal_unstable: true,
         }
     });
-    let span = Span { expn_id: eid, ..DUMMY_SP };
+    let span = Span { ctxt: SyntaxContext::empty().apply_mark(mark), ..DUMMY_SP };
 
     let proc_macro = Ident::from_str("proc_macro");
     let krate = cx.item(span,