diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md
index 14774e2d2293c..a5599395f7965 100644
--- a/src/doc/unstable-book/src/SUMMARY.md
+++ b/src/doc/unstable-book/src/SUMMARY.md
@@ -83,6 +83,7 @@
 - [future_atomic_orderings](future-atomic-orderings.md)
 - [generic_param_attrs](generic-param-attrs.md)
 - [get_type_id](get-type-id.md)
+- [global_asm](global_asm.md)
 - [heap_api](heap-api.md)
 - [i128](i128.md)
 - [i128_type](i128-type.md)
diff --git a/src/doc/unstable-book/src/asm.md b/src/doc/unstable-book/src/asm.md
index 032d9d8124026..5e68be633e7ab 100644
--- a/src/doc/unstable-book/src/asm.md
+++ b/src/doc/unstable-book/src/asm.md
@@ -189,3 +189,5 @@ constraints, etc.
 
 [llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions
 
+If you need more power and don't mind losing some of the niceties of
+`asm!`, check out [global_asm](global_asm.html).
diff --git a/src/doc/unstable-book/src/global_asm.md b/src/doc/unstable-book/src/global_asm.md
new file mode 100644
index 0000000000000..44921aa309f84
--- /dev/null
+++ b/src/doc/unstable-book/src/global_asm.md
@@ -0,0 +1,78 @@
+# `global_asm`
+
+The tracking issue for this feature is: [#35119]
+
+[#35119]: https://github.com/rust-lang/rust/issues/35119
+
+------------------------
+
+The `global_asm!` macro allows the programmer to write arbitrary
+assembly outside the scope of a function body, passing it through
+`rustc` and `llvm` to the assembler. The macro is a no-frills
+interface to LLVM's concept of [module-level inline assembly]. That is,
+all caveats applicable to LLVM's module-level inline assembly apply
+to `global_asm!`.
+
+[module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly
+
+`global_asm!` fills a role not currently satisfied by either `asm!`
+or `#[naked]` functions. The programmer has _all_ features of the
+assembler at their disposal. The linker will expect to resolve any
+symbols defined in the inline assembly, modulo any symbols marked as
+external. It also means syntax for directives and assembly follow the
+conventions of the assembler in your toolchain.
+
+A simple usage looks like this:
+
+```rust,ignore
+# #![feature(global_asm)]
+# you also need relevant target_arch cfgs
+global_asm!(include_str!("something_neato.s"));
+```
+
+And a more complicated usage looks like this:
+
+```rust,ignore
+# #![feature(global_asm)]
+# #![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+
+pub mod sally {
+    global_asm!(r#"
+        .global foo
+      foo:
+        jmp baz
+    "#);
+
+    #[no_mangle]
+    pub unsafe extern "C" fn baz() {}
+}
+
+// the symbols `foo` and `bar` are global, no matter where
+// `global_asm!` was used.
+extern "C" {
+    fn foo();
+    fn bar();
+}
+
+pub mod harry {
+    global_asm!(r#"
+        .global bar
+      bar:
+        jmp quux
+    "#);
+
+    #[no_mangle]
+    pub unsafe extern "C" fn quux() {}
+}
+```
+
+You may use `global_asm!` multiple times, anywhere in your crate, in
+whatever way suits you. The effect is as if you concatenated all
+usages and placed the larger, single usage in the crate root.
+
+------------------------
+
+If you don't need quite as much power and flexibility as
+`global_asm!` provides, and you don't mind restricting your inline
+assembly to `fn` bodies only, you might try the [asm](asm.html)
+feature instead.
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 7bab4a8d725dc..771031db0c045 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -57,6 +57,8 @@ pub enum Def {
     // Macro namespace
     Macro(DefId, MacroKind),
 
+    GlobalAsm(DefId),
+
     // Both namespaces
     Err,
 }
@@ -144,7 +146,8 @@ impl Def {
             Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) |
             Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
             Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
-            Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) | Def::Macro(id, ..) => {
+            Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) | Def::Macro(id, ..) |
+            Def::GlobalAsm(id) => {
                 id
             }
 
@@ -185,6 +188,7 @@ impl Def {
             Def::Label(..) => "label",
             Def::SelfTy(..) => "self type",
             Def::Macro(..) => "macro",
+            Def::GlobalAsm(..) => "global asm",
             Def::Err => "unresolved item",
         }
     }
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 2c8b145f126cd..2b0d53b2bc356 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -474,6 +474,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_id(item.id);
             walk_list!(visitor, visit_foreign_item, &foreign_module.items);
         }
+        ItemGlobalAsm(_) => {
+            visitor.visit_id(item.id);
+        }
         ItemTy(ref typ, ref type_parameters) => {
             visitor.visit_id(item.id);
             visitor.visit_ty(typ);
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 30fec50d4eb6f..c86aaa7bf6727 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -646,6 +646,13 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
+    fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
+        P(hir::GlobalAsm {
+            asm: ga.asm,
+            ctxt: ga.ctxt,
+        })
+    }
+
     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
         Spanned {
             node: hir::Variant_ {
@@ -1288,6 +1295,7 @@ impl<'a> LoweringContext<'a> {
             }
             ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
             ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
+            ItemKind::GlobalAsm(ref ga) => hir::ItemGlobalAsm(self.lower_global_asm(ga)),
             ItemKind::Ty(ref t, ref generics) => {
                 hir::ItemTy(self.lower_ty(t), self.lower_generics(generics))
             }
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index c1417f718b27a..7ff5152c71a2c 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -109,6 +109,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
                 DefPathData::ValueNs(i.ident.name.as_str()),
             ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_str()),
             ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
+            ItemKind::GlobalAsm(..) => DefPathData::Misc,
             ItemKind::Use(ref view_path) => {
                 match view_path.node {
                     ViewPathGlob(..) => {}
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index cfafec00ae20d..48b8a819fff03 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -1077,6 +1077,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemFn(..) => "fn",
                 ItemMod(..) => "mod",
                 ItemForeignMod(..) => "foreign mod",
+                ItemGlobalAsm(..) => "global asm",
                 ItemTy(..) => "ty",
                 ItemEnum(..) => "enum",
                 ItemStruct(..) => "struct",
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 0da405d1821d3..562b58844409d 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1495,6 +1495,12 @@ pub struct ForeignMod {
     pub items: HirVec<ForeignItem>,
 }
 
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct GlobalAsm {
+    pub asm: Symbol,
+    pub ctxt: SyntaxContext,
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct EnumDef {
     pub variants: HirVec<Variant>,
@@ -1686,6 +1692,8 @@ pub enum Item_ {
     ItemMod(Mod),
     /// An external module
     ItemForeignMod(ForeignMod),
+    /// Module-level inline assembly (from global_asm!)
+    ItemGlobalAsm(P<GlobalAsm>),
     /// A type alias, e.g. `type Foo = Bar<u8>`
     ItemTy(P<Ty>, Generics),
     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
@@ -1720,6 +1728,7 @@ impl Item_ {
             ItemFn(..) => "function",
             ItemMod(..) => "module",
             ItemForeignMod(..) => "foreign module",
+            ItemGlobalAsm(..) => "global asm",
             ItemTy(..) => "type alias",
             ItemEnum(..) => "enum",
             ItemStruct(..) => "struct",
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 4a5a35aa82ca0..5144f75b1a363 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -633,6 +633,11 @@ impl<'a> State<'a> {
                 self.print_foreign_mod(nmod, &item.attrs)?;
                 self.bclose(item.span)?;
             }
+            hir::ItemGlobalAsm(ref ga) => {
+                self.head(&visibility_qualified(&item.vis, "global asm"))?;
+                word(&mut self.s, &ga.asm.as_str())?;
+                self.end()?
+            }
             hir::ItemTy(ref ty, ref params) => {
                 self.ibox(indent_unit)?;
                 self.ibox(0)?;
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 9cf8a0693d363..82e03a9fddc35 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -881,6 +881,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Item {
             hir::ItemFn(..)          |
             hir::ItemMod(..)         |
             hir::ItemForeignMod(..)  |
+            hir::ItemGlobalAsm(..)   |
             hir::ItemTy(..)          |
             hir::ItemEnum(..)        |
             hir::ItemStruct(..)      |
@@ -925,6 +926,7 @@ impl_stable_hash_for!(enum hir::Item_ {
     ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
     ItemMod(module),
     ItemForeignMod(foreign_mod),
+    ItemGlobalAsm(global_asm),
     ItemTy(ty, generics),
     ItemEnum(enum_def, generics),
     ItemStruct(variant_data, generics),
@@ -1014,6 +1016,19 @@ impl_stable_hash_for!(struct hir::InlineAsmOutput {
     is_indirect
 });
 
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::GlobalAsm {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::GlobalAsm {
+            asm,
+            ctxt: _
+        } = *self;
+
+        asm.hash_stable(hcx, hasher);
+    }
+}
+
 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::InlineAsm {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a, 'tcx>,
@@ -1070,6 +1085,7 @@ impl_stable_hash_for!(enum hir::def::Def {
     Upvar(def_id, index, expr_id),
     Label(node_id),
     Macro(def_id, macro_kind),
+    GlobalAsm(def_id),
     Err
 });
 
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index e5dd48534a6a1..63455f94cedff 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -267,7 +267,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::ItemMod(..) | hir::ItemForeignMod(..) |
                     hir::ItemImpl(..) | hir::ItemTrait(..) |
                     hir::ItemStruct(..) | hir::ItemEnum(..) |
-                    hir::ItemUnion(..) | hir::ItemDefaultImpl(..) => {}
+                    hir::ItemUnion(..) | hir::ItemDefaultImpl(..) |
+                    hir::ItemGlobalAsm(..) => {}
                 }
             }
             hir_map::NodeTraitItem(trait_method) => {
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 8037570d24a80..b9938a04047c9 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -314,7 +314,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             hir::ItemUse(..) |
             hir::ItemMod(..) |
             hir::ItemDefaultImpl(..) |
-            hir::ItemForeignMod(..) => {
+            hir::ItemForeignMod(..) |
+            hir::ItemGlobalAsm(..) => {
                 // These sorts of items have no lifetime parameters at all.
                 intravisit::walk_item(self, item);
             }
diff --git a/src/librustc_back/target/wasm32_unknown_emscripten.rs b/src/librustc_back/target/wasm32_unknown_emscripten.rs
index a51f59d6ff192..f5fb63038e917 100644
--- a/src/librustc_back/target/wasm32_unknown_emscripten.rs
+++ b/src/librustc_back/target/wasm32_unknown_emscripten.rs
@@ -14,7 +14,7 @@ use super::emscripten_base::{cmd};
 
 pub fn target() -> Result<Target, String> {
     let mut post_link_args = LinkArgs::new();
-    post_link_args.insert(LinkerFlavor::Gcc,
+    post_link_args.insert(LinkerFlavor::Em,
                           vec!["-s".to_string(),
                                "BINARYEN=1".to_string(),
                                "-s".to_string(),
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index af2416f787ea4..44e291a44c777 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -233,6 +233,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
                 hir::ItemStatic(..) |
                 hir::ItemFn(..) |
                 hir::ItemForeignMod(..) |
+                hir::ItemGlobalAsm(..) |
                 hir::ItemTy(..) => None,
 
                 hir::ItemEnum(..) |
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 32c9183ece999..402166cc13fd9 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -507,6 +507,7 @@ extern "C" {
 
     /// See Module::setModuleInlineAsm.
     pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
+    pub fn LLVMRustAppendModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
 
     /// See llvm::LLVMTypeKind::getTypeID.
     pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind;
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index cdbecb3ae2e42..3498be9dfdf32 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -429,6 +429,7 @@ impl<'tcx> EntryKind<'tcx> {
             EntryKind::Trait(_) => Def::Trait(did),
             EntryKind::Enum(..) => Def::Enum(did),
             EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang),
+            EntryKind::GlobalAsm => Def::GlobalAsm(did),
 
             EntryKind::ForeignMod |
             EntryKind::Impl(_) |
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 3bf22f8a6c827..0e204695e8f22 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -677,6 +677,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> EntryBuilder<'a, 'b, 'tcx> {
                 return self.encode_info_for_mod(FromId(item.id, (m, &item.attrs, &item.vis)));
             }
             hir::ItemForeignMod(_) => EntryKind::ForeignMod,
+            hir::ItemGlobalAsm(..) => EntryKind::GlobalAsm,
             hir::ItemTy(..) => EntryKind::Type,
             hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
             hir::ItemStruct(ref struct_def, _) => {
@@ -917,6 +918,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
             hir::ItemFn(..) |
             hir::ItemMod(..) |
             hir::ItemForeignMod(..) |
+            hir::ItemGlobalAsm(..) |
             hir::ItemExternCrate(..) |
             hir::ItemUse(..) |
             hir::ItemDefaultImpl(..) |
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 53d6a9ec10df2..6cd35f1335ed7 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -267,6 +267,7 @@ pub enum EntryKind<'tcx> {
     ForeignImmStatic,
     ForeignMutStatic,
     ForeignMod,
+    GlobalAsm,
     Type,
     Enum(ReprOptions),
     Field,
@@ -297,6 +298,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for EntryKind<'tcx> {
             EntryKind::ForeignImmStatic |
             EntryKind::ForeignMutStatic |
             EntryKind::ForeignMod       |
+            EntryKind::GlobalAsm        |
             EntryKind::Field |
             EntryKind::Type => {
                 // Nothing else to hash here.
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 300848fe8f25e..92f7e48b6be48 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -160,7 +160,10 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
                 self.prev_level
             }
             // Other `pub` items inherit levels from parents
-            _ => {
+            hir::ItemConst(..) | hir::ItemEnum(..) | hir::ItemExternCrate(..) |
+            hir::ItemGlobalAsm(..) | hir::ItemFn(..) | hir::ItemMod(..) |
+            hir::ItemStatic(..) | hir::ItemStruct(..) | hir::ItemTrait(..) |
+            hir::ItemTy(..) | hir::ItemUnion(..) | hir::ItemUse(..) => {
                 if item.vis == hir::Public { self.prev_level } else { None }
             }
         };
@@ -212,7 +215,9 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
                     }
                 }
             }
-            _ => {}
+            hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
+            hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) |
+            hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemDefaultImpl(..) => {}
         }
 
         // Mark all items in interfaces of reachable items as reachable
@@ -225,6 +230,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
             hir::ItemUse(..) => {}
             // The interface is empty
             hir::ItemDefaultImpl(..) => {}
+            // The interface is empty
+            hir::ItemGlobalAsm(..) => {}
             // Visit everything
             hir::ItemConst(..) | hir::ItemStatic(..) |
             hir::ItemFn(..) | hir::ItemTy(..) => {
@@ -1092,6 +1099,8 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
             hir::ItemMod(..) => {}
             // Checked in resolve
             hir::ItemUse(..) => {}
+            // No subitems
+            hir::ItemGlobalAsm(..) => {}
             // Subitems of these items have inherited publicity
             hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
             hir::ItemTy(..) => {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index a15431afc164b..80f853778c744 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -268,6 +268,8 @@ impl<'a> Resolver<'a> {
                 self.define(parent, ident, TypeNS, imported_binding);
             }
 
+            ItemKind::GlobalAsm(..) => {}
+
             ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root
 
             ItemKind::Mod(..) => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c94f63329d1ff..6ba214f20f98d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1709,7 +1709,7 @@ impl<'a> Resolver<'a> {
                 }
             }
 
-            ItemKind::ExternCrate(_) | ItemKind::MacroDef(..) => {
+            ItemKind::ExternCrate(_) | ItemKind::MacroDef(..) | ItemKind::GlobalAsm(_)=> {
                 // do nothing, these are just around to be encoded
             }
 
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 3fd0ce45e3610..3e8f7e11b6b43 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -341,6 +341,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
             Def::AssociatedTy(..) |
             Def::AssociatedConst(..) |
             Def::PrimTy(_) |
+            Def::GlobalAsm(_) |
             Def::Err => {
                span_bug!(span,
                          "process_def_kind for unexpected item: {:?}",
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 44615071a56a7..d822f7bea3a30 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -701,6 +701,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             Def::SelfTy(..) |
             Def::Label(..) |
             Def::Macro(..) |
+            Def::GlobalAsm(..) |
             Def::Err => None,
         }
     }
diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs
index 3e270b7928ebc..92cbd004206e7 100644
--- a/src/librustc_trans/asm.rs
+++ b/src/librustc_trans/asm.rs
@@ -124,3 +124,11 @@ pub fn trans_inline_asm<'a, 'tcx>(
             llvm::LLVMMDNodeInContext(bcx.ccx.llcx(), &val, 1));
     }
 }
+
+pub fn trans_global_asm<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+                                  ga: &hir::GlobalAsm) {
+    let asm = CString::new(ga.asm.as_str().as_bytes()).unwrap();
+    unsafe {
+        llvm::LLVMRustAppendModuleInlineAsm(ccx.llmod(), asm.as_ptr());
+    }
+}
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 500802a4135d0..ba2b807d5a01c 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -349,6 +349,9 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
 
             collect_neighbours(scx, instance, &mut neighbors);
         }
+        TransItem::GlobalAsm(..) => {
+            recursion_depth_reset = None;
+        }
     }
 
     record_inlining_canditates(scx.tcx(), starting_point, &neighbors[..], inlining_map);
@@ -840,6 +843,12 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
                     }
                 }
             }
+            hir::ItemGlobalAsm(..) => {
+                debug!("RootCollector: ItemGlobalAsm({})",
+                       def_id_to_string(self.scx.tcx(),
+                                        self.scx.tcx().hir.local_def_id(item.id)));
+                self.output.push(TransItem::GlobalAsm(item.id));
+            }
             hir::ItemStatic(..) => {
                 debug!("RootCollector: ItemStatic({})",
                        def_id_to_string(self.scx.tcx(),
diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs
index 90ce40cfbcf8f..4973181202eed 100644
--- a/src/librustc_trans/partitioning.rs
+++ b/src/librustc_trans/partitioning.rs
@@ -185,15 +185,16 @@ impl<'tcx> CodegenUnit<'tcx> {
             symbol_name.len().hash(&mut state);
             symbol_name.hash(&mut state);
             let exported = match item {
-               TransItem::Fn(ref instance) => {
-                   let node_id =
-                       scx.tcx().hir.as_local_node_id(instance.def_id());
+                TransItem::Fn(ref instance) => {
+                    let node_id =
+                        scx.tcx().hir.as_local_node_id(instance.def_id());
                     node_id.map(|node_id| exported_symbols.contains(&node_id))
-                           .unwrap_or(false)
-               }
-               TransItem::Static(node_id) => {
+                        .unwrap_or(false)
+                }
+                TransItem::Static(node_id) => {
                     exported_symbols.contains(&node_id)
-               }
+                }
+                TransItem::GlobalAsm(..) => true,
             };
             exported.hash(&mut state);
         }
@@ -243,7 +244,9 @@ impl<'tcx> CodegenUnit<'tcx> {
                 TransItem::Fn(instance) => {
                     tcx.hir.as_local_node_id(instance.def_id())
                 }
-                TransItem::Static(node_id) => Some(node_id),
+                TransItem::Static(node_id) | TransItem::GlobalAsm(node_id) => {
+                    Some(node_id)
+                }
             }
         }
     }
@@ -338,7 +341,8 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
                 None => {
                     match trans_item {
                         TransItem::Fn(..) |
-                        TransItem::Static(..) => llvm::ExternalLinkage,
+                        TransItem::Static(..) |
+                        TransItem::GlobalAsm(..) => llvm::ExternalLinkage,
                     }
                 }
             };
@@ -483,7 +487,8 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't
 
             Some(def_id)
         }
-        TransItem::Static(node_id) => Some(tcx.hir.local_def_id(node_id)),
+        TransItem::Static(node_id) |
+        TransItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)),
     }
 }
 
diff --git a/src/librustc_trans/symbol_map.rs b/src/librustc_trans/symbol_map.rs
index 1b48e131b720a..36c3981e3a6f2 100644
--- a/src/librustc_trans/symbol_map.rs
+++ b/src/librustc_trans/symbol_map.rs
@@ -99,7 +99,10 @@ impl<'tcx> SymbolMap<'tcx> {
                 TransItem::Fn(Instance { def, .. }) => {
                     tcx.hir.as_local_node_id(def.def_id())
                 }
-                TransItem::Static(node_id) => Some(node_id),
+                TransItem::Static(node_id) |
+                TransItem::GlobalAsm(node_id) => {
+                    Some(node_id)
+                }
             }.map(|node_id| {
                 tcx.hir.span(node_id)
             })
diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs
index 410e3f30be731..f5556bb8382f6 100644
--- a/src/librustc_trans/trans_item.rs
+++ b/src/librustc_trans/trans_item.rs
@@ -14,6 +14,7 @@
 //! item-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
+use asm;
 use attributes;
 use base;
 use consts;
@@ -38,7 +39,8 @@ use std::iter;
 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
 pub enum TransItem<'tcx> {
     Fn(Instance<'tcx>),
-    Static(NodeId)
+    Static(NodeId),
+    GlobalAsm(NodeId),
 }
 
 /// Describes how a translation item will be instantiated in object files.
@@ -89,6 +91,14 @@ impl<'a, 'tcx> TransItem<'tcx> {
                     span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
                 }
             }
