about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-29 00:12:12 +0000
committerbors <bors@rust-lang.org>2019-07-29 00:12:12 +0000
commit8b94e9e9188b65df38a5f1ae723617dc2dfb3155 (patch)
tree365c90767ab79c5839c267ea78dd834bfeb81dd1
parentc7312fe4ff85ada30103cea58db25d83e0bec4b0 (diff)
parentf8321d0d97495212f8247fcd620398721638ba0c (diff)
downloadrust-8b94e9e9188b65df38a5f1ae723617dc2dfb3155.tar.gz
rust-8b94e9e9188b65df38a5f1ae723617dc2dfb3155.zip
Auto merge of #63094 - Centril:rollup-lm7peuh, r=Centril
Rollup of 6 pull requests

Successful merges:

 - #62809 (rustc: Update wasm32 support for LLVM 9)
 - #63055 (Various cleanups to save analysis)
 - #63076 (Miri: fix determining size of an "extra function" allocation)
 - #63077 (cleanup: Remove some language features related to built-in macros)
 - #63086 (Ignore test cases that are not supported by vxWorks)
 - #63092 (Update `impl Trait` gate issues)

Failed merges:

r? @ghost
-rw-r--r--src/doc/unstable-book/src/library-features/asm.md (renamed from src/doc/unstable-book/src/language-features/asm.md)0
-rw-r--r--src/doc/unstable-book/src/library-features/concat-idents.md (renamed from src/doc/unstable-book/src/language-features/concat-idents.md)0
-rw-r--r--src/doc/unstable-book/src/library-features/global-asm.md (renamed from src/doc/unstable-book/src/language-features/global-asm.md)0
-rw-r--r--src/doc/unstable-book/src/library-features/trace-macros.md (renamed from src/doc/unstable-book/src/language-features/trace-macros.md)0
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs22
-rw-r--r--src/librustc_codegen_ssa/back/link.rs8
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs47
-rw-r--r--src/librustc_codegen_ssa/back/mod.rs1
-rw-r--r--src/librustc_codegen_ssa/back/wasm.rs191
-rw-r--r--src/librustc_mir/interpret/machine.rs10
-rw-r--r--src/librustc_mir/interpret/memory.rs82
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs41
-rw-r--r--src/librustc_save_analysis/dumper.rs4
-rw-r--r--src/librustc_save_analysis/lib.rs68
-rw-r--r--src/librustc_target/spec/wasm32_base.rs8
-rw-r--r--src/libstd/Cargo.toml5
-rw-r--r--src/libstd/sys/wasi/mod.rs2
-rw-r--r--src/libstd/sys/wasm/fast_thread_local.rs9
-rw-r--r--src/libstd/sys/wasm/mod.rs5
-rw-r--r--src/libstd/sys/wasm/thread.rs76
-rw-r--r--src/libstd/sys/wasm/thread_local.rs32
-rw-r--r--src/libstd/sys/wasm/thread_local_atomics.rs61
-rw-r--r--src/libsyntax/feature_gate.rs22
m---------src/llvm-project0
-rw-r--r--src/test/ui/core-run-destroy.rs1
-rw-r--r--src/test/ui/existential-type/issue-60371.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-asm2.rs1
-rw-r--r--src/test/ui/feature-gates/feature-gate-asm2.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-concat_idents2.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-concat_idents2.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-concat_idents3.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-concat_idents3.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-existential-type.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-log_syntax2.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-log_syntax2.stderr2
-rw-r--r--src/test/ui/process/process-sigpipe.rs1
-rw-r--r--src/test/ui/wait-forked-but-failed-child.rs1
-rw-r--r--src/test/ui/x86stdcall.rs1
38 files changed, 239 insertions, 484 deletions
diff --git a/src/doc/unstable-book/src/language-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md
index 2a1b6397781..2a1b6397781 100644
--- a/src/doc/unstable-book/src/language-features/asm.md
+++ b/src/doc/unstable-book/src/library-features/asm.md
diff --git a/src/doc/unstable-book/src/language-features/concat-idents.md b/src/doc/unstable-book/src/library-features/concat-idents.md
index ecfd34a22e5..ecfd34a22e5 100644
--- a/src/doc/unstable-book/src/language-features/concat-idents.md
+++ b/src/doc/unstable-book/src/library-features/concat-idents.md
diff --git a/src/doc/unstable-book/src/language-features/global-asm.md b/src/doc/unstable-book/src/library-features/global-asm.md
index bc55fe80fa6..bc55fe80fa6 100644
--- a/src/doc/unstable-book/src/language-features/global-asm.md
+++ b/src/doc/unstable-book/src/library-features/global-asm.md
diff --git a/src/doc/unstable-book/src/language-features/trace-macros.md b/src/doc/unstable-book/src/library-features/trace-macros.md
index 41aa286e69b..41aa286e69b 100644
--- a/src/doc/unstable-book/src/language-features/trace-macros.md
+++ b/src/doc/unstable-book/src/library-features/trace-macros.md
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index fbeda43af42..f0bdb0018ef 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -913,9 +913,12 @@ pub fn compile_unit_metadata(
     }
 
     debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
+    let rustc_producer = format!(
+        "rustc version {}",
+        option_env!("CFG_VERSION").expect("CFG_VERSION"),
+    );
     // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
-    let producer = format!("clang LLVM (rustc version {})",
-                           (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
+    let producer = format!("clang LLVM ({})", rustc_producer);
 
     let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
     let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
@@ -980,6 +983,21 @@ pub fn compile_unit_metadata(
                                               gcov_metadata);
         }
 
+        // Insert `llvm.ident` metadata on the wasm32 targets since that will
+        // get hooked up to the "producer" sections `processed-by` information.
+        if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
+            let name_metadata = llvm::LLVMMDStringInContext(
+                debug_context.llcontext,
+                rustc_producer.as_ptr() as *const _,
+                rustc_producer.as_bytes().len() as c_uint,
+            );
+            llvm::LLVMAddNamedMetadataOperand(
+                debug_context.llmod,
+                const_cstr!("llvm.ident").as_ptr(),
+                llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
+            );
+        }
+
         return unit_metadata;
     };
 
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 707b7cae16c..3f6a1a72ea6 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -678,14 +678,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
             sess.fatal(&format!("failed to run dsymutil: {}", e))
         }
     }
