mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Record enabled unstable features into DefMap
This commit is contained in:
parent
1fa9d5e07b
commit
8ae58b9fe4
4 changed files with 27 additions and 18 deletions
|
@ -64,7 +64,7 @@ use hir_expand::{name::Name, InFile, MacroCallId, MacroDefId};
|
|||
use itertools::Itertools;
|
||||
use la_arena::Arena;
|
||||
use profile::Count;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use stdx::format_to;
|
||||
use syntax::{ast, SmolStr};
|
||||
|
||||
|
@ -114,6 +114,8 @@ pub struct DefMap {
|
|||
registered_attrs: Vec<SmolStr>,
|
||||
/// Custom tool modules registered with `#![register_tool]`.
|
||||
registered_tools: Vec<SmolStr>,
|
||||
/// Unstable features of Rust enabled with `#![feature(A, B)]`.
|
||||
unstable_features: FxHashSet<SmolStr>,
|
||||
|
||||
edition: Edition,
|
||||
recursion_limit: Option<u32>,
|
||||
|
@ -284,6 +286,7 @@ impl DefMap {
|
|||
modules,
|
||||
registered_attrs: Vec::new(),
|
||||
registered_tools: Vec::new(),
|
||||
unstable_features: FxHashSet::default(),
|
||||
diagnostics: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -314,6 +317,10 @@ impl DefMap {
|
|||
&self.registered_attrs
|
||||
}
|
||||
|
||||
pub fn is_unstable_feature_enabled(&self, feature: &str) -> bool {
|
||||
self.unstable_features.contains(feature)
|
||||
}
|
||||
|
||||
pub fn root(&self) -> LocalModuleId {
|
||||
self.root
|
||||
}
|
||||
|
@ -483,6 +490,7 @@ impl DefMap {
|
|||
registered_tools,
|
||||
fn_proc_macro_mapping,
|
||||
derive_helpers_in_scope,
|
||||
unstable_features,
|
||||
proc_macro_loading_error: _,
|
||||
block: _,
|
||||
edition: _,
|
||||
|
@ -500,6 +508,7 @@ impl DefMap {
|
|||
registered_tools.shrink_to_fit();
|
||||
fn_proc_macro_mapping.shrink_to_fit();
|
||||
derive_helpers_in_scope.shrink_to_fit();
|
||||
unstable_features.shrink_to_fit();
|
||||
for (_, module) in modules.iter_mut() {
|
||||
module.children.shrink_to_fit();
|
||||
module.scope.shrink_to_fit();
|
||||
|
|
|
@ -294,6 +294,17 @@ impl DefCollector<'_> {
|
|||
continue;
|
||||
}
|
||||
|
||||
if *attr_name == hir_expand::name![feature] {
|
||||
let features =
|
||||
attr.parse_path_comma_token_tree().into_iter().flatten().filter_map(
|
||||
|feat| match feat.segments() {
|
||||
[name] => Some(name.to_smol_str()),
|
||||
_ => None,
|
||||
},
|
||||
);
|
||||
self.def_map.unstable_features.extend(features);
|
||||
}
|
||||
|
||||
let attr_is_register_like = *attr_name == hir_expand::name![register_attr]
|
||||
|| *attr_name == hir_expand::name![register_tool];
|
||||
if !attr_is_register_like {
|
||||
|
|
|
@ -336,6 +336,7 @@ pub mod known {
|
|||
test,
|
||||
test_case,
|
||||
recursion_limit,
|
||||
feature,
|
||||
// Safe intrinsics
|
||||
abort,
|
||||
add_with_overflow,
|
||||
|
|
|
@ -274,7 +274,6 @@
|
|||
use std::iter::once;
|
||||
|
||||
use hir_def::{AdtId, DefWithBodyId, HasModule, ModuleId};
|
||||
use once_cell::unsync::OnceCell;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use typed_arena::Arena;
|
||||
|
||||
|
@ -290,7 +289,7 @@ pub(crate) struct MatchCheckCtx<'a, 'p> {
|
|||
pub(crate) db: &'a dyn HirDatabase,
|
||||
/// Lowered patterns from arms plus generated by the check.
|
||||
pub(crate) pattern_arena: &'p Arena<DeconstructedPat<'p>>,
|
||||
feature_exhaustive_patterns: OnceCell<bool>,
|
||||
exhaustive_patterns: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'p> MatchCheckCtx<'a, 'p> {
|
||||
|
@ -300,7 +299,9 @@ impl<'a, 'p> MatchCheckCtx<'a, 'p> {
|
|||
db: &'a dyn HirDatabase,
|
||||
pattern_arena: &'p Arena<DeconstructedPat<'p>>,
|
||||
) -> Self {
|
||||
Self { module, body, db, pattern_arena, feature_exhaustive_patterns: Default::default() }
|
||||
let def_map = db.crate_def_map(module.krate());
|
||||
let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns");
|
||||
Self { module, body, db, pattern_arena, exhaustive_patterns }
|
||||
}
|
||||
|
||||
pub(super) fn is_uninhabited(&self, ty: &Ty) -> bool {
|
||||
|
@ -326,20 +327,7 @@ impl<'a, 'p> MatchCheckCtx<'a, 'p> {
|
|||
|
||||
// Rust's unstable feature described as "Allows exhaustive pattern matching on types that contain uninhabited types."
|
||||
pub(super) fn feature_exhaustive_patterns(&self) -> bool {
|
||||
*self.feature_exhaustive_patterns.get_or_init(|| {
|
||||
let def_map = self.db.crate_def_map(self.module.krate());
|
||||
let root_mod = def_map.module_id(def_map.root());
|
||||
let rood_attrs = self.db.attrs(root_mod.into());
|
||||
let mut nightly_features = rood_attrs
|
||||
.by_key("feature")
|
||||
.attrs()
|
||||
.map(|attr| attr.parse_path_comma_token_tree())
|
||||
.flatten()
|
||||
.flatten();
|
||||
nightly_features.any(
|
||||
|feat| matches!(feat.segments(), [name] if name.to_smol_str() == "exhaustive_patterns"),
|
||||
)
|
||||
})
|
||||
self.exhaustive_patterns
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue