Skip to main content

hir_def/
unstable_features.rs

1//! Handling of unstable features.
2//!
3//! We define two kinds of handling: we have a map of all unstable features for a crate
4//! as `Symbol`s. This is mostly for external consumers.
5//!
6//! For analysis, we store them as a struct of bools, for fast access.
7
8use std::fmt;
9
10use base_db::{Crate, SourceDatabase};
11use intern::{Symbol, sym};
12use rustc_hash::FxHashSet;
13
14impl fmt::Debug for UnstableFeatures {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        f.debug_set().entries(&self.all).finish()
17    }
18}
19
20impl PartialEq for UnstableFeatures {
21    fn eq(&self, other: &Self) -> bool {
22        self.all == other.all
23    }
24}
25
26impl Eq for UnstableFeatures {}
27
28impl UnstableFeatures {
29    #[inline]
30    pub fn is_enabled(&self, feature: &Symbol) -> bool {
31        self.all.contains(feature)
32    }
33
34    #[inline]
35    pub fn iter(&self) -> impl Iterator<Item = Symbol> {
36        self.all.iter().cloned()
37    }
38
39    pub(crate) fn shrink_to_fit(&mut self) {
40        self.all.shrink_to_fit();
41    }
42}
43
44#[salsa::tracked]
45impl UnstableFeatures {
46    /// Query unstable features for a crate.
47    ///
48    /// This is also available as `DefMap::features()`. Use that if you have a DefMap available.
49    /// Otherwise, use this, to not draw a dependency to the def map.
50    #[salsa::tracked(returns(ref))]
51    pub fn query(db: &dyn SourceDatabase, krate: Crate) -> UnstableFeatures {
52        crate::crate_def_map(db, krate).features().clone()
53    }
54}
55
56macro_rules! define_unstable_features {
57    ( $( $feature:ident, )* ) => {
58        #[derive(Clone, Default)]
59        pub struct UnstableFeatures {
60            all: FxHashSet<Symbol>,
61
62            $( pub $feature: bool, )*
63        }
64
65        impl UnstableFeatures {
66            pub(crate) fn enable(&mut self, feature: Symbol) {
67                match () {
68                    $( () if feature == sym::$feature => self.$feature = true, )*
69                    _ => {}
70                }
71
72                self.all.insert(feature);
73            }
74        }
75    };
76}
77
78define_unstable_features! {
79    lang_items,
80    exhaustive_patterns,
81    generic_associated_type_extended,
82    arbitrary_self_types,
83    arbitrary_self_types_pointers,
84    supertrait_item_shadowing,
85    new_range,
86    never_type_fallback,
87    specialization,
88    min_specialization,
89    ref_pat_eat_one_layer_2024,
90    ref_pat_eat_one_layer_2024_structural,
91    deref_patterns,
92    mut_ref,
93    type_changing_struct_update,
94}