Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/unstable_features.rs')
-rw-r--r--crates/hir-def/src/unstable_features.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/crates/hir-def/src/unstable_features.rs b/crates/hir-def/src/unstable_features.rs
new file mode 100644
index 0000000000..3b7f83081f
--- /dev/null
+++ b/crates/hir-def/src/unstable_features.rs
@@ -0,0 +1,91 @@
+//! Handling of unstable features.
+//!
+//! We define two kinds of handling: we have a map of all unstable features for a crate
+//! as `Symbol`s. This is mostly for external consumers.
+//!
+//! For analysis, we store them as a struct of bools, for fast access.
+
+use std::fmt;
+
+use base_db::Crate;
+use intern::{Symbol, sym};
+use rustc_hash::FxHashSet;
+
+use crate::db::DefDatabase;
+
+impl fmt::Debug for UnstableFeatures {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_set().entries(&self.all).finish()
+ }
+}
+
+impl PartialEq for UnstableFeatures {
+ fn eq(&self, other: &Self) -> bool {
+ self.all == other.all
+ }
+}
+
+impl Eq for UnstableFeatures {}
+
+impl UnstableFeatures {
+ #[inline]
+ pub fn is_enabled(&self, feature: &Symbol) -> bool {
+ self.all.contains(feature)
+ }
+
+ #[inline]
+ pub fn iter(&self) -> impl Iterator<Item = Symbol> {
+ self.all.iter().cloned()
+ }
+
+ pub(crate) fn shrink_to_fit(&mut self) {
+ self.all.shrink_to_fit();
+ }
+}
+
+#[salsa::tracked]
+impl UnstableFeatures {
+ /// Query unstable features for a crate.
+ ///
+ /// This is also available as `DefMap::features()`. Use that if you have a DefMap available.
+ /// Otherwise, use this, to not draw a dependency to the def map.
+ #[salsa::tracked(returns(ref))]
+ pub fn query(db: &dyn DefDatabase, krate: Crate) -> UnstableFeatures {
+ crate::crate_def_map(db, krate).features().clone()
+ }
+}
+
+macro_rules! define_unstable_features {
+ ( $( $feature:ident, )* ) => {
+ #[derive(Clone, Default)]
+ pub struct UnstableFeatures {
+ all: FxHashSet<Symbol>,
+
+ $( pub $feature: bool, )*
+ }
+
+ impl UnstableFeatures {
+ pub(crate) fn enable(&mut self, feature: Symbol) {
+ match () {
+ $( () if feature == sym::$feature => self.$feature = true, )*
+ _ => {}
+ }
+
+ self.all.insert(feature);
+ }
+ }
+ };
+}
+
+define_unstable_features! {
+ lang_items,
+ exhaustive_patterns,
+ generic_associated_type_extended,
+ arbitrary_self_types,
+ arbitrary_self_types_pointers,
+ supertrait_item_shadowing,
+ new_range,
+ never_type_fallback,
+ specialization,
+ min_specialization,
+}