about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_data_structures/src')
-rw-r--r--compiler/rustc_data_structures/src/flock.rs5
-rw-r--r--compiler/rustc_data_structures/src/flock/windows.rs64
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/tests.rs6
-rw-r--r--compiler/rustc_data_structures/src/graph/vec_graph/tests.rs6
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs19
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs105
-rw-r--r--compiler/rustc_data_structures/src/vec_map.rs192
-rw-r--r--compiler/rustc_data_structures/src/vec_map/tests.rs48
9 files changed, 138 insertions, 308 deletions
diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs
index e395d8dbbbf..efdb44248d1 100644
--- a/compiler/rustc_data_structures/src/flock.rs
+++ b/compiler/rustc_data_structures/src/flock.rs
@@ -4,9 +4,6 @@
 //! green/native threading. This is just a bare-bones enough solution for
 //! librustdoc, it is not production quality at all.
 
-#![allow(non_camel_case_types)]
-#![allow(nonstandard_style)]
-
 cfg_if! {
     if #[cfg(target_os = "linux")] {
         mod linux;
@@ -16,7 +13,7 @@ cfg_if! {
         use unix as imp;
     } else if #[cfg(windows)] {
         mod windows;
-        use windows as imp;
+        use self::windows as imp;
     } else {
         mod unsupported;
         use unsupported as imp;
diff --git a/compiler/rustc_data_structures/src/flock/windows.rs b/compiler/rustc_data_structures/src/flock/windows.rs
index 43e6caaa18d..da128f464a6 100644
--- a/compiler/rustc_data_structures/src/flock/windows.rs
+++ b/compiler/rustc_data_structures/src/flock/windows.rs
@@ -1,13 +1,16 @@
 use std::fs::{File, OpenOptions};
 use std::io;
-use std::mem;
 use std::os::windows::prelude::*;
 use std::path::Path;
 
-use winapi::shared::winerror::ERROR_INVALID_FUNCTION;
-use winapi::um::fileapi::LockFileEx;
-use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, OVERLAPPED};
-use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};
+use windows::{
+    Win32::Foundation::{ERROR_INVALID_FUNCTION, HANDLE},
+    Win32::Storage::FileSystem::{
+        LockFileEx, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, LOCKFILE_EXCLUSIVE_LOCK,
+        LOCKFILE_FAIL_IMMEDIATELY, LOCK_FILE_FLAGS,
+    },
+    Win32::System::IO::OVERLAPPED,
+};
 
 #[derive(Debug)]
 pub struct Lock {
@@ -25,7 +28,7 @@ impl Lock {
         let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
 
         let mut open_options = OpenOptions::new();
-        open_options.read(true).share_mode(share_mode);
+        open_options.read(true).share_mode(share_mode.0);
 
         if create {
             open_options.create(true).write(true);
@@ -43,33 +46,42 @@ impl Lock {
             }
         };
 
-        let ret = unsafe {
-            let mut overlapped: OVERLAPPED = mem::zeroed();
+        let mut flags = LOCK_FILE_FLAGS::default();
+        if !wait {
+            flags |= LOCKFILE_FAIL_IMMEDIATELY;
+        }
 
-            let mut dwFlags = 0;
-            if !wait {
-                dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
-            }
+        if exclusive {
+            flags |= LOCKFILE_EXCLUSIVE_LOCK;
+        }
 
-            if exclusive {
-                dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
-            }
+        let mut overlapped = OVERLAPPED::default();
 
-            debug!("attempting to acquire lock on lock file `{}`", p.display());
-            LockFileEx(file.as_raw_handle(), dwFlags, 0, 0xFFFF_FFFF, 0xFFFF_FFFF, &mut overlapped)
-        };
-        if ret == 0 {
-            let err = io::Error::last_os_error();
-            debug!("failed acquiring file lock: {}", err);
-            Err(err)
-        } else {
-            debug!("successfully acquired lock");
-            Ok(Lock { _file: file })
+        debug!("attempting to acquire lock on lock file `{}`", p.display());
+
+        unsafe {
+            LockFileEx(
+                HANDLE(file.as_raw_handle() as isize),
+                flags,
+                0,
+                u32::MAX,
+                u32::MAX,
+                &mut overlapped,
+            )
         }
+        .ok()
+        .map_err(|e| {
+            let err = io::Error::from_raw_os_error(e.code().0);
+            debug!("failed acquiring file lock: {}", err);
+            err
+        })?;
+
+        debug!("successfully acquired lock");
+        Ok(Lock { _file: file })
     }
 
     pub fn error_unsupported(err: &io::Error) -> bool {
-        err.raw_os_error() == Some(ERROR_INVALID_FUNCTION as i32)
+        err.raw_os_error() == Some(ERROR_INVALID_FUNCTION.0 as i32)
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs
index 820a70fc8e4..513df666d0d 100644
--- a/compiler/rustc_data_structures/src/graph/scc/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs
@@ -56,7 +56,7 @@ fn test_three_sccs() {
     assert_eq!(sccs.scc(1), 0);
     assert_eq!(sccs.scc(2), 0);
     assert_eq!(sccs.scc(3), 2);
-    assert_eq!(sccs.successors(0), &[]);
+    assert_eq!(sccs.successors(0), &[] as &[usize]);
     assert_eq!(sccs.successors(1), &[0]);
     assert_eq!(sccs.successors(2), &[0]);
 }
@@ -113,7 +113,7 @@ fn test_find_state_2() {
     assert_eq!(sccs.scc(2), 0);
     assert_eq!(sccs.scc(3), 0);
     assert_eq!(sccs.scc(4), 0);
-    assert_eq!(sccs.successors(0), &[]);
+    assert_eq!(sccs.successors(0), &[] as &[usize]);
 }
 
 #[test]
@@ -138,7 +138,7 @@ fn test_find_state_3() {
     assert_eq!(sccs.scc(3), 0);
     assert_eq!(sccs.scc(4), 0);
     assert_eq!(sccs.scc(5), 1);
-    assert_eq!(sccs.successors(0), &[]);
+    assert_eq!(sccs.successors(0), &[] as &[usize]);
     assert_eq!(sccs.successors(1), &[0]);
 }
 
diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs
index c8f97926717..7c866da6009 100644
--- a/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs
@@ -27,11 +27,11 @@ fn successors() {
     let graph = create_graph();
     assert_eq!(graph.successors(0), &[1]);
     assert_eq!(graph.successors(1), &[2, 3]);
-    assert_eq!(graph.successors(2), &[]);
+    assert_eq!(graph.successors(2), &[] as &[usize]);
     assert_eq!(graph.successors(3), &[4]);
-    assert_eq!(graph.successors(4), &[]);
+    assert_eq!(graph.successors(4), &[] as &[usize]);
     assert_eq!(graph.successors(5), &[1]);
-    assert_eq!(graph.successors(6), &[]);
+    assert_eq!(graph.successors(6), &[] as &[usize]);
 }
 
 #[test]
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index c595bf830a3..0339fb925d4 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -79,7 +79,6 @@ pub mod sync;
 pub mod tiny_list;
 pub mod transitive_relation;
 pub mod vec_linked_list;
-pub mod vec_map;
 pub mod work_queue;
 pub use atomic_ref::AtomicRef;
 pub mod frozen;
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 91abdaadabd..27a869eb7cd 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -97,7 +97,17 @@ pub trait ObligationProcessor {
     type Error: Debug;
     type OUT: OutcomeTrait<Obligation = Self::Obligation, Error = Error<Self::Obligation, Self::Error>>;
 
-    fn needs_process_obligation(&self, obligation: &Self::Obligation) -> bool;
+    /// Implementations can provide a fast-path to obligation-processing
+    /// by counting the prefix of the passed iterator for which
+    /// `needs_process_obligation` would return false.
+    fn skippable_obligations<'a>(
+        &'a self,
+        _it: impl Iterator<Item = &'a Self::Obligation>,
+    ) -> usize {
+        0
+    }
+
+    fn needs_process_obligation(&self, _obligation: &Self::Obligation) -> bool;
 
     fn process_obligation(
         &mut self,
@@ -416,6 +426,10 @@ impl<O: ForestObligation> ObligationForest<O> {
         loop {
             let mut has_changed = false;
 
+            // This is the super fast path for cheap-to-check conditions.
+            let mut index =
+                processor.skippable_obligations(self.nodes.iter().map(|n| &n.obligation));
+
             // Note that the loop body can append new nodes, and those new nodes
             // will then be processed by subsequent iterations of the loop.
             //
@@ -424,9 +438,8 @@ impl<O: ForestObligation> ObligationForest<O> {
             // `for index in 0..self.nodes.len() { ... }` because the range would
             // be computed with the initial length, and we would miss the appended
             // nodes. Therefore we use a `while` loop.
-            let mut index = 0;
             while let Some(node) = self.nodes.get_mut(index) {
-                // This test is extremely hot.
+                // This is the moderately fast path when the prefix skipping above didn't work out.
                 if node.state.get() != NodeState::Pending
                     || !processor.needs_process_obligation(&node.obligation)
                 {
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 44331683694..58a0609e296 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -97,6 +97,7 @@ use std::time::{Duration, Instant};
 pub use measureme::EventId;
 use measureme::{EventIdBuilder, Profiler, SerializableString, StringId};
 use parking_lot::RwLock;
+use serde_json::json;
 use smallvec::SmallVec;
 
 bitflags::bitflags! {
@@ -145,6 +146,15 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
 /// Something that uniquely identifies a query invocation.
 pub struct QueryInvocationId(pub u32);
 
+/// Which format to use for `-Z time-passes`
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum TimePassesFormat {
+    /// Emit human readable text
+    Text,
+    /// Emit structured JSON
+    Json,
+}
+
 /// A reference to the SelfProfiler. It can be cloned and sent across thread
 /// boundaries at will.
 #[derive(Clone)]
@@ -158,14 +168,14 @@ pub struct SelfProfilerRef {
     // actually enabled.
     event_filter_mask: EventFilter,
 
-    // Print verbose generic activities to stderr?
-    print_verbose_generic_activities: bool,
+    // Print verbose generic activities to stderr.
+    print_verbose_generic_activities: Option<TimePassesFormat>,
 }
 
 impl SelfProfilerRef {
     pub fn new(
         profiler: Option<Arc<SelfProfiler>>,
-        print_verbose_generic_activities: bool,
+        print_verbose_generic_activities: Option<TimePassesFormat>,
     ) -> SelfProfilerRef {
         // If there is no SelfProfiler then the filter mask is set to NONE,
         // ensuring that nothing ever tries to actually access it.
@@ -207,9 +217,10 @@ impl SelfProfilerRef {
     /// a measureme event, "verbose" generic activities also print a timing entry to
     /// stderr if the compiler is invoked with -Ztime-passes.
     pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> {
-        let message = self.print_verbose_generic_activities.then(|| event_label.to_owned());
+        let message_and_format =
+            self.print_verbose_generic_activities.map(|format| (event_label.to_owned(), format));
 
-        VerboseTimingGuard::start(message, self.generic_activity(event_label))
+        VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label))
     }
 
     /// Like `verbose_generic_activity`, but with an extra arg.
@@ -221,11 +232,14 @@ impl SelfProfilerRef {
     where
         A: Borrow<str> + Into<String>,
     {
-        let message = self
+        let message_and_format = self
             .print_verbose_generic_activities
-            .then(|| format!("{}({})", event_label, event_arg.borrow()));
+            .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format));
 
-        VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg))
+        VerboseTimingGuard::start(
+            message_and_format,
+            self.generic_activity_with_arg(event_label, event_arg),
+        )
     }
 
     /// Start profiling a generic activity. Profiling continues until the
@@ -703,17 +717,32 @@ impl<'a> TimingGuard<'a> {
     }
 }
 
+struct VerboseInfo {
+    start_time: Instant,
+    start_rss: Option<usize>,
+    message: String,
+    format: TimePassesFormat,
+}
+
 #[must_use]
 pub struct VerboseTimingGuard<'a> {
-    start_and_message: Option<(Instant, Option<usize>, String)>,
+    info: Option<VerboseInfo>,
     _guard: TimingGuard<'a>,
 }
 
 impl<'a> VerboseTimingGuard<'a> {
-    pub fn start(message: Option<String>, _guard: TimingGuard<'a>) -> Self {
+    pub fn start(
+        message_and_format: Option<(String, TimePassesFormat)>,
+        _guard: TimingGuard<'a>,
+    ) -> Self {
         VerboseTimingGuard {
             _guard,
-            start_and_message: message.map(|msg| (Instant::now(), get_resident_set_size(), msg)),
+            info: message_and_format.map(|(message, format)| VerboseInfo {
+                start_time: Instant::now(),
+                start_rss: get_resident_set_size(),
+                message,
+                format,
+            }),
         }
     }
 
@@ -726,10 +755,10 @@ impl<'a> VerboseTimingGuard<'a> {
 
 impl Drop for VerboseTimingGuard<'_> {
     fn drop(&mut self) {
-        if let Some((start_time, start_rss, ref message)) = self.start_and_message {
+        if let Some(info) = &self.info {
             let end_rss = get_resident_set_size();
-            let dur = start_time.elapsed();
-            print_time_passes_entry(message, dur, start_rss, end_rss);
+            let dur = info.start_time.elapsed();
+            print_time_passes_entry(&info.message, dur, info.start_rss, end_rss, info.format);
         }
     }
 }
@@ -739,7 +768,22 @@ pub fn print_time_passes_entry(
     dur: Duration,
     start_rss: Option<usize>,
     end_rss: Option<usize>,
+    format: TimePassesFormat,
 ) {
+    match format {
+        TimePassesFormat::Json => {
+            let json = json!({
+                "pass": what,
+                "time": dur.as_secs_f64(),
+                "rss_start": start_rss,
+                "rss_end": end_rss,
+            });
+            eprintln!("time: {}", json.to_string());
+            return;
+        }
+        TimePassesFormat::Text => (),
+    }
+
     // Print the pass if its duration is greater than 5 ms, or it changed the
     // measured RSS.
     let is_notable = || {
@@ -796,21 +840,26 @@ fn get_thread_id() -> u32 {
 cfg_if! {
     if #[cfg(windows)] {
         pub fn get_resident_set_size() -> Option<usize> {
-            use std::mem::{self, MaybeUninit};
-            use winapi::shared::minwindef::DWORD;
-            use winapi::um::processthreadsapi::GetCurrentProcess;
-            use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS};
-
-            let mut pmc = MaybeUninit::<PROCESS_MEMORY_COUNTERS>::uninit();
-            match unsafe {
-                GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD)
-            } {
-                0 => None,
-                _ => {
-                    let pmc = unsafe { pmc.assume_init() };
-                    Some(pmc.WorkingSetSize as usize)
-                }
+            use std::mem;
+
+            use windows::{
+                Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
+                Win32::System::Threading::GetCurrentProcess,
+            };
+
+            let mut pmc = PROCESS_MEMORY_COUNTERS::default();
+            let pmc_size = mem::size_of_val(&pmc);
+            unsafe {
+                K32GetProcessMemoryInfo(
+                    GetCurrentProcess(),
+                    &mut pmc,
+                    pmc_size as u32,
+                )
             }
+            .ok()
+            .ok()?;
+
+            Some(pmc.WorkingSetSize)
         }
     } else if #[cfg(target_os = "macos")] {
         pub fn get_resident_set_size() -> Option<usize> {
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
deleted file mode 100644
index d1a99bcaeb7..00000000000
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-use std::borrow::Borrow;
-use std::fmt::Debug;
-use std::slice::Iter;
-use std::vec::IntoIter;
-
-use crate::stable_hasher::{HashStable, StableHasher};
-
-/// A map type implemented as a vector of pairs `K` (key) and `V` (value).
-/// It currently provides a subset of all the map operations, the rest could be added as needed.
-#[derive(Clone, Encodable, Decodable, Debug)]
-pub struct VecMap<K, V>(Vec<(K, V)>);
-
-impl<K, V> VecMap<K, V>
-where
-    K: Debug + PartialEq,
-    V: Debug,
-{
-    pub fn new() -> Self {
-        VecMap(Default::default())
-    }
-
-    /// Sets the value of the entry, and returns the entry's old value.
-    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
-        if let Some(elem) = self.0.iter_mut().find(|(key, _)| *key == k) {
-            Some(std::mem::replace(&mut elem.1, v))
-        } else {
-            self.0.push((k, v));
-            None
-        }
-    }
-
-    /// Removes the entry from the map and returns the removed value
-    pub fn remove(&mut self, k: &K) -> Option<V> {
-        self.0.iter().position(|(k2, _)| k2 == k).map(|pos| self.0.remove(pos).1)
-    }
-
-    /// Gets a reference to the value in the entry.
-    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
-    where
-        K: Borrow<Q>,
-        Q: Eq,
-    {
-        self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1)
-    }
-
-    /// Gets a mutable reference to the value in the entry.
-    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
-    where
-        K: Borrow<Q>,
-        Q: Eq,
-    {
-        self.0.iter_mut().find(|(key, _)| k == key.borrow()).map(|elem| &mut elem.1)
-    }
-
-    /// Returns the any value corresponding to the supplied predicate filter.
-    ///
-    /// The supplied predicate will be applied to each (key, value) pair and it will return a
-    /// reference to the values where the predicate returns `true`.
-    pub fn any_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
-        self.0.iter().find(|kv| predicate(kv)).map(|elem| &elem.1)
-    }
-
-    /// Returns the value corresponding to the supplied predicate filter. It crashes if there's
-    /// more than one matching element.
-    ///
-    /// The supplied predicate will be applied to each (key, value) pair and it will return a
-    /// reference to the value where the predicate returns `true`.
-    pub fn get_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
-        let mut filter = self.0.iter().filter(|kv| predicate(kv));
-        let (_, value) = filter.next()?;
-        // This should return just one element, otherwise it's a bug
-        assert!(
-            filter.next().is_none(),
-            "Collection {self:#?} should have just one matching element"
-        );
-        Some(value)
-    }
-
-    /// Returns `true` if the map contains a value for the specified key.
-    ///
-    /// The key may be any borrowed form of the map's key type,
-    /// [`Eq`] on the borrowed form *must* match those for
-    /// the key type.
-    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
-    where
-        K: Borrow<Q>,
-        Q: Eq,
-    {
-        self.get(k).is_some()
-    }
-
-    /// Returns `true` if the map contains no elements.
-    pub fn is_empty(&self) -> bool {
-        self.0.is_empty()
-    }
-
-    pub fn iter(&self) -> Iter<'_, (K, V)> {
-        self.into_iter()
-    }
-
-    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
-        self.into_iter()
-    }
-
-    pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) {
-        self.0.retain(f)
-    }
-}
-
-impl<K, V> Default for VecMap<K, V> {
-    #[inline]
-    fn default() -> Self {
-        Self(Default::default())
-    }
-}
-
-impl<K, V> From<Vec<(K, V)>> for VecMap<K, V> {
-    fn from(vec: Vec<(K, V)>) -> Self {
-        Self(vec)
-    }
-}
-
-impl<K, V> Into<Vec<(K, V)>> for VecMap<K, V> {
-    fn into(self) -> Vec<(K, V)> {
-        self.0
-    }
-}
-
-impl<K, V> FromIterator<(K, V)> for VecMap<K, V> {
-    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
-        Self(iter.into_iter().collect())
-    }
-}
-
-impl<'a, K, V> IntoIterator for &'a VecMap<K, V> {
-    type Item = &'a (K, V);
-    type IntoIter = Iter<'a, (K, V)>;
-
-    #[inline]
-    fn into_iter(self) -> Self::IntoIter {
-        self.0.iter()
-    }
-}
-
-impl<'a, K: 'a, V: 'a> IntoIterator for &'a mut VecMap<K, V> {
-    type Item = (&'a K, &'a mut V);
-    type IntoIter = impl Iterator<Item = Self::Item>;
-
-    #[inline]
-    fn into_iter(self) -> Self::IntoIter {
-        self.0.iter_mut().map(|(k, v)| (&*k, v))
-    }
-}
-
-impl<K, V> IntoIterator for VecMap<K, V> {
-    type Item = (K, V);
-    type IntoIter = IntoIter<(K, V)>;
-
-    #[inline]
-    fn into_iter(self) -> Self::IntoIter {
-        self.0.into_iter()
-    }
-}
-
-impl<K: PartialEq + Debug, V: Debug> Extend<(K, V)> for VecMap<K, V> {
-    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
-        for (k, v) in iter {
-            self.insert(k, v);
-        }
-    }
-
-    fn extend_one(&mut self, (k, v): (K, V)) {
-        self.insert(k, v);
-    }
-
-    fn extend_reserve(&mut self, additional: usize) {
-        self.0.extend_reserve(additional);
-    }
-}
-
-impl<K, V, CTX> HashStable<CTX> for VecMap<K, V>
-where
-    K: HashStable<CTX> + Eq,
-    V: HashStable<CTX>,
-{
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        self.0.hash_stable(hcx, hasher)
-    }
-}
-
-#[cfg(test)]
-mod tests;
diff --git a/compiler/rustc_data_structures/src/vec_map/tests.rs b/compiler/rustc_data_structures/src/vec_map/tests.rs
deleted file mode 100644
index 458b60077dc..00000000000
--- a/compiler/rustc_data_structures/src/vec_map/tests.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use super::*;
-
-impl<K, V> VecMap<K, V> {
-    fn into_vec(self) -> Vec<(K, V)> {
-        self.0.into()
-    }
-}
-
-#[test]
-fn test_from_iterator() {
-    assert_eq!(
-        std::iter::empty().collect::<VecMap<i32, bool>>().into_vec(),
-        Vec::<(i32, bool)>::new()
-    );
-    assert_eq!(std::iter::once((42, true)).collect::<VecMap<_, _>>().into_vec(), vec![(42, true)]);
-    assert_eq!(
-        [(1, true), (2, false)].into_iter().collect::<VecMap<_, _>>().into_vec(),
-        vec![(1, true), (2, false)]
-    );
-}
-
-#[test]
-fn test_into_iterator_owned() {
-    assert_eq!(VecMap::new().into_iter().collect::<Vec<(i32, bool)>>(), Vec::<(i32, bool)>::new());
-    assert_eq!(VecMap::from(vec![(1, true)]).into_iter().collect::<Vec<_>>(), vec![(1, true)]);
-    assert_eq!(
-        VecMap::from(vec![(1, true), (2, false)]).into_iter().collect::<Vec<_>>(),
-        vec![(1, true), (2, false)]
-    );
-}
-
-#[test]
-fn test_insert() {
-    let mut v = VecMap::new();
-    assert_eq!(v.insert(1, true), None);
-    assert_eq!(v.insert(2, false), None);
-    assert_eq!(v.clone().into_vec(), vec![(1, true), (2, false)]);
-    assert_eq!(v.insert(1, false), Some(true));
-    assert_eq!(v.into_vec(), vec![(1, false), (2, false)]);
-}
-
-#[test]
-fn test_get() {
-    let v = [(1, true), (2, false)].into_iter().collect::<VecMap<_, _>>();
-    assert_eq!(v.get(&1), Some(&true));
-    assert_eq!(v.get(&2), Some(&false));
-    assert_eq!(v.get(&3), None);
-}