rustc_data_structures/
lib.rs

1//! Various data structures used by the Rust compiler. The intention
2//! is that code in here should not be *specific* to rustc, so that
3//! it can be easily unit tested and so forth.
4//!
5//! # Note
6//!
7//! This API is completely unstable and subject to change.
8
9// tidy-alphabetical-start
10#![allow(internal_features)]
11#![allow(rustc::default_hash_types)]
12#![allow(rustc::potential_query_instability)]
13#![cfg_attr(bootstrap, feature(cfg_match))]
14#![cfg_attr(not(bootstrap), feature(cfg_select))]
15#![cfg_attr(not(bootstrap), feature(sized_hierarchy))]
16#![deny(unsafe_op_in_unsafe_fn)]
17#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
18#![doc(rust_logo)]
19#![feature(allocator_api)]
20#![feature(array_windows)]
21#![feature(ascii_char)]
22#![feature(ascii_char_variants)]
23#![feature(assert_matches)]
24#![feature(auto_traits)]
25#![feature(core_intrinsics)]
26#![feature(dropck_eyepatch)]
27#![feature(extend_one)]
28#![feature(file_buffered)]
29#![feature(map_try_insert)]
30#![feature(min_specialization)]
31#![feature(negative_impls)]
32#![feature(never_type)]
33#![feature(ptr_alignment_type)]
34#![feature(rustc_attrs)]
35#![feature(rustdoc_internals)]
36#![feature(test)]
37#![feature(thread_id_value)]
38#![feature(type_alias_impl_trait)]
39#![feature(unwrap_infallible)]
40// tidy-alphabetical-end
41
42use std::fmt;
43
44pub use atomic_ref::AtomicRef;
45pub use ena::{snapshot_vec, undo_log, unify};
46pub use rustc_index::static_assert_size;
47// re-exported for `rustc_smir`
48// FIXME(sized_hierarchy): remove with `cfg(bootstrap)`, see `rustc_serialize/src/lib.rs`
49pub use rustc_serialize::PointeeSized;
50
51pub mod aligned;
52pub mod base_n;
53pub mod binary_search_util;
54pub mod fingerprint;
55pub mod flat_map_in_place;
56pub mod flock;
57pub mod frozen;
58pub mod fx;
59pub mod graph;
60pub mod intern;
61pub mod jobserver;
62pub mod marker;
63pub mod memmap;
64pub mod obligation_forest;
65pub mod owned_slice;
66pub mod packed;
67pub mod profiling;
68pub mod sharded;
69pub mod small_c_str;
70pub mod snapshot_map;
71pub mod sorted_map;
72pub mod sso;
73pub mod stable_hasher;
74pub mod stack;
75pub mod steal;
76pub mod svh;
77pub mod sync;
78pub mod tagged_ptr;
79pub mod temp_dir;
80pub mod thinvec;
81pub mod thousands;
82pub mod transitive_relation;
83pub mod unhash;
84pub mod unord;
85pub mod vec_cache;
86pub mod work_queue;
87
88mod atomic_ref;
89
90/// This calls the passed function while ensuring it won't be inlined into the caller.
91#[inline(never)]
92#[cold]
93pub fn outline<F: FnOnce() -> R, R>(f: F) -> R {
94    f()
95}
96
97/// Returns a structure that calls `f` when dropped.
98pub fn defer<F: FnOnce()>(f: F) -> OnDrop<F> {
99    OnDrop(Some(f))
100}
101
102pub struct OnDrop<F: FnOnce()>(Option<F>);
103
104impl<F: FnOnce()> OnDrop<F> {
105    /// Disables on-drop call.
106    #[inline]
107    pub fn disable(mut self) {
108        self.0.take();
109    }
110}
111
112impl<F: FnOnce()> Drop for OnDrop<F> {
113    #[inline]
114    fn drop(&mut self) {
115        if let Some(f) = self.0.take() {
116            f();
117        }
118    }
119}
120
121/// This is a marker for a fatal compiler error used with `resume_unwind`.
122pub struct FatalErrorMarker;
123
124/// Turns a closure that takes an `&mut Formatter` into something that can be display-formatted.
125pub fn make_display(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display {
126    struct Printer<F> {
127        f: F,
128    }
129    impl<F> fmt::Display for Printer<F>
130    where
131        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
132    {
133        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
134            (self.f)(fmt)
135        }
136    }
137
138    Printer { f }
139}
140
141// See comment in compiler/rustc_middle/src/tests.rs and issue #27438.
142#[doc(hidden)]
143pub fn __noop_fix_for_windows_dllimport_issue() {}
144
145#[macro_export]
146macro_rules! external_bitflags_debug {
147    ($Name:ident) => {
148        impl ::std::fmt::Debug for $Name {
149            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
150                ::bitflags::parser::to_writer(self, f)
151            }
152        }
153    };
154}