hir_def/
unstable_features.rs1use 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 #[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}