+            TransItem::GlobalAsm(node_id) => {
+                let item = ccx.tcx().hir.expect_item(node_id);
+                if let hir::ItemGlobalAsm(ref ga) = item.node {
+                    asm::trans_global_asm(ccx, ga);
+                } else {
+                    span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
+                }
+            }
             TransItem::Fn(instance) => {
                 let _task = ccx.tcx().dep_graph.in_task(
                     DepNode::TransCrateItem(instance.def_id())); // (*)
@@ -123,6 +133,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
             TransItem::Fn(instance) => {
                 TransItem::predefine_fn(ccx, instance, linkage, &symbol_name);
             }
+            TransItem::GlobalAsm(..) => {}
         }
 
         debug!("END PREDEFINING '{} ({})' in cgu {}",
@@ -185,6 +196,10 @@ impl<'a, 'tcx> TransItem<'tcx> {
                 let def_id = scx.tcx().hir.local_def_id(node_id);
                 symbol_names::symbol_name(Instance::mono(scx.tcx(), def_id), scx)
             }
+            TransItem::GlobalAsm(node_id) => {
+                let def_id = scx.tcx().hir.local_def_id(node_id);
+                format!("global_asm_{:?}", def_id)
+            }
         }
     }
 
@@ -202,6 +217,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
                 }
             }
             TransItem::Static(..) => InstantiationMode::GloballyShared,