-
-    if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" {
-        super::wasm::add_producer_section(
-            &out_filename,
-            &sess.edition().to_string(),
-            option_env!("CFG_VERSION").unwrap_or("unknown"),
-        );
-    }
 }
 
 /// Returns a boolean indicating whether the specified crate should be ignored
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index cb8870d0be9..26091005f25 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -901,7 +901,45 @@ pub struct WasmLd<'a> {
 }
 
 impl<'a> WasmLd<'a> {
-    fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
+    fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
+        // If the atomics feature is enabled for wasm then we need a whole bunch
+        // of flags:
+        //
+        // * `--shared-memory` - the link won't even succeed without this, flags
+        //   the one linear memory as `shared`
+        //
+        // * `--max-memory=1G` - when specifying a shared memory this must also
+        //   be specified. We conservatively choose 1GB but users should be able
+        //   to override this with `-C link-arg`.
+        //
+        // * `--import-memory` - it doesn't make much sense for memory to be
+        //   exported in a threaded module because typically you're
+        //   sharing memory and instantiating the module multiple times. As a
+        //   result if it were exported then we'd just have no sharing.
+        //
+        // * `--passive-segments` - all memory segments should be passive to
+        //   prevent each module instantiation from reinitializing memory.
+        //
+        // * `--export=__wasm_init_memory` - when using `--passive-segments` the
+        //   linker will synthesize this function, and so we need to make sure
+        //   that our usage of `--export` below won't accidentally cause this
+        //   function to get deleted.
+        //
+        // * `--export=*tls*` - when `#[thread_local]` symbols are used these
+        //   symbols are how the TLS segments are initialized and configured.
+        let atomics = sess.opts.cg.target_feature.contains("+atomics") ||
+            sess.target.target.options.features.contains("+atomics");
+        if atomics {
+            cmd.arg("--shared-memory");
+            cmd.arg("--max-memory=1073741824");
+            cmd.arg("--import-memory");
+            cmd.arg("--passive-segments");
+            cmd.arg("--export=__wasm_init_memory");
+            cmd.arg("--export=__wasm_init_tls");
+            cmd.arg("--export=__tls_size");
+            cmd.arg("--export=__tls_align");
+            cmd.arg("--export=__tls_base");
+        }
         WasmLd { cmd, sess, info }
     }
 }
@@ -1004,6 +1042,13 @@ impl<'a> Linker for WasmLd<'a> {
         for sym in self.info.exports[&crate_type].iter() {
             self.cmd.arg("--export").arg(&sym);
         }
+
+        // LLD will hide these otherwise-internal symbols since our `--export`
+        // list above is a whitelist of what to export. Various bits and pieces
+        // of tooling use this, so be sure these symbols make their way out of
+        // the linker as well.
+        self.cmd.arg("--export=__heap_base");
+        self.cmd.arg("--export=__data_end");
     }
 
     fn subsystem(&mut self, _subsystem: &str) {
diff --git a/src/librustc_codegen_ssa/back/mod.rs b/src/librustc_codegen_ssa/back/mod.rs
index a16d099ee3e..901891d85a4 100644
--- a/src/librustc_codegen_ssa/back/mod.rs
+++ b/src/librustc_codegen_ssa/back/mod.rs
@@ -6,4 +6,3 @@ pub mod command;
 pub mod symbol_export;
 pub mod archive;
 pub mod rpath;
-pub mod wasm;
diff --git a/src/librustc_codegen_ssa/back/wasm.rs b/src/librustc_codegen_ssa/back/wasm.rs
deleted file mode 100644
index 2a9e81a788e..00000000000
--- a/src/librustc_codegen_ssa/back/wasm.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-use std::fs;
-use std::path::Path;
-use std::str;
-
-use rustc_serialize::leb128;
-
-// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec
-const WASM_CUSTOM_SECTION_ID: u8 = 0;
-
-/// Adds or augment the existing `producers` section to encode information about
-/// the Rust compiler used to produce the wasm file.
-pub fn add_producer_section(
-    path: &Path,
-    rust_version: &str,
-    rustc_version: &str,
-) {
-    struct Field<'a> {
-        name: &'a str,
-        values: Vec<FieldValue<'a>>,
-    }
-
-    #[derive(Copy, Clone)]
-    struct FieldValue<'a> {
-        name: &'a str,
-        version: &'a str,
-    }
-
-    let wasm = fs::read(path).expect("failed to read wasm output");
-    let mut ret = WasmEncoder::new();
-    ret.data.extend(&wasm[..8]);
-
-    // skip the 8 byte wasm/version header
-    let rustc_value = FieldValue {
-        name: "rustc",
-        version: rustc_version,
-    };
-    let rust_value = FieldValue {
-        name: "Rust",
-        version: rust_version,
-    };
-    let mut fields = Vec::new();
-    let mut wrote_rustc = false;
-    let mut wrote_rust = false;
-
-    // Move all sections from the original wasm file to our output, skipping
-    // everything except the producers section
-    for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) {
-        if id != WASM_CUSTOM_SECTION_ID {
-            ret.byte(id);
-            ret.bytes(raw);
-            continue
-        }
-        let mut decoder = WasmDecoder::new(raw);
-        if decoder.str() != "producers" {
-            ret.byte(id);
-            ret.bytes(raw);
-            continue
-        }
-
-        // Read off the producers section into our fields outside the loop,
-        // we'll re-encode the producers section when we're done (to handle an
-        // entirely missing producers section as well).
-        info!("rewriting existing producers section");
-
-        for _ in 0..decoder.u32() {
-            let name = decoder.str();
-            let mut values = Vec::new();
-            for _ in 0..decoder.u32() {
-                let name = decoder.str();
-                let version = decoder.str();
-                values.push(FieldValue { name, version });
-            }
-
-            if name == "language" {
-                values.push(rust_value);
-                wrote_rust = true;
-            } else if name == "processed-by" {
-                values.push(rustc_value);
-                wrote_rustc = true;
-            }
-            fields.push(Field { name, values });
-        }
-    }
-
-    if !wrote_rust {
-        fields.push(Field {
-            name: "language",
-            values: vec![rust_value],
-        });
-    }
-    if !wrote_rustc {
-        fields.push(Field {
-            name: "processed-by",
-            values: vec![rustc_value],
-        });
-    }
-
-    // Append the producers section to the end of the wasm file.
-    let mut section = WasmEncoder::new();
-    section.str("producers");
-    section.u32(fields.len() as u32);
-    for field in fields {
-        section.str(field.name);
-        section.u32(field.values.len() as u32);
-        for value in field.values {
-            section.str(value.name);
-            section.str(value.version);
-        }
-    }
-    ret.byte(WASM_CUSTOM_SECTION_ID);
-    ret.bytes(&section.data);
-
-    fs::write(path, &ret.data).expect("failed to write wasm output");
-}
-
-struct WasmSections<'a>(WasmDecoder<'a>);
-
-impl<'a> Iterator for WasmSections<'a> {
-    type Item = (u8, &'a [u8]);
-
-    fn next(&mut self) -> Option<(u8, &'a [u8])> {
-        if self.0.data.is_empty() {
-            return None
-        }
-
-        // see https://webassembly.github.io/spec/core/binary/modules.html#sections
-        let id = self.0.byte();
-        let section_len = self.0.u32();
-        info!("new section {} / {} bytes", id, section_len);
-        let section = self.0.skip(section_len as usize);
-        Some((id, section))
-    }
-}
-
-struct WasmDecoder<'a> {
-    data: &'a [u8],
-}
-
-impl<'a> WasmDecoder<'a> {
-    fn new(data: &'a [u8]) -> WasmDecoder<'a> {
-        WasmDecoder { data }
-    }
-
-    fn byte(&mut self) -> u8 {
-        self.skip(1)[0]
-    }
-
-    fn u32(&mut self) -> u32 {
-        let (n, l1) = leb128::read_u32_leb128(self.data);
-        self.data = &self.data[l1..];
-        return n
-    }
-
-    fn skip(&mut self, amt: usize) -> &'a [u8] {
-        let (data, rest) = self.data.split_at(amt);
-        self.data = rest;
-        data
-    }
-
-    fn str(&mut self) -> &'a str {
-        let len = self.u32();
-        str::from_utf8(self.skip(len as usize)).unwrap()
-    }
-}
-
-struct WasmEncoder {
-    data: Vec<u8>,
-}
-
-impl WasmEncoder {
-    fn new() -> WasmEncoder {
-        WasmEncoder { data: Vec::new() }
-    }
-
-    fn u32(&mut self, val: u32) {
-        leb128::write_u32_leb128(&mut self.data, val);
-    }
-
-    fn byte(&mut self, val: u8) {
-        self.data.push(val);
-    }
-
-    fn bytes(&mut self, val: &[u8]) {
-        self.u32(val.len() as u32);
-        self.data.extend_from_slice(val);
-    }
-
-    fn str(&mut self, val: &str) {
-        self.bytes(val.as_bytes())
-    }
-}
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index f37c474fa4f..e3f16a3c9ea 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -54,6 +54,16 @@ pub trait AllocMap<K: Hash + Eq, V> {
         k: K,
         vacant: impl FnOnce() -> Result<V, E>
     ) -> Result<&mut V, E>;
+
+    /// Read-only lookup.
+    fn get(&self, k: K) -> Option<&V> {
+        self.get_or(k, || Err(())).ok()
+    }
+
+    /// Mutable lookup.
+    fn get_mut(&mut self, k: K) -> Option<&mut V> {
+        self.get_mut_or(k, || Err(())).ok()
+    }
 }
 
 /// Methods of this trait signifies a point where CTFE evaluation would fail
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 4575784ac37..87dd7738410 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -535,48 +535,52 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         id: AllocId,
         liveness: AllocCheck,
     ) -> InterpResult<'static, (Size, Align)> {
+        // # Regular allocations
         // Don't use `self.get` here as that will
         // a) cause cycles in case `id` refers to a static
         // b) duplicate a static's allocation in miri
-        match self.alloc_map.get_or(id, || Err(())) {
-            Ok((_, alloc)) => Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
-            Err(()) => {
-                // Not a local allocation, check the global `tcx.alloc_map`.
-
-                // Can't do this in the match argument, we may get cycle errors since the lock would
-                // be held throughout the match.
-                let alloc = self.tcx.alloc_map.lock().get(id);
-                match alloc {
-                    Some(GlobalAlloc::Static(did)) => {
-                        // Use size and align of the type.
-                        let ty = self.tcx.type_of(did);
-                        let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
-                        Ok((layout.size, layout.align.abi))
-                    },
-                    Some(GlobalAlloc::Memory(alloc)) =>
-                        // Need to duplicate the logic here, because the global allocations have
-                        // different associated types than the interpreter-local ones.
-                        Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
-                    Some(GlobalAlloc::Function(_)) => {
-                        if let AllocCheck::Dereferencable = liveness {
-                            // The caller requested no function pointers.
-                            err!(DerefFunctionPointer)
-                        } else {
-                            Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
-                        }
-                    },
-                    // The rest must be dead.
-                    None => if let AllocCheck::MaybeDead = liveness {
-                        // Deallocated pointers are allowed, we should be able to find
-                        // them in the map.
-                        Ok(*self.dead_alloc_map.get(&id)
-                            .expect("deallocated pointers should all be recorded in \
-                                    `dead_alloc_map`"))
-                    } else {
-                        err!(DanglingPointerDeref)
-                    },
-                }
-            }
+        if let Some((_, alloc)) = self.alloc_map.get(id) {
+            return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
+        }
+
+        // # Function pointers
+        // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
+        if let Ok(_) = self.get_fn_alloc(id) {
+            return if let AllocCheck::Dereferencable = liveness {
+                // The caller requested no function pointers.
+                err!(DerefFunctionPointer)
+            } else {
+                Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
+            };
+        }
+
+        // # Statics
+        // Can't do this in the match argument, we may get cycle errors since the lock would
+        // be held throughout the match.
+        let alloc = self.tcx.alloc_map.lock().get(id);
+        match alloc {
+            Some(GlobalAlloc::Static(did)) => {
+                // Use size and align of the type.
+                let ty = self.tcx.type_of(did);
+                let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
+                Ok((layout.size, layout.align.abi))
+            },
+            Some(GlobalAlloc::Memory(alloc)) =>
+                // Need to duplicate the logic here, because the global allocations have
+                // different associated types than the interpreter-local ones.
+                Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
+            Some(GlobalAlloc::Function(_)) =>
+                bug!("We already checked function pointers above"),
+            // The rest must be dead.
+            None => if let AllocCheck::MaybeDead = liveness {
+                // Deallocated pointers are allowed, we should be able to find
+                // them in the map.
+                Ok(*self.dead_alloc_map.get(&id)
+                    .expect("deallocated pointers should all be recorded in \
+                            `dead_alloc_map`"))
+            } else {
+                err!(DanglingPointerDeref)
+            },
         }
     }
 
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 2b349613dc5..6fce7ca1f33 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -23,7 +23,7 @@ use rustc_data_structures::fx::FxHashSet;
 use std::path::Path;
 use std::env;
 
-use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID};
+use syntax::ast::{self, Attribute, NodeId, PatKind};
 use syntax::parse::token;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{
@@ -75,15 +75,13 @@ macro_rules! access_from_vis {
     };
 }
 
-pub struct DumpVisitor<'l, 'tcx, 'll> {
-    save_ctxt: SaveContext<'l, 'tcx>,
+pub struct DumpVisitor<'l, 'tcx> {
+    pub save_ctxt: SaveContext<'l, 'tcx>,
     tcx: TyCtxt<'tcx>,
-    dumper: &'ll mut Dumper,
+    dumper: Dumper,
 
     span: SpanUtils<'l>,
 
-    cur_scope: NodeId,
-
     // Set of macro definition (callee) spans, and the set
     // of macro use (callsite) spans. We store these to ensure
     // we only write one macro def per unique macro definition, and
@@ -92,36 +90,29 @@ pub struct DumpVisitor<'l, 'tcx, 'll> {
     // macro_calls: FxHashSet<Span>,
 }
 
-impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> {
+impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
     pub fn new(
         save_ctxt: SaveContext<'l, 'tcx>,
-        dumper: &'ll mut Dumper,
-    ) -> DumpVisitor<'l, 'tcx, 'll> {
+    ) -> DumpVisitor<'l, 'tcx> {
         let span_utils = SpanUtils::new(&save_ctxt.tcx.sess);
+        let dumper = Dumper::new(save_ctxt.config.clone());
         DumpVisitor {
             tcx: save_ctxt.tcx,
             save_ctxt,
             dumper,
             span: span_utils,
-            cur_scope: CRATE_NODE_ID,
             // mac_defs: FxHashSet::default(),
             // macro_calls: FxHashSet::default(),
         }
     }
 
-    fn nest_scope<F>(&mut self, scope_id: NodeId, f: F)
-    where
-        F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>),
-    {
-        let parent_scope = self.cur_scope;
-        self.cur_scope = scope_id;
-        f(self);
-        self.cur_scope = parent_scope;
+    pub fn analysis(&self) -> &rls_data::Analysis {
+        self.dumper.analysis()
     }
 
     fn nest_tables<F>(&mut self, item_id: NodeId, f: F)
     where
-        F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>),
+        F: FnOnce(&mut Self),
     {
         let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
         if self.tcx.has_typeck_tables(item_def_id) {
@@ -320,7 +311,7 @@ impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> {
 
         // walk the fn body
         if let Some(body) = body {
-            self.nest_tables(id, |v| v.nest_scope(id, |v| v.visit_block(body)));
+            self.nest_tables(id, |v| v.visit_block(body));
         }
     }
 
@@ -405,7 +396,7 @@ impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> {
             self.visit_ty(&ret_ty);
         }
 
-        self.nest_tables(item.id, |v| v.nest_scope(item.id, |v| v.visit_block(&body)));
+        self.nest_tables(item.id, |v| v.visit_block(&body));
     }
 
     fn process_static_or_const_item(
@@ -1311,7 +1302,7 @@ impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> {
     }
 }
 
-impl<'l, 'tcx, 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll> {
+impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
     fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], id: NodeId) {
         // Since we handle explicit modules ourselves in visit_item, this should
         // only get called for the root module of a crate.
@@ -1349,7 +1340,7 @@ impl<'l, 'tcx, 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll> {
                 attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt),
             },
         );
