Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22111 from ChayimFriedman2/unstable-features
internal: Create a struct of bools for unstable features, like we did for lang items
| -rw-r--r-- | crates/hir-def/src/lang_item.rs | 2 | ||||
| -rw-r--r-- | crates/hir-def/src/lib.rs | 1 | ||||
| -rw-r--r-- | crates/hir-def/src/nameres.rs | 12 | ||||
| -rw-r--r-- | crates/hir-def/src/nameres/collector.rs | 4 | ||||
| -rw-r--r-- | crates/hir-def/src/unstable_features.rs | 91 | ||||
| -rw-r--r-- | crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs | 6 | ||||
| -rw-r--r-- | crates/hir-ty/src/dyn_compatibility.rs | 16 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 11 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/fallback.rs | 3 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution.rs | 26 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution/confirm.rs | 5 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution/probe.rs | 12 | ||||
| -rw-r--r-- | crates/hir-ty/src/specialization.rs | 11 | ||||
| -rw-r--r-- | crates/hir/src/attrs.rs | 9 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 18 | ||||
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 3 |
16 files changed, 147 insertions, 83 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs index 37d70b1e33..5b6ebe2a0b 100644 --- a/crates/hir-def/src/lang_item.rs +++ b/crates/hir-def/src/lang_item.rs @@ -40,7 +40,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt let crate_def_map = crate_def_map(db, krate); - if !crate_def_map.is_unstable_feature_enabled(&sym::lang_items) { + if !crate_def_map.features().lang_items { return None; } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 9a7fbc812f..2c7685b189 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -32,6 +32,7 @@ pub mod item_tree; pub mod builtin_derive; pub mod lang_item; +pub mod unstable_features; pub mod hir; pub use self::hir::type_ref; diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 56b3f03f7b..88e3408a33 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -68,7 +68,7 @@ use hir_expand::{ }; use intern::Symbol; use itertools::Itertools; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashMap; use span::{Edition, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; use syntax::{AstNode, SmolStr, SyntaxNode, ToSmolStr, ast}; @@ -83,6 +83,7 @@ use crate::{ item_tree::TreeId, nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, per_ns::PerNs, + unstable_features::UnstableFeatures, visibility::{Visibility, VisibilityExplicitness}, }; @@ -216,7 +217,7 @@ struct DefMapCrateData { /// Custom tool modules registered with `#![register_tool]`. registered_tools: Vec<Symbol>, /// Unstable features of Rust enabled with `#![feature(A, B)]`. - unstable_features: FxHashSet<Symbol>, + unstable_features: UnstableFeatures, /// `#[rustc_coherence_is_core]` rustc_coherence_is_core: bool, no_core: bool, @@ -233,7 +234,7 @@ impl DefMapCrateData { fn_proc_macro_mapping: FxHashMap::default(), fn_proc_macro_mapping_back: FxHashMap::default(), registered_tools: PREDEFINED_TOOLS.iter().map(|it| Symbol::intern(it)).collect(), - unstable_features: FxHashSet::default(), + unstable_features: UnstableFeatures::default(), rustc_coherence_is_core: false, no_core: false, no_std: false, @@ -554,8 +555,9 @@ impl DefMap { &self.data.registered_tools } - pub fn is_unstable_feature_enabled(&self, feature: &Symbol) -> bool { - self.data.unstable_features.contains(feature) + #[inline] + pub fn features(&self) -> &UnstableFeatures { + &self.data.unstable_features } pub fn is_rustc_coherence_is_core(&self) -> bool { diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 703f070dba..5ef51dbb2c 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -316,7 +316,7 @@ impl<'db> DefCollector<'db> { _ => None, }, ); - crate_data.unstable_features.extend(features); + features.for_each(|feature| crate_data.unstable_features.enable(feature)); } () if *attr_name == sym::register_tool => { if let Some(ident) = attr.single_ident_value() { @@ -2840,6 +2840,6 @@ foo!(KABOOM); assert_eq!(def_map.recursion_limit(), 4); assert!(def_map.is_no_core()); assert!(def_map.is_no_std()); - assert!(def_map.is_unstable_feature_enabled(&sym::register_tool)); + assert!(def_map.features().is_enabled(&sym::register_tool)); } } 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, +} diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index bc3d9bbec6..5ed7eb7a66 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -4,9 +4,8 @@ use std::{cell::LazyCell, fmt}; use hir_def::{ EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId, attrs::AttrFlags, - signatures::VariantFields, + signatures::VariantFields, unstable_features::UnstableFeatures, }; -use intern::sym; use rustc_pattern_analysis::{ IndexVec, PatCx, PrivateUninhabitedField, constructor::{Constructor, ConstructorSet, VariantVisibility}, @@ -82,8 +81,7 @@ pub(crate) struct MatchCheckCtx<'a, 'db> { impl<'a, 'db> MatchCheckCtx<'a, 'db> { pub(crate) fn new(module: ModuleId, infcx: &'a InferCtxt<'db>, env: ParamEnv<'db>) -> Self { let db = infcx.interner.db; - let def_map = module.crate_def_map(db); - let exhaustive_patterns = def_map.is_unstable_feature_enabled(&sym::exhaustive_patterns); + let exhaustive_patterns = UnstableFeatures::query(db, module.krate(db)).exhaustive_patterns; Self { module, db, exhaustive_patterns, env, infcx } } diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index ba63343d49..ee7527446a 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -6,8 +6,8 @@ use hir_def::{ AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, hir::generics::{GenericParams, LocalTypeOrConstParamId}, - nameres::crate_def_map, signatures::{FunctionSignature, TraitFlags, TraitSignature}, + unstable_features::UnstableFeatures, }; use rustc_hash::FxHashSet; use rustc_type_ir::{ @@ -111,8 +111,9 @@ where // rustc checks for non-lifetime binders here, but we don't support HRTB yet let trait_data = trait_.trait_items(db); + let mut features = None; for (_, assoc_item) in &trait_data.items { - dyn_compatibility_violation_for_assoc_item(db, trait_, *assoc_item, cb)?; + dyn_compatibility_violation_for_assoc_item(db, &mut features, trait_, *assoc_item, cb)?; } ControlFlow::Continue(()) @@ -274,8 +275,9 @@ fn contains_illegal_self_type_reference<'db, T: rustc_type_ir::TypeVisitable<DbI t.visit_with(&mut visitor).is_break() } -fn dyn_compatibility_violation_for_assoc_item<F>( - db: &dyn HirDatabase, +fn dyn_compatibility_violation_for_assoc_item<'db, F>( + db: &'db dyn HirDatabase, + features: &mut Option<&'db UnstableFeatures>, trait_: TraitId, item: AssocItemId, cb: &mut F, @@ -297,8 +299,10 @@ where }) } AssocItemId::TypeAliasId(it) => { - let def_map = crate_def_map(db, trait_.krate(db)); - if def_map.is_unstable_feature_enabled(&intern::sym::generic_associated_type_extended) { + if features + .get_or_insert_with(|| UnstableFeatures::query(db, trait_.krate(db))) + .generic_associated_type_extended + { ControlFlow::Continue(()) } else { let generic_params = GenericParams::of(db, item.into()); diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 339ce7933a..9acd5c0e0f 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -44,6 +44,7 @@ use hir_def::{ resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, type_ref::{ConstRef, LifetimeRefId, TypeRef, TypeRefId}, + unstable_features::UnstableFeatures, }; use hir_expand::{mod_path::ModPath, name::Name}; use indexmap::IndexSet; @@ -78,7 +79,7 @@ use crate::{ lower::{ ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic, }, - method_resolution::{CandidateId, MethodResolutionUnstableFeatures}, + method_resolution::CandidateId, next_solver::{ AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, StoredGenericArgs, StoredTy, StoredTys, Ty, TyKind, Tys, @@ -1112,11 +1113,11 @@ pub(crate) struct InferenceContext<'body, 'db> { /// and resolve the path via its methods. This will ensure proper error reporting. pub(crate) resolver: Resolver<'db>, target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>, - pub(crate) unstable_features: MethodResolutionUnstableFeatures, pub(crate) edition: Edition, pub(crate) generic_def: GenericDefId, pub(crate) table: unify::InferenceTable<'db>, pub(crate) lang_items: &'db LangItems, + pub(crate) features: &'db UnstableFeatures, /// The traits in scope, disregarding block modules. This is used for caching purposes. traits_in_scope: FxHashSet<TraitId>, pub(crate) result: InferenceResult, @@ -1218,10 +1219,8 @@ impl<'body, 'db> InferenceContext<'body, 'db> { return_ty: types.types.error, // set in collect_* calls types, target_features: OnceCell::new(), - unstable_features: MethodResolutionUnstableFeatures::from_def_map( - resolver.top_level_def_map(), - ), lang_items: table.interner().lang_items(), + features: resolver.top_level_def_map().features(), edition: resolver.krate().data(db).edition, table, tuple_field_accesses_rev: Default::default(), @@ -2317,7 +2316,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } fn has_new_range_feature(&self) -> bool { - self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range) + self.features.new_range } fn resolve_range(&self) -> Option<AdtId> { diff --git a/crates/hir-ty/src/infer/fallback.rs b/crates/hir-ty/src/infer/fallback.rs index c7669b346f..160749591d 100644 --- a/crates/hir-ty/src/infer/fallback.rs +++ b/crates/hir-ty/src/infer/fallback.rs @@ -1,6 +1,5 @@ //! Fallback of infer vars to `!` and `i32`/`f64`. -use intern::sym; use petgraph::{ Graph, visit::{Dfs, Walker}, @@ -80,7 +79,7 @@ impl<'db> InferenceContext<'_, 'db> { return DivergingFallbackBehavior::ToNever; } - if self.resolver.def_map().is_unstable_feature_enabled(&sym::never_type_fallback) { + if self.features.never_type_fallback { return DivergingFallbackBehavior::ContextDependent; } diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 68c4833d81..25c2df0d9f 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -23,8 +23,9 @@ use hir_def::{ nameres::{DefMap, block_def_map, crate_def_map}, resolver::Resolver, signatures::{ConstSignature, FunctionSignature}, + unstable_features::UnstableFeatures, }; -use intern::{Symbol, sym}; +use intern::Symbol; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ TypeVisitableExt, @@ -57,32 +58,13 @@ pub use self::probe::{ Candidate, CandidateKind, CandidateStep, CandidateWithPrivate, Mode, Pick, PickKind, }; -#[derive(Debug, Clone)] -pub struct MethodResolutionUnstableFeatures { - arbitrary_self_types: bool, - arbitrary_self_types_pointers: bool, - supertrait_item_shadowing: bool, -} - -impl MethodResolutionUnstableFeatures { - pub fn from_def_map(def_map: &DefMap) -> Self { - Self { - arbitrary_self_types: def_map.is_unstable_feature_enabled(&sym::arbitrary_self_types), - arbitrary_self_types_pointers: def_map - .is_unstable_feature_enabled(&sym::arbitrary_self_types_pointers), - supertrait_item_shadowing: def_map - .is_unstable_feature_enabled(&sym::supertrait_item_shadowing), - } - } -} - pub struct MethodResolutionContext<'a, 'db> { pub infcx: &'a InferCtxt<'db>, pub resolver: &'a Resolver<'db>, pub param_env: ParamEnv<'db>, pub traits_in_scope: &'a FxHashSet<TraitId>, pub edition: Edition, - pub unstable_features: &'a MethodResolutionUnstableFeatures, + pub features: &'a UnstableFeatures, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)] @@ -201,7 +183,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { param_env: self.table.param_env, traits_in_scope, edition: self.edition, - unstable_features: &self.unstable_features, + features: self.features, }; f(&ctx) } diff --git a/crates/hir-ty/src/method_resolution/confirm.rs b/crates/hir-ty/src/method_resolution/confirm.rs index 94c70c29f7..3bdef44dd3 100644 --- a/crates/hir-ty/src/method_resolution/confirm.rs +++ b/crates/hir-ty/src/method_resolution/confirm.rs @@ -320,8 +320,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { // We don't need to gate this behind arbitrary self types // per se, but it does make things a bit more gated. - if self.ctx.unstable_features.arbitrary_self_types - || self.ctx.unstable_features.arbitrary_self_types_pointers + if self.ctx.features.arbitrary_self_types || self.ctx.features.arbitrary_self_types_pointers { autoderef = autoderef.use_receiver_trait(); } @@ -483,7 +482,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { self.ctx.table.register_infer_ok(infer_ok); } Err(_) => { - if self.ctx.unstable_features.arbitrary_self_types { + if self.ctx.features.arbitrary_self_types { self.ctx.result.type_mismatches.get_or_insert_default().insert( self.expr.into(), TypeMismatch { expected: method_self_ty.store(), actual: self_ty.store() }, diff --git a/crates/hir-ty/src/method_resolution/probe.rs b/crates/hir-ty/src/method_resolution/probe.rs index 3604076ccd..afdc62183e 100644 --- a/crates/hir-ty/src/method_resolution/probe.rs +++ b/crates/hir-ty/src/method_resolution/probe.rs @@ -315,7 +315,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { // ambiguous. if let Some(bad_ty) = &steps.opt_bad_ty { if bad_ty.reached_raw_pointer - && !self.unstable_features.arbitrary_self_types_pointers + && !self.features.arbitrary_self_types_pointers && self.edition.at_least_2018() { // this case used to be allowed by the compiler, @@ -404,8 +404,8 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { Autoderef::new(infcx, self.param_env, self_ty).include_raw_pointers(); let mut reached_raw_pointer = false; - let arbitrary_self_types_enabled = self.unstable_features.arbitrary_self_types - || self.unstable_features.arbitrary_self_types_pointers; + let arbitrary_self_types_enabled = + self.features.arbitrary_self_types || self.features.arbitrary_self_types_pointers; let (mut steps, reached_recursion_limit) = if arbitrary_self_types_enabled { let reachable_via_deref = autoderef_via_deref.by_ref().map(|_| true).chain(std::iter::repeat(false)); @@ -613,7 +613,7 @@ impl<'db> ProbeChoice<'db> for ProbeForNameChoice<'db> { // We collapse to a subtrait pick *after* filtering unstable candidates // to make sure we don't prefer a unstable subtrait method over a stable // supertrait method. - if this.ctx.unstable_features.supertrait_item_shadowing + if this.ctx.features.supertrait_item_shadowing && let Some(pick) = this.collapse_candidates_to_subtrait_pick(self_ty, &applicable_candidates) { @@ -1183,8 +1183,8 @@ impl<'a, 'db> ProbeContext<'a, 'db, ProbeForNameChoice<'db>> { // The errors emitted by this function are part of // the arbitrary self types work, and should not impact // other users. - if !self.ctx.unstable_features.arbitrary_self_types - && !self.ctx.unstable_features.arbitrary_self_types_pointers + if !self.ctx.features.arbitrary_self_types + && !self.ctx.features.arbitrary_self_types_pointers { return Ok(()); } diff --git a/crates/hir-ty/src/specialization.rs b/crates/hir-ty/src/specialization.rs index 8bc6c51fae..a0bac48250 100644 --- a/crates/hir-ty/src/specialization.rs +++ b/crates/hir-ty/src/specialization.rs @@ -1,10 +1,9 @@ //! Impl specialization related things use hir_def::{ - ExpressionStoreOwnerId, GenericDefId, HasModule, ImplId, nameres::crate_def_map, - signatures::ImplSignature, + ExpressionStoreOwnerId, GenericDefId, HasModule, ImplId, signatures::ImplSignature, + unstable_features::UnstableFeatures, }; -use intern::sym; use tracing::debug; use crate::{ @@ -153,10 +152,8 @@ pub(crate) fn specializes( // `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]` // is an internal feature, std is not using it for specialization nor is likely to // ever use it, and we don't have the span information necessary to replicate that. - let def_map = crate_def_map(db, module.krate(db)); - if !def_map.is_unstable_feature_enabled(&sym::specialization) - && !def_map.is_unstable_feature_enabled(&sym::min_specialization) - { + let features = UnstableFeatures::query(db, module.krate(db)); + if !features.specialization && !features.min_specialization { return false; } diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 223103b6e5..9943b718fd 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -18,9 +18,7 @@ use hir_expand::{ }; use hir_ty::{ db::HirDatabase, - method_resolution::{ - self, CandidateId, MethodError, MethodResolutionContext, MethodResolutionUnstableFeatures, - }, + method_resolution::{self, CandidateId, MethodError, MethodResolutionContext}, next_solver::{DbInterner, TypingMode, infer::DbInternerInferExt}, }; use intern::Symbol; @@ -498,15 +496,14 @@ fn resolve_impl_trait_item<'db>( // FIXME: resolve type aliases (which are not yielded by iterate_path_candidates) let interner = DbInterner::new_with(db, environment.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); - let unstable_features = - MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map()); + let features = resolver.top_level_def_map().features(); let ctx = MethodResolutionContext { infcx: &infcx, resolver: &resolver, param_env: environment.param_env, traits_in_scope: &traits_in_scope, edition: krate.edition(db), - unstable_features: &unstable_features, + features, }; let resolution = ctx.probe_for_name(method_resolution::Mode::Path, name.clone(), ty.ty); let resolution = match resolution { diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index ebcc1da43d..91b48bbfb6 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -75,6 +75,7 @@ use hir_def::{ TypeAliasSignature, UnionSignature, VariantFields, }, src::HasSource as _, + unstable_features::UnstableFeatures, visibility::visibility_from_ast, }; use hir_expand::{ @@ -89,9 +90,7 @@ use hir_ty::{ diagnostics::BodyValidationDiagnostic, direct_super_traits, known_const_to_ast, layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding}, - method_resolution::{ - self, InherentImpls, MethodResolutionContext, MethodResolutionUnstableFeatures, - }, + method_resolution::{self, InherentImpls, MethodResolutionContext}, mir::interpret_mir, next_solver::{ AliasTy, AnyImplId, ClauseKind, ConstKind, DbInterner, EarlyBinder, EarlyParamRegion, @@ -343,7 +342,7 @@ impl Crate { } pub fn is_unstable_feature_enabled(self, db: &dyn HirDatabase, feature: &Symbol) -> bool { - crate_def_map(db, self.id).is_unstable_feature_enabled(feature) + UnstableFeatures::query(db, self.id).is_enabled(feature) } } @@ -983,10 +982,8 @@ impl Module { // relationship here would be significantly more expensive. if !missing.is_empty() { let krate = self.krate(db).id; - let def_map = crate_def_map(db, krate); - if def_map.is_unstable_feature_enabled(&sym::specialization) - || def_map.is_unstable_feature_enabled(&sym::min_specialization) - { + let features = UnstableFeatures::query(db, krate); + if features.specialization || features.min_specialization { missing.retain(|(assoc_name, assoc_item)| { let AssocItem::Function(_) = assoc_item else { return true; @@ -6177,8 +6174,7 @@ impl<'db> Type<'db> { TypingMode::non_body_analysis() }; let infcx = interner.infer_ctxt().build(typing_mode); - let unstable_features = - MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map()); + let features = resolver.top_level_def_map().features(); let environment = param_env_from_resolver(db, resolver); let ctx = MethodResolutionContext { infcx: &infcx, @@ -6186,7 +6182,7 @@ impl<'db> Type<'db> { param_env: environment.param_env, traits_in_scope, edition: resolver.krate().data(db).edition, - unstable_features: &unstable_features, + features, }; f(&ctx) } diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 6c43f80ce8..bbe1e670de 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -626,8 +626,7 @@ impl<'db> SourceAnalyzer<'db> { has_start: bool, has_end: bool, ) -> Option<StructId> { - let has_new_range = - self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range); + let has_new_range = self.resolver.top_level_def_map().features().new_range; let lang_items = self.lang_items(db); match (op_kind, has_start, has_end) { (RangeOp::Exclusive, false, false) => lang_items.RangeFull, |