+            TransItem::GlobalAsm(..) => InstantiationMode::GloballyShared,
         }
     }
 
@@ -210,7 +226,8 @@ impl<'a, 'tcx> TransItem<'tcx> {
             TransItem::Fn(ref instance) => {
                 instance.substs.types().next().is_some()
             }
-            TransItem::Static(..)   => false,
+            TransItem::Static(..) |
+            TransItem::GlobalAsm(..) => false,
         }
     }
 
@@ -218,6 +235,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
         let def_id = match *self {
             TransItem::Fn(ref instance) => instance.def_id(),
             TransItem::Static(node_id) => tcx.hir.local_def_id(node_id),
+            TransItem::GlobalAsm(..) => return None,
         };
 
         let attributes = tcx.get_attrs(def_id);
@@ -249,6 +267,9 @@ impl<'a, 'tcx> TransItem<'tcx> {
                 let instance = Instance::new(def_id, tcx.intern_substs(&[]));
                 to_string_internal(tcx, "static ", instance)
             },
+            TransItem::GlobalAsm(..) => {
+                "global_asm".to_string()
+            }
         };
 
         fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -273,6 +294,9 @@ impl<'a, 'tcx> TransItem<'tcx> {
             TransItem::Static(id) => {
                 format!("Static({:?})", id)
             }