-        self.nest_scope(id, |v| visit::walk_mod(v, m));
+        visit::walk_mod(self, m);
     }
 
     fn visit_item(&mut self, item: &'l ast::Item) {
@@ -1404,7 +1395,7 @@ impl<'l, 'tcx, 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll> {
             }
             Mod(ref m) => {
                 self.process_mod(item);
-                self.nest_scope(item.id, |v| visit::walk_mod(v, m));
+                visit::walk_mod(self, m);
             }
             Ty(ref ty, ref ty_params) => {
                 let qualname = format!("::{}",
@@ -1570,7 +1561,7 @@ impl<'l, 'tcx, 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll> {
                 // walk the body
                 self.nest_tables(ex.id, |v| {
                     v.process_formals(&decl.inputs, &id);
-                    v.nest_scope(ex.id, |v| v.visit_expr(body))
+                    v.visit_expr(body)
                 });
             }
             ast::ExprKind::ForLoop(ref pattern, ref subexpression, ref block, _) => {
diff --git a/src/librustc_save_analysis/dumper.rs b/src/librustc_save_analysis/dumper.rs
index 6fb55e6c990..b80778c8fec 100644
--- a/src/librustc_save_analysis/dumper.rs
+++ b/src/librustc_save_analysis/dumper.rs
@@ -22,8 +22,8 @@ impl Dumper {
         }
     }
 
-    pub fn to_output(self, f: impl FnOnce(&Analysis)) {
-        f(&self.result)
+    pub fn analysis(&self) -> &Analysis {
+        &self.result
     }
 }
 
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 9edb4c0fa67..25dcd4664a6 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -35,12 +35,11 @@ use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{arg_to_string, ty_to_string};
 use syntax_pos::*;
 
-use dumper::Dumper;
 use dump_visitor::DumpVisitor;
 use span_utils::SpanUtils;
 
 use rls_data::{Def, DefKind, ExternalCrateData, GlobalCrateId, MacroRef, Ref, RefKind, Relation,
-               RelationKind, SpanData, Impl, ImplKind};
+               RelationKind, SpanData, Impl, ImplKind, Analysis};
 use rls_data::config::Config;
 
 use log::{debug, error, info};
@@ -997,12 +996,10 @@ impl<'l> Visitor<'l> for PathCollector<'l> {
 
 /// Defines what to do with the results of saving the analysis.
 pub trait SaveHandler {
-    fn save<'l, 'tcx>(
+    fn save(
         &mut self,
-        save_ctxt: SaveContext<'l, 'tcx>,
-        krate: &ast::Crate,
-        cratename: &str,
-        input: &'l Input,
+        save_ctxt: &SaveContext<'_, '_>,
+        analysis: &Analysis,
     );
 }
 
@@ -1062,28 +1059,17 @@ impl<'a> DumpHandler<'a> {
     }
 }
 
-impl<'a> SaveHandler for DumpHandler<'a> {
-    fn save<'l, 'tcx>(
+impl SaveHandler for DumpHandler<'_> {
+    fn save(
         &mut self,
-        save_ctxt: SaveContext<'l, 'tcx>,
-        krate: &ast::Crate,
-        cratename: &str,
-        input: &'l Input,
+        save_ctxt: &SaveContext<'_, '_>,
+        analysis: &Analysis,
     ) {
         let sess = &save_ctxt.tcx.sess;
         let (output, file_name) = self.output_file(&save_ctxt);
-        let mut dumper = Dumper::new(save_ctxt.config.clone());
-        let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
-
-        visitor.dump_crate_info(cratename, krate);
-        visitor.dump_compilation_options(input, cratename);
-        visit::walk_crate(&mut visitor, krate);
-
-        dumper.to_output(|analysis| {
-            if let Err(e) = serde_json::to_writer(output, analysis) {
-                error!("Can't serialize save-analysis: {:?}", e);
-            }
-        });
+        if let Err(e) = serde_json::to_writer(output, &analysis) {
+            error!("Can't serialize save-analysis: {:?}", e);
+        }
 
         if sess.opts.debugging_opts.emit_artifact_notifications {
             sess.parse_sess.span_diagnostic
@@ -1097,27 +1083,13 @@ pub struct CallbackHandler<'b> {
     pub callback: &'b mut dyn FnMut(&rls_data::Analysis),
 }
 
-impl<'b> SaveHandler for CallbackHandler<'b> {
-    fn save<'l, 'tcx>(
+impl SaveHandler for CallbackHandler<'_> {
+    fn save(
         &mut self,
-        save_ctxt: SaveContext<'l, 'tcx>,
-        krate: &ast::Crate,
-        cratename: &str,
-        input: &'l Input,
+        _: &SaveContext<'_, '_>,
+        analysis: &Analysis,
     ) {
-        // We're using the Dumper here because it has the format of the
-        // save-analysis results that we will pass to the callback. IOW, we are
-        // using the Dumper to collect the save-analysis results, but not
-        // actually to dump them to a file. This is all a bit convoluted and
-        // there is certainly a simpler design here trying to get out (FIXME).
-        let mut dumper = Dumper::new(save_ctxt.config.clone());
-        let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
-
-        visitor.dump_crate_info(cratename, krate);
-        visitor.dump_compilation_options(input, cratename);
-        visit::walk_crate(&mut visitor, krate);
-
-        dumper.to_output(|a| (self.callback)(a))
+        (self.callback)(analysis)
     }
 }
 
@@ -1148,7 +1120,13 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
             impl_counter: Cell::new(0),
         };
 
-        handler.save(save_ctxt, krate, cratename, input)
+        let mut visitor = DumpVisitor::new(save_ctxt);
+
+        visitor.dump_crate_info(cratename, krate);
+        visitor.dump_compilation_options(input, cratename);
+        visit::walk_crate(&mut visitor, krate);
+
+        handler.save(&visitor.save_ctxt, &visitor.analysis())
     })
 }
 
diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs
index 39a8ce92825..6f00245b009 100644
--- a/src/librustc_target/spec/wasm32_base.rs
+++ b/src/librustc_target/spec/wasm32_base.rs
@@ -132,6 +132,14 @@ pub fn options() -> TargetOptions {
         // non-relative calls and such later on).
         relocation_model: "static".to_string(),
 
+        // When the atomics feature is activated then these two keys matter,
+        // otherwise they're basically ignored by the standard library. In this
+        // mode, however, the `#[thread_local]` attribute works (i.e.
+        // `has_elf_tls`) and we need to get it to work by specifying
+        // `local-exec` as that's all that's implemented in LLVM today for wasm.
+        has_elf_tls: true,
+        tls_model: "local-exec".to_string(),
+
         .. Default::default()
     }
 }
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 6da77ab57d1..2e0da0409eb 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -75,11 +75,6 @@ panic_immediate_abort = ["core/panic_immediate_abort"]
 # requires rebuilding the standard library to use it.
 wasm_syscall = []
 
-# An off-by-default features to enable libstd to assume that wasm-bindgen is in
-# the environment for hooking up some thread-related information like the
-# current thread id and accessing/getting the current thread's TCB
-wasm-bindgen-threads = []
-
 # Enable std_detect default features for stdarch/crates/std_detect:
 # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
 std_detect_file_io = []
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index e22434439f5..f842869e08e 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -47,6 +47,8 @@ pub mod stdio;
 pub mod thread;
 #[path = "../wasm/thread_local.rs"]
 pub mod thread_local;
+#[path = "../wasm/fast_thread_local.rs"]
+pub mod fast_thread_local;
 pub mod time;
 pub mod ext;
 
diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/fast_thread_local.rs
new file mode 100644
index 00000000000..ff2198175f0
--- /dev/null
+++ b/src/libstd/sys/wasm/fast_thread_local.rs
@@ -0,0 +1,9 @@
+#![unstable(feature = "thread_local_internals", issue = "0")]
+
+pub unsafe fn register_dtor(_t: *mut u8, _dtor: unsafe extern fn(*mut u8)) {
+    // FIXME: right now there is no concept of "thread exit", but this is likely
+    // going to show up at some point in the form of an exported symbol that the
+    // wasm runtime is oging to be expected to call. For now we basically just
+    // ignore the arguments, but if such a function starts to exist it will
+    // likely look like the OSX implementation in `unix/fast_thread_local.rs`
+}
diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs
index 7d157709eb6..56cbafcfdb8 100644
--- a/src/libstd/sys/wasm/mod.rs
+++ b/src/libstd/sys/wasm/mod.rs
@@ -37,6 +37,8 @@ pub mod stack_overflow;
 pub mod thread;
 pub mod time;
 pub mod stdio;
+pub mod thread_local;
+pub mod fast_thread_local;
 
 pub use crate::sys_common::os_str_bytes as os_str;
 
@@ -48,13 +50,10 @@ cfg_if::cfg_if! {
         pub mod mutex;
         #[path = "rwlock_atomics.rs"]
         pub mod rwlock;
-        #[path = "thread_local_atomics.rs"]
-        pub mod thread_local;
     } else {
         pub mod condvar;
         pub mod mutex;
         pub mod rwlock;
-        pub mod thread_local;
     }
 }
 
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index 61b4003cd3d..d06965f3278 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -59,48 +59,40 @@ pub mod guard {
     pub unsafe fn init() -> Option<Guard> { None }
 }
 