+            TransItem::GlobalAsm(id) => {
+                format!("GlobalAsm({:?})", id)
+            }
         }
     }
 }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 77ab076eba386..649353d52f6aa 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -490,8 +490,10 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
     let def_id = tcx.hir.local_def_id(item_id);
     match it.node {
         // These don't define types.
-        hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
-        }
+        hir::ItemExternCrate(_) |
+        hir::ItemUse(..) |
+        hir::ItemMod(_) |
+        hir::ItemGlobalAsm(_) => {}
         hir::ItemForeignMod(ref foreign_mod) => {
             for item in &foreign_mod.items {
                 let def_id = tcx.hir.local_def_id(item.id);
@@ -543,12 +545,12 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
             tcx.item_generics(def_id);
             tcx.item_type(def_id);
             tcx.item_predicates(def_id);
-        },
-        _ => {
+        }
+        hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => {
             tcx.item_generics(def_id);
             tcx.item_type(def_id);
             tcx.item_predicates(def_id);
-        },
+        }
     }
 }
 
@@ -1074,6 +1076,7 @@ fn ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 ItemTrait(..) |
                 ItemMod(..) |
                 ItemForeignMod(..) |
+                ItemGlobalAsm(..) |
                 ItemExternCrate(..) |
                 ItemUse(..) => {
                     span_bug!(
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index f0f543fa6f23b..1bde1eea37c39 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -113,6 +113,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
             hir::ItemFn(..) |
             hir::ItemMod(..) |
             hir::ItemForeignMod(..) |
+            hir::ItemGlobalAsm(..) |
             hir::ItemTy(..) |
             hir::ItemImpl(..) |
             hir::ItemDefaultImpl(..) => {}
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index 36352f50e4406..890414e317c62 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -251,6 +251,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for TermsContext<'a, 'tcx> {
             hir::ItemFn(..) |
             hir::ItemMod(..) |
             hir::ItemForeignMod(..) |
+            hir::ItemGlobalAsm(..) |
             hir::ItemTy(..) => {}
         }
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index fb8ba51853fe8..3d233463bba3a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2285,7 +2285,7 @@ impl Clean<PathParameters> for hir::PathParameters {
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
 pub struct PathSegment {
     pub name: String,
-    pub params: PathParameters
+    pub params: PathParameters,
 }
 
 impl Clean<PathSegment> for hir::PathSegment {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index ffef42bc3d27c..0f47265a1aa66 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -470,10 +470,22 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
 /// rendering function with the necessary arguments for linking to a local path.
 fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
                  print_all: bool, use_absolute: bool, is_not_debug: bool) -> fmt::Result {
-    let last = path.segments.last().unwrap();
-    let rel_root = match &*path.segments[0].name {
-        "self" => Some("./".to_string()),
-        _ => None,
+    let empty = clean::PathSegment {
+                    name: String::new(),
+                    params: clean::PathParameters::Parenthesized {
+                        inputs: Vec::new(),
+                        output: None,
+                    }
+                };
+    let last = path.segments.last()
+                            .unwrap_or(&empty);
+    let rel_root = if path.segments.is_empty() {
+        None
+    } else {
+        match &*path.segments[0].name {
+            "self" => Some("./".to_string()),
+            _ => None,
+        }
     };
 
     if print_all {
@@ -487,10 +499,9 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
                         root.push_str(&seg.name);
                         root.push_str("/");
                         if is_not_debug {
-                            write!(w, "<a class=\"mod\"
-                                           href=\"{}index.html\">{}</a>::",
-                                     root,
-                                     seg.name)?;
+                            write!(w, "<a class=\"mod\" href=\"{}index.html\">{}</a>::",
+                                   root,
+                                   seg.name)?;
                         } else {
                             write!(w, "{}::", seg.name)?;
                         }
@@ -516,7 +527,8 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
                 match href(did) {
                     Some((_, _, fqp)) => format!("{}::{}",
                                                  fqp[..fqp.len()-1].join("::"),
-                                                 HRef::new(did, fqp.last().unwrap())),
+                                                 HRef::new(did, fqp.last()
+                                                                   .unwrap_or(&String::new()))),
                     None => format!("{}", HRef::new(did, &last.name)),
                 }
             } else {
@@ -528,7 +540,8 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
                 match href(did) {
                     Some((_, _, fqp)) => format!("{:?}::{:?}",
                                                  fqp[..fqp.len()-1].join("::"),
-                                                 HRef::new(did, fqp.last().unwrap())),
+                                                 HRef::new(did, fqp.last()
+                                                                   .unwrap_or(&String::new()))),
                     None => format!("{:?}", HRef::new(did, &last.name)),
                 }
             } else {
@@ -801,45 +814,65 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool,
             }
             Ok(())
         }
-        // It's pretty unsightly to look at `<A as B>::C` in output, and
-        // we've got hyperlinking on our side, so try to avoid longer
-        // notation as much as possible by making `C` a hyperlink to trait
-        // `B` to disambiguate.
-        //
-        // FIXME: this is still a lossy conversion and there should probably
-        //        be a better way of representing this in general? Most of
-        //        the ugliness comes from inlining across crates where
-        //        everything comes in as a fully resolved QPath (hard to
-        //        look at).
-        clean::QPath {
-            ref name,
-            ref self_type,
-            trait_: box clean::ResolvedPath { did, ref typarams, .. },
-        } => {
-            if f.alternate() {
-                write!(f, "{:#}::", self_type)?;
-            } else {
-                write!(f, "{}::", self_type)?;
-            }
-            let path = clean::Path::singleton(name.clone());
-            resolved_path(f, did, &path, true, use_absolute, is_not_debug)?;
-
-            // FIXME: `typarams` are not rendered, and this seems bad?
-            drop(typarams);
-            Ok(())
-        }
         clean::QPath { ref name, ref self_type, ref trait_ } => {
+            let should_show_cast = match *trait_ {
+                box clean::ResolvedPath { .. } => {
+                    let path = clean::Path::singleton(name.clone());
+                    !path.segments.is_empty() && &format!("{:#}", trait_) != "()" &&
+                    &format!("{:#}", self_type) != "Self"
+                }
+                _ => true,
+            };
             if f.alternate() {
                 if is_not_debug {
-                    write!(f, "<{:#} as {:#}>::{}", self_type, trait_, name)
+                    if should_show_cast {
+                        write!(f, "<{:#} as {:#}>::", self_type, trait_)?
+                    } else {
+                        write!(f, "{:#}::", self_type)?
+                    }
                 } else {
-                    write!(f, "<{:#?} as {:#?}>::{}", self_type, trait_, name)
+                    if should_show_cast {
+                        write!(f, "<{:#?} as {:#?}>::", self_type, trait_)?
+                    } else {
+                        write!(f, "{:#?}::", self_type)?
+                    }
                 }
             } else {
                 if is_not_debug {
-                    write!(f, "&lt;{} as {}&gt;::{}", self_type, trait_, name)
+                    if should_show_cast {
+                        write!(f, "&lt;{} as {}&gt;::", self_type, trait_)?
+                    } else {
+                        write!(f, "{}::", self_type)?
+                    }
                 } else {
-                    write!(f, "<{:?} as {:?}>::{}", self_type, trait_, name)
+                    if should_show_cast {
+                        write!(f, "<{:?} as {:?}>::", self_type, trait_)?
+                    } else {
+                        write!(f, "{:?}::", self_type)?
+                    }
+                }
+            };
+            match *trait_ {
+                // It's pretty unsightly to look at `<A as B>::C` in output, and
+                // we've got hyperlinking on our side, so try to avoid longer
+                // notation as much as possible by making `C` a hyperlink to trait
+                // `B` to disambiguate.
+                //
+                // FIXME: this is still a lossy conversion and there should probably
+                //        be a better way of representing this in general? Most of
+                //        the ugliness comes from inlining across crates where
+                //        everything comes in as a fully resolved QPath (hard to
+                //        look at).
+                box clean::ResolvedPath { did, ref typarams, .. } => {
+                    let path = clean::Path::singleton(name.clone());
+                    resolved_path(f, did, &path, true, use_absolute, is_not_debug)?;
+
+                    // FIXME: `typarams` are not rendered, and this seems bad?
+                    drop(typarams);
+                    Ok(())
+                }
+                _ => {
+                    write!(f, "{}", name)
                 }
             }
         }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index c89ec5bbe15bd..4252f2981ed61 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -373,6 +373,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             }
             // If we're inlining, skip private items.
             _ if self.inlining && item.vis != hir::Public => {}
+            hir::ItemGlobalAsm(..) => {}
             hir::ItemExternCrate(ref p) => {
                 let cstore = &self.cx.sess().cstore;
                 om.extern_crates.push(ExternCrate {
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 852c98eb2fd52..40a6ffe9505fd 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -13,6 +13,7 @@ use rustc::middle::privacy::{AccessLevels, AccessLevel};
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::ty::Visibility;
+use rustc::util::nodemap::FxHashSet;
 
 use std::cell::RefMut;
 
@@ -29,6 +30,8 @@ pub struct LibEmbargoVisitor<'a, 'b: 'a, 'tcx: 'b> {
     access_levels: RefMut<'a, AccessLevels<DefId>>,
     // Previous accessibility level, None means unreachable
     prev_level: Option<AccessLevel>,
+    // Keeps track of already visited modules, in case a module re-exports its parent
+    visited_mods: FxHashSet<DefId>,
 }
 
 impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
@@ -38,6 +41,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
             cstore: &*cx.sess().cstore,
             access_levels: cx.access_levels.borrow_mut(),
             prev_level: Some(AccessLevel::Public),
+            visited_mods: FxHashSet()
         }
     }
 
@@ -62,6 +66,10 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
     }
 
     pub fn visit_mod(&mut self, def_id: DefId) {
+        if !self.visited_mods.insert(def_id) {
+            return;
+        }
+
         for item in self.cstore.item_children(def_id) {
             self.visit_item(item.def);
         }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index c6a3e8a2dedc4..131adfe47afda 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1585,6 +1585,15 @@ pub struct ForeignMod {
     pub items: Vec<ForeignItem>,
 }
 
+/// Global inline assembly
+///
+/// aka module-level assembly or file-scoped assembly
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+pub struct GlobalAsm {
+    pub asm: Symbol,
+    pub ctxt: SyntaxContext,
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct EnumDef {
     pub variants: Vec<Variant>,
@@ -1812,6 +1821,8 @@ pub enum ItemKind {
     ///
     /// E.g. `extern {}` or `extern "C" {}`
     ForeignMod(ForeignMod),
+    /// Module-level inline assembly (from `global_asm!()`)
+    GlobalAsm(P<GlobalAsm>),
     /// A type alias (`type` or `pub type`).
     ///
     /// E.g. `type Foo = Bar<u8>;`
@@ -1864,6 +1875,7 @@ impl ItemKind {
             ItemKind::Fn(..) => "function",
             ItemKind::Mod(..) => "module",
             ItemKind::ForeignMod(..) => "foreign module",
+            ItemKind::GlobalAsm(..) => "global asm",
             ItemKind::Ty(..) => "type alias",
             ItemKind::Enum(..) => "enum",
             ItemKind::Struct(..) => "struct",
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 1b3352f73ade7..48bfc050223ab 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1039,6 +1039,7 @@ impl<'feat> ExpansionConfig<'feat> {
     feature_tests! {
         fn enable_quotes = quote,
         fn enable_asm = asm,
+        fn enable_global_asm = global_asm,
         fn enable_log_syntax = log_syntax,
         fn enable_concat_idents = concat_idents,
         fn enable_trace_macros = trace_macros,
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 08762ccf04bde..8b62416dcbdbd 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -346,6 +346,9 @@ declare_features! (
 
     // Hack to document `-Z linker-flavor` in The Unstable Book
     (active, linker_flavor, "1.18.0", Some(41142)),
+
+    // Allows module-level inline assembly by way of global_asm!()
+    (active, global_asm, "1.18.0", Some(35119)),
 );
 
 declare_features! (
@@ -982,6 +985,9 @@ pub const EXPLAIN_STMT_ATTR_SYNTAX: &'static str =
 pub const EXPLAIN_ASM: &'static str =
     "inline assembly is not stable enough for use and is subject to change";
 
+pub const EXPLAIN_GLOBAL_ASM: &'static str =
+    "`global_asm!` is not stable enough for use and is subject to change";
+
 pub const EXPLAIN_LOG_SYNTAX: &'static str =
     "`log_syntax!` is not stable enough for use and is subject to change";
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 92e25b00e0ac1..a6ab8e10d9f91 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -140,6 +140,10 @@ pub trait Folder : Sized {
         noop_fold_foreign_mod(nm, self)
     }
 
+    fn fold_global_asm(&mut self, ga: P<GlobalAsm>) -> P<GlobalAsm> {
+        noop_fold_global_asm(ga, self)
+    }
+
     fn fold_variant(&mut self, v: Variant) -> Variant {
         noop_fold_variant(v, self)
     }
@@ -412,6 +416,11 @@ pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
     }
 }
 
+pub fn noop_fold_global_asm<T: Folder>(ga: P<GlobalAsm>,
+                                       _: &mut T) -> P<GlobalAsm> {
+    ga
+}
+
 pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant {
     Spanned {
         node: Variant_ {
@@ -867,6 +876,7 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
         }
         ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)),
         ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)),
+        ItemKind::GlobalAsm(ga) => ItemKind::GlobalAsm(folder.fold_global_asm(ga)),
         ItemKind::Ty(t, generics) => {
             ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics))
         }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index e7feff2b79fce..433ba3d3693f1 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1267,6 +1267,11 @@ impl<'a> State<'a> {
                 self.print_foreign_mod(nmod, &item.attrs)?;
                 self.bclose(item.span)?;
             }
+            ast::ItemKind::GlobalAsm(ref ga) => {
+                self.head(&visibility_qualified(&item.vis, "global_asm!"))?;
+                word(&mut self.s, &ga.asm.as_str())?;
+                self.end()?;
+            }
             ast::ItemKind::Ty(ref ty, ref params) => {
                 self.ibox(INDENT_UNIT)?;
                 self.ibox(0)?;
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index b5e9a1892acc9..bae1c56db007c 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -58,6 +58,7 @@ pub trait Visitor<'ast>: Sized {
     }
     fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
     fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { walk_foreign_item(self, i) }
+    fn visit_global_asm(&mut self, ga: &'ast GlobalAsm) { walk_global_asm(self, ga) }
     fn visit_item(&mut self, i: &'ast Item) { walk_item(self, i) }
     fn visit_local(&mut self, l: &'ast Local) { walk_local(self, l) }
     fn visit_block(&mut self, b: &'ast Block) { walk_block(self, b) }
@@ -253,6 +254,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
         ItemKind::ForeignMod(ref foreign_module) => {
             walk_list!(visitor, visit_foreign_item, &foreign_module.items);
         }
+        ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga),
         ItemKind::Ty(ref typ, ref type_parameters) => {
             visitor.visit_ty(typ);
             visitor.visit_generics(type_parameters)
@@ -464,6 +466,10 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, foreign_item: &'a
     walk_list!(visitor, visit_attribute, &foreign_item.attrs);
 }
 
+pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) {
+    // Empty!
+}
+
 pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyParamBound) {
     match *bound {
         TraitTyParamBound(ref typ, ref modifier) => {
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
new file mode 100644
index 0000000000000..dc67e1c45f6e7
--- /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 1e9b112b6df56..e35e79df58520 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -38,6 +38,7 @@ mod concat_idents;
 mod env;
 mod format;
 mod format_foreign;
+mod global_asm;
 mod log_syntax;
 mod trace_macros;
 
@@ -99,6 +100,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/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 5ab786f40b933..c24867224ea86 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -312,6 +312,10 @@ extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString,
                              HasSideEffects, IsAlignStack, fromRust(Dialect)));
 }
 
+extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
+  unwrap(M)->appendModuleInlineAsm(StringRef(Asm));
+}
+
 typedef DIBuilder *LLVMRustDIBuilderRef;
 
 typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
diff --git a/src/test/codegen/foo.s b/src/test/codegen/foo.s
new file mode 100644
index 0000000000000..304d82aa0c653
--- /dev/null
+++ b/src/test/codegen/foo.s
@@ -0,0 +1,3 @@
+.global foo
+foo:
+    jmp baz
diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs
new file mode 100644
index 0000000000000..5bd0c1b4076ee
--- /dev/null
+++ b/src/test/codegen/global_asm.rs
@@ -0,0 +1,73 @@
+// Copyright 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.
+
+// ignore-aarch64
+// ignore-aarch64_be
+// ignore-arm
+// ignore-armeb
+// ignore-avr
+// ignore-bpfel
+// ignore-bpfeb
+// ignore-hexagon
+// ignore-mips
+// ignore-mipsel
+// ignore-mips64
+// ignore-mips64el
+// ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
+// ignore-powerpc
+// ignore-r600
+// ignore-amdgcn
+// ignore-sparc
+// ignore-sparcv9
+// ignore-sparcel
+// ignore-s390x
+// ignore-tce
+// ignore-thumb
+// ignore-thumbeb
+// ignore-xcore
+// ignore-nvptx
+// ignore-nvptx64
+// ignore-le32
+// ignore-le64
+// ignore-amdil
+// ignore-amdil64
+// ignore-hsail
+// ignore-hsail64
+// ignore-spir
+// ignore-spir64
+// ignore-kalimba
+// ignore-shave
+// ignore-wasm32
+// ignore-wasm64
+// ignore-emscripten
+// compile-flags: -C no-prepopulate-passes
+
+#![feature(global_asm)]
+#![crate_type = "lib"]
+
+// CHECK-LABEL: foo
+// CHECK: module asm
+// this regex will capture the correct unconditional branch inst.
+// CHECK: module asm "{{[[:space:]]+}}jmp baz"
+global_asm!(r#"
+    .global foo
+foo:
+    jmp baz
+"#);
+
+extern "C" {
+    fn foo();
+}
+
+// CHECK-LABEL: @baz
+#[no_mangle]
+pub unsafe extern "C" fn baz() {}
diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs
new file mode 100644
index 0000000000000..401b1fad566d5
--- /dev/null
+++ b/src/test/codegen/global_asm_include.rs
@@ -0,0 +1,68 @@
+// Copyright 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.
+
+// ignore-aarch64
+// ignore-aarch64_be
+// ignore-arm
+// ignore-armeb
+// ignore-avr
+// ignore-bpfel
+// ignore-bpfeb
+// ignore-hexagon
+// ignore-mips
+// ignore-mipsel
+// ignore-mips64
+// ignore-mips64el
+// ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
+// ignore-powerpc
+// ignore-r600
+// ignore-amdgcn
+// ignore-sparc
+// ignore-sparcv9
+// ignore-sparcel
+// ignore-s390x
+// ignore-tce
+// ignore-thumb
+// ignore-thumbeb
+// ignore-xcore
+// ignore-nvptx
+// ignore-nvptx64
+// ignore-le32
+// ignore-le64
+// ignore-amdil
+// ignore-amdil64
+// ignore-hsail
+// ignore-hsail64
+// ignore-spir
+// ignore-spir64
+// ignore-kalimba
+// ignore-shave
+// ignore-wasm32
+// ignore-wasm64
+// ignore-emscripten
+// compile-flags: -C no-prepopulate-passes
+
+#![feature(global_asm)]
+#![crate_type = "lib"]
+
+// CHECK-LABEL: foo
+// CHECK: module asm
+// CHECK: module asm "{{[[:space:]]+}}jmp baz"
+global_asm!(include_str!("foo.s"));
+
+extern "C" {
+    fn foo();
+}
+
+// CHECK-LABEL: @baz
+#[no_mangle]
+pub unsafe extern "C" fn baz() {}
diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs
new file mode 100644
index 0000000000000..8b59165e9e61b
--- /dev/null
+++ b/src/test/codegen/global_asm_x2.rs
@@ -0,0 +1,90 @@
+// Copyright 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.
+
+// ignore-aarch64
+// ignore-aarch64_be
+// ignore-arm
+// ignore-armeb
+// ignore-avr
+// ignore-bpfel
+// ignore-bpfeb
+// ignore-hexagon
+// ignore-mips
+// ignore-mipsel
+// ignore-mips64
+// ignore-mips64el
+// ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
+// ignore-powerpc
+// ignore-r600
+// ignore-amdgcn
+// ignore-sparc
+// ignore-sparcv9
+// ignore-sparcel
+// ignore-s390x
+// ignore-tce
+// ignore-thumb
+// ignore-thumbeb
+// ignore-xcore
+// ignore-nvptx
+// ignore-nvptx64
+// ignore-le32
+// ignore-le64
+// ignore-amdil
+// ignore-amdil64
+// ignore-hsail
+// ignore-hsail64
+// ignore-spir
+// ignore-spir64
+// ignore-kalimba
+// ignore-shave
+// ignore-wasm32
+// ignore-wasm64
+// ignore-emscripten
+// compile-flags: -C no-prepopulate-passes
+
+#![feature(global_asm)]
+#![crate_type = "lib"]
+#[no_std]
+
+// CHECK-LABEL: foo
+// CHECK: module asm
+// CHECK: module asm "{{[[:space:]]+}}jmp baz"
+// any other global_asm will be appended to this first block, so:
+// CHECK-LABEL: bar
+// CHECK: module asm "{{[[:space:]]+}}jmp quux"
+global_asm!(r#"
+    .global foo
+foo:
+    jmp baz
+"#);
+
+extern "C" {
+    fn foo();
+}
+
+// CHECK-LABEL: @baz
+#[no_mangle]
+pub unsafe extern "C" fn baz() {}
+
+// no checks here; this has been appended to the first occurrence
+global_asm!(r#"
+    .global bar
+bar:
+    jmp quux
+"#);
+
+extern "C" {
+    fn bar();
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn quux() {}
diff --git a/src/test/compile-fail/feature-gate-global_asm.rs b/src/test/compile-fail/feature-gate-global_asm.rs
new file mode 100644
index 0000000000000..0560abb6af498
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-global_asm.rs
@@ -0,0 +1,15 @@
+// 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.
+
+// gate-test-global_asm
+
+global_asm!(""); //~ ERROR `global_asm!` is not stable
+
+fn main() {}
diff --git a/src/test/run-pass/empty_global_asm.rs b/src/test/run-pass/empty_global_asm.rs
new file mode 100644
index 0000000000000..db73da2747f9c
--- /dev/null
+++ b/src/test/run-pass/empty_global_asm.rs
@@ -0,0 +1,28 @@
+// Copyright 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.
+
+#![feature(global_asm)]
+
+#[cfg(target_arch = "x86")]
+global_asm!("");
+
+#[cfg(target_arch = "x86_64")]
+global_asm!("");
+
+#[cfg(target_arch = "arm")]
+global_asm!("");
+
+#[cfg(target_arch = "aarch64")]
+global_asm!("");
+
+#[cfg(target_arch = "mips")]
+global_asm!("");
+
+fn main() {}
diff --git a/src/test/run-pass/simple_global_asm.rs b/src/test/run-pass/simple_global_asm.rs
new file mode 100644
index 0000000000000..cd8273c6bc2b8
--- /dev/null
+++ b/src/test/run-pass/simple_global_asm.rs
@@ -0,0 +1,31 @@
+// Copyright 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.
+
+#![feature(global_asm)]
+#![feature(naked_functions)]
+
+#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
+global_asm!(r#"
+    .global foo
+    .global _foo
+foo:
+_foo:
+    ret
+"#);
+
+extern {
+    fn foo();
+}
+
+#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
+fn main() { unsafe { foo(); } }
+
+#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
+fn main() {}
diff --git a/src/test/rustdoc/assoc-item-cast.rs b/src/test/rustdoc/assoc-item-cast.rs
new file mode 100644
index 0000000000000..24f31b5b1040b
--- /dev/null
+++ b/src/test/rustdoc/assoc-item-cast.rs
@@ -0,0 +1,26 @@
+// Copyright 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.
+
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+pub trait Expression {
+    type SqlType;
+}
+
+pub trait AsExpression<T> {
+    type Expression: Expression<SqlType = T>;
+    fn as_expression(self) -> Self::Expression;
+}
+
+// @has foo/type.AsExprOf.html
+// @has - '//*[@class="rust typedef"]' 'type AsExprOf<Item, Type> = <Item as AsExpression<Type>>::Expression;'
+pub type AsExprOf<Item, Type> = <Item as AsExpression<Type>>::Expression;
diff --git a/src/test/rustdoc/auxiliary/issue-40936.rs b/src/test/rustdoc/auxiliary/issue-40936.rs
new file mode 100644
index 0000000000000..54cc18cca23ac
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/issue-40936.rs
@@ -0,0 +1,15 @@
+// Copyright 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.
+
+pub mod outermod {
+    pub mod innermod {
+        pub use super::*;
+    }
+}
diff --git a/src/test/rustdoc/issue-40936.rs b/src/test/rustdoc/issue-40936.rs
new file mode 100644
index 0000000000000..3e02eec1b9c30
--- /dev/null
+++ b/src/test/rustdoc/issue-40936.rs
@@ -0,0 +1,16 @@
+// Copyright 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.
+
+// aux-build:issue-40936.rs
+// build-aux-docs
+
+#![crate_name = "foo"]
+
+extern crate issue_40936;