-cfg_if::cfg_if! {
-    if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] {
-        #[link(wasm_import_module = "__wbindgen_thread_xform__")]
-        extern {
-            fn __wbindgen_current_id() -> u32;
-            fn __wbindgen_tcb_get() -> u32;
-            fn __wbindgen_tcb_set(ptr: u32);
+// This is only used by atomics primitives when the `atomics` feature is
+// enabled. In that mode we currently just use our own thread-local to store our
+// current thread's ID, and then we lazily initialize it to something allocated
+// from a global counter.
+#[cfg(target_feature = "atomics")]
+pub fn my_id() -> u32 {
+    use crate::sync::atomic::{AtomicU32, Ordering::SeqCst};
+
+    static NEXT_ID: AtomicU32 = AtomicU32::new(0);
+
+    #[thread_local]
+    static mut MY_ID: u32 = 0;
+
+    unsafe {
+        // If our thread ID isn't set yet then we need to allocate one. Do so
+        // with with a simple "atomically add to a global counter" strategy.
+        // This strategy doesn't handled what happens when the counter
+        // overflows, however, so just abort everything once the counter
+        // overflows and eventually we could have some sort of recycling scheme
+        // (or maybe this is all totally irrelevant by that point!). In any case
+        // though we're using a CAS loop instead of a `fetch_add` to ensure that
+        // the global counter never overflows.
+        if MY_ID == 0 {
+            let mut cur = NEXT_ID.load(SeqCst);
+            MY_ID = loop {
+                let next = cur.checked_add(1).unwrap_or_else(|| {
+                    crate::arch::wasm32::unreachable()
+                });
+                match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) {
+                    Ok(_) => break next,
+                    Err(i) => cur = i,
+                }
+            };
         }
-        pub fn my_id() -> u32 {
-            unsafe { __wbindgen_current_id() }
-        }
-
-        // These are currently only ever used in `thread_local_atomics.rs`, if
-        // you'd like to use them be sure to update that and make sure everyone
-        // agrees what's what.
-        pub fn tcb_get() -> *mut u8 {
-            use crate::mem;
-            assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::<u32>());
-            unsafe { __wbindgen_tcb_get() as *mut u8 }
-        }
-
-        pub fn tcb_set(ptr: *mut u8) {
-            unsafe { __wbindgen_tcb_set(ptr as u32); }
-        }
-
-        // FIXME: still need something for hooking exiting a thread to free
-        // data...
-
-    } else if #[cfg(target_feature = "atomics")] {
-        pub fn my_id() -> u32 {
-            panic!("thread ids not implemented on wasm with atomics yet")
-        }
-
-        pub fn tcb_get() -> *mut u8 {
-            panic!("thread local data not implemented on wasm with atomics yet")
-        }
-
-        pub fn tcb_set(_ptr: *mut u8) {
-            panic!("thread local data not implemented on wasm with atomics yet")
-        }
-    } else {
-        // stubbed out because no functions actually access these intrinsics
-        // unless atomics are enabled
+        MY_ID
     }
 }
diff --git a/src/libstd/sys/wasm/thread_local.rs b/src/libstd/sys/wasm/thread_local.rs
index 29e9854bcfc..8a0ca6f3d25 100644
--- a/src/libstd/sys/wasm/thread_local.rs
+++ b/src/libstd/sys/wasm/thread_local.rs
@@ -1,40 +1,26 @@
-use crate::boxed::Box;
-use crate::ptr;
-
 pub type Key = usize;
 
-struct Allocated {
-    value: *mut u8,
-    dtor: Option<unsafe extern fn(*mut u8)>,
-}
-
 #[inline]
-pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
-    Box::into_raw(Box::new(Allocated {
-        value: ptr::null_mut(),
-        dtor,
-    })) as usize
+pub unsafe fn create(_dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    (*(key as *mut Allocated)).value = value;
+pub unsafe fn set(_key: Key, _value: *mut u8) {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    (*(key as *mut Allocated)).value
+pub unsafe fn get(_key: Key) -> *mut u8 {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn destroy(key: Key) {
-    let key = Box::from_raw(key as *mut Allocated);
-    if let Some(f) = key.dtor {
-        f(key.value);
-    }
+pub unsafe fn destroy(_key: Key) {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
 pub fn requires_synchronized_create() -> bool {
-    false
+    panic!("should not be used on the wasm target");
 }
diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs
deleted file mode 100644
index 3dc0bb24553..00000000000
--- a/src/libstd/sys/wasm/thread_local_atomics.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-use crate::sys::thread;
-use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
-
-const MAX_KEYS: usize = 128;
-static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
-
-struct ThreadControlBlock {
-    keys: [*mut u8; MAX_KEYS],
-}
-
-impl ThreadControlBlock {
-    fn new() -> ThreadControlBlock {
-        ThreadControlBlock {
-            keys: [core::ptr::null_mut(); MAX_KEYS],
-        }
-    }
-
-    fn get() -> *mut ThreadControlBlock {
-        let ptr = thread::tcb_get();
-        if !ptr.is_null() {
-            return ptr as *mut ThreadControlBlock
-        }
-        let tcb = Box::into_raw(Box::new(ThreadControlBlock::new()));
-        thread::tcb_set(tcb as *mut u8);
-        tcb
-    }
-}
-
-pub type Key = usize;
-
-pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
-    drop(dtor); // FIXME: need to figure out how to hook thread exit to run this
-    let key = NEXT_KEY.fetch_add(1, SeqCst);
-    if key >= MAX_KEYS {
-        NEXT_KEY.store(MAX_KEYS, SeqCst);
-        panic!("cannot allocate space for more TLS keys");
-    }
-    // offset by 1 so we never hand out 0. This is currently required by
-    // `sys_common/thread_local.rs` where it can't cope with keys of value 0
-    // because it messes up the atomic management.
-    return key + 1
-}
-
-pub unsafe fn set(key: Key, value: *mut u8) {
-    (*ThreadControlBlock::get()).keys[key - 1] = value;
-}
-
-pub unsafe fn get(key: Key) -> *mut u8 {
-    (*ThreadControlBlock::get()).keys[key - 1]
-}
-
-pub unsafe fn destroy(_key: Key) {
-    // FIXME: should implement this somehow, this isn't typically called but it
-    // can be called if two threads race to initialize a TLS slot and one ends
-    // up not being needed.
-}
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    false
-}
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 384474b08f6..34e4d7d5a19 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -243,9 +243,6 @@ declare_features! (
     // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
     (active, allocator_internals, "1.20.0", None, None),
 
-    // Allows using the `format_args_nl` macro.
-    (active, format_args_nl, "1.29.0", Some(0), None),
-
     // no-tracking-issue-end
 
     // Added for testing E0705; perma-unstable.
@@ -286,12 +283,6 @@ declare_features! (
     // feature-group-start: actual feature gates
     // -------------------------------------------------------------------------
 
-    // Allows using `asm!` macro with which inline assembly can be embedded.
-    (active, asm, "1.0.0", Some(29722), None),
-
-    // Allows using the `concat_idents!` macro with which identifiers can be concatenated.
-    (active, concat_idents, "1.0.0", Some(29599), None),
-
     // Allows using the `#[link_args]` attribute.
     (active, link_args, "1.0.0", Some(29596), None),
 
@@ -307,12 +298,6 @@ declare_features! (
     // Allows using `#[thread_local]` on `static` items.
     (active, thread_local, "1.0.0", Some(29594), None),
 
-    // Allows using the `log_syntax!` macro.
-    (active, log_syntax, "1.0.0", Some(29598), None),
-
-    // Allows using the `trace_macros!` macro.
-    (active, trace_macros, "1.0.0", Some(29598), None),
-
     // Allows the use of SIMD types in functions declared in `extern` blocks.
     (active, simd_ffi, "1.0.0", Some(27731), None),
 
@@ -402,9 +387,6 @@ declare_features! (
     // Allows `extern "x86-interrupt" fn()`.
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
 
-    // Allows module-level inline assembly by way of `global_asm!()`.
-    (active, global_asm, "1.18.0", Some(35119), None),
-
     // Allows overlapping impls of marker traits.
     (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
 
@@ -472,7 +454,7 @@ declare_features! (
     (active, doc_alias, "1.27.0", Some(50146), None),
 
     // Allows defining `existential type`s.
-    (active, existential_type, "1.28.0", Some(34511), None),
+    (active, existential_type, "1.28.0", Some(63063), None),
 
     // Allows inconsistent bounds in where clauses.
     (active, trivial_bounds, "1.28.0", Some(48214), None),
@@ -525,7 +507,7 @@ declare_features! (
     (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
 
     // Allows `impl Trait` in bindings (`let`, `const`, `static`).
-    (active, impl_trait_in_bindings, "1.30.0", Some(34511), None),
+    (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
 
     // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (active, lint_reasons, "1.31.0", Some(54503), None),
diff --git a/src/llvm-project b/src/llvm-project
-Subproject f6446fa8e9629ffb1861303f17930c3aa83ef66
+Subproject 9b64ca5b7e1e3583978f9ac8af6d93b220a13d9
diff --git a/src/test/ui/core-run-destroy.rs b/src/test/ui/core-run-destroy.rs
index 225b2ca8f4d..b3614bfd5b6 100644
--- a/src/test/ui/core-run-destroy.rs
+++ b/src/test/ui/core-run-destroy.rs
@@ -8,6 +8,7 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 // ignore-sgx no processes
+// ignore-vxworks no 'cat' and 'sleep'
 
 // N.B., these tests kill child processes. Valgrind sees these children as leaking
 // memory, which makes for some *confusing* logs. That's why these are here
diff --git a/src/test/ui/existential-type/issue-60371.stderr b/src/test/ui/existential-type/issue-60371.stderr
index 6349b92f3e6..092cb31f97d 100644
--- a/src/test/ui/existential-type/issue-60371.stderr
+++ b/src/test/ui/existential-type/issue-60371.stderr
@@ -4,7 +4,7 @@ error[E0658]: existential types are unstable
 LL |     existential type Item: Bug;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/34511
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(existential_type)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `(): Bug` is not satisfied
diff --git a/src/test/ui/feature-gates/feature-gate-asm2.rs b/src/test/ui/feature-gates/feature-gate-asm2.rs
index 82900eb7e6c..4f56aa72344 100644
--- a/src/test/ui/feature-gates/feature-gate-asm2.rs
+++ b/src/test/ui/feature-gates/feature-gate-asm2.rs
@@ -1,4 +1,3 @@
-// gate-test-asm
 // ignore-emscripten
 
 fn main() {
diff --git a/src/test/ui/feature-gates/feature-gate-asm2.stderr b/src/test/ui/feature-gates/feature-gate-asm2.stderr
index e985818f30e..7519cad9a96 100644
--- a/src/test/ui/feature-gates/feature-gate-asm2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-asm2.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change
-  --> $DIR/feature-gate-asm2.rs:6:26
+  --> $DIR/feature-gate-asm2.rs:5:26
    |
 LL |         println!("{:?}", asm!(""));
    |                          ^^^
diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.rs b/src/test/ui/feature-gates/feature-gate-concat_idents2.rs
index 0cc6c577e8d..9660ffeafa5 100644
--- a/src/test/ui/feature-gates/feature-gate-concat_idents2.rs
+++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.rs
@@ -1,5 +1,3 @@
-// gate-test-concat_idents
-
 fn main() {
     concat_idents!(a, b); //~ ERROR `concat_idents` is not stable enough
                           //~| ERROR cannot find value `ab` in this scope
diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr
index 4ae5e3e7308..14519622c05 100644
--- a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
-  --> $DIR/feature-gate-concat_idents2.rs:4:5
+  --> $DIR/feature-gate-concat_idents2.rs:2:5
    |
 LL |     concat_idents!(a, b);
    |     ^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     concat_idents!(a, b);
    = help: add `#![feature(concat_idents)]` to the crate attributes to enable
 
 error[E0425]: cannot find value `ab` in this scope
-  --> $DIR/feature-gate-concat_idents2.rs:4:5
+  --> $DIR/feature-gate-concat_idents2.rs:2:5
    |
 LL |     concat_idents!(a, b);
    |     ^^^^^^^^^^^^^^^^^^^^^ not found in this scope
diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents3.rs b/src/test/ui/feature-gates/feature-gate-concat_idents3.rs
index 2882e7a8008..81710fd9fb0 100644
--- a/src/test/ui/feature-gates/feature-gate-concat_idents3.rs
+++ b/src/test/ui/feature-gates/feature-gate-concat_idents3.rs
@@ -1,5 +1,3 @@
-// gate-test-concat_idents
-
 const XY_1: i32 = 10;
 
 fn main() {
diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr
index 367638693d7..afe6acb2535 100644
--- a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr
+++ b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
-  --> $DIR/feature-gate-concat_idents3.rs:7:20
+  --> $DIR/feature-gate-concat_idents3.rs:5:20
    |
 LL |     assert_eq!(10, concat_idents!(X, Y_1));
    |                    ^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     assert_eq!(10, concat_idents!(X, Y_1));
    = help: add `#![feature(concat_idents)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
-  --> $DIR/feature-gate-concat_idents3.rs:8:20
+  --> $DIR/feature-gate-concat_idents3.rs:6:20
    |
 LL |     assert_eq!(20, concat_idents!(X, Y_2));
    |                    ^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-existential-type.stderr b/src/test/ui/feature-gates/feature-gate-existential-type.stderr
index 29d047d22e1..30e25e55aff 100644
--- a/src/test/ui/feature-gates/feature-gate-existential-type.stderr
+++ b/src/test/ui/feature-gates/feature-gate-existential-type.stderr
@@ -4,7 +4,7 @@ error[E0658]: existential types are unstable
 LL | existential type Foo: std::fmt::Debug;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/34511
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(existential_type)]` to the crate attributes to enable
 
 error[E0658]: existential types are unstable
@@ -13,7 +13,7 @@ error[E0658]: existential types are unstable
 LL |     existential type Baa: std::fmt::Debug;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/34511
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(existential_type)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax2.rs b/src/test/ui/feature-gates/feature-gate-log_syntax2.rs
index a3906dcc16e..db1a96f1f23 100644
--- a/src/test/ui/feature-gates/feature-gate-log_syntax2.rs
+++ b/src/test/ui/feature-gates/feature-gate-log_syntax2.rs
@@ -1,5 +1,3 @@
-// gate-test-log_syntax
-
 fn main() {
     println!("{:?}", log_syntax!()); //~ ERROR `log_syntax!` is not stable
 }
diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr
index 0443b988b41..81daee0b49f 100644
--- a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change
-  --> $DIR/feature-gate-log_syntax2.rs:4:22
+  --> $DIR/feature-gate-log_syntax2.rs:2:22
    |
 LL |     println!("{:?}", log_syntax!());
    |                      ^^^^^^^^^^
diff --git a/src/test/ui/process/process-sigpipe.rs b/src/test/ui/process/process-sigpipe.rs
index bf589096006..36303440ee9 100644
--- a/src/test/ui/process/process-sigpipe.rs
+++ b/src/test/ui/process/process-sigpipe.rs
@@ -14,6 +14,7 @@
 
 // ignore-cloudabi no subprocesses support
 // ignore-emscripten no threads support
+// ignore-vxworks no 'sh'
 
 use std::process;
 use std::thread;
diff --git a/src/test/ui/wait-forked-but-failed-child.rs b/src/test/ui/wait-forked-but-failed-child.rs
index 434361b40de..08b16c0e9ca 100644
--- a/src/test/ui/wait-forked-but-failed-child.rs
+++ b/src/test/ui/wait-forked-but-failed-child.rs
@@ -2,6 +2,7 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 // ignore-sgx no processes
+// ignore-vxworks no 'ps'
 
 #![feature(rustc_private)]
 
diff --git a/src/test/ui/x86stdcall.rs b/src/test/ui/x86stdcall.rs
index fc67ccdc8c4..32a4df87fbe 100644
--- a/src/test/ui/x86stdcall.rs
+++ b/src/test/ui/x86stdcall.rs
@@ -32,5 +32,6 @@ pub fn main() {
           target_os = "macos",
           target_os = "netbsd",
           target_os = "openbsd",
+          target_os = "vxworks",
           target_os = "solaris"))]
 pub fn main() { }