diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2025-01-27 07:54:44 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-27 07:54:44 +0000 |
| commit | 1711a19dbff28d81e6c6df7503973a545ed74381 (patch) | |
| tree | 769ea99829a39649dda0c4324ec705c97a5d1db7 | |
| parent | 6db1411ae090608150cf545cf18151d316e6fb99 (diff) | |
| parent | bdebd866fb0469c1955cd9ec2fb0e7094d0a37d4 (diff) | |
| download | rust-1711a19dbff28d81e6c6df7503973a545ed74381.tar.gz rust-1711a19dbff28d81e6c6df7503973a545ed74381.zip | |
Merge pull request #19036 from Veykril/push-nprltlwvryxw
Split out `ExpressionStore` from `Body`
38 files changed, 645 insertions, 526 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index bf6cc1dcade..598a850898b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -10,12 +10,12 @@ use triomphe::Arc; use crate::{ attr::{Attrs, AttrsWithOwner}, - body::{scope::ExprScopes, Body, BodySourceMap}, data::{ adt::{EnumData, EnumVariantData, StructData, VariantData}, ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData, ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData, }, + expr_store::{scope::ExprScopes, Body, BodySourceMap}, generics::GenericParams, import_map::ImportMap, item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps}, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index de439249306..9df6eaade75 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs @@ -1,18 +1,19 @@ -//! Defines `Body`: a lowered representation of bodies of functions, statics and +//! Defines `ExpressionStore`: a lowered representation of functions, statics and //! consts. +mod body; mod lower; mod pretty; pub mod scope; + #[cfg(test)] mod tests; use std::ops::{Deref, Index}; -use base_db::CrateId; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{name::Name, ExpandError, InFile}; -use la_arena::{Arena, ArenaMap, Idx, RawIdx}; +use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::{Edition, MacroFileId, SyntaxContextData}; @@ -22,19 +23,18 @@ use tt::TextRange; use crate::{ db::DefDatabase, - expander::Expander, hir::{ - dummy_expr_id, Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, - LabelId, Pat, PatId, RecordFieldPat, Statement, + Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat, + PatId, RecordFieldPat, Statement, }, - item_tree::AttrOwner, nameres::DefMap, path::{ModPath, Path}, - src::HasSource, type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap}, - BlockId, DefWithBodyId, HasModule, Lookup, SyntheticSyntax, + BlockId, DefWithBodyId, Lookup, SyntheticSyntax, }; +pub use self::body::{Body, BodySourceMap}; + /// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct HygieneId(span::SyntaxContextId); @@ -58,9 +58,29 @@ impl HygieneId { } } -/// The body of an item (function, const etc.). +pub type ExprPtr = AstPtr<ast::Expr>; +pub type ExprSource = InFile<ExprPtr>; + +pub type PatPtr = AstPtr<ast::Pat>; +pub type PatSource = InFile<PatPtr>; + +pub type LabelPtr = AstPtr<ast::Label>; +pub type LabelSource = InFile<LabelPtr>; + +pub type FieldPtr = AstPtr<ast::RecordExprField>; +pub type FieldSource = InFile<FieldPtr>; + +pub type PatFieldPtr = AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>; +pub type PatFieldSource = InFile<PatFieldPtr>; + +pub type ExprOrPatPtr = AstPtr<Either<ast::Expr, ast::Pat>>; +pub type ExprOrPatSource = InFile<ExprOrPatPtr>; + +pub type SelfParamPtr = AstPtr<ast::SelfParam>; +pub type MacroCallPtr = AstPtr<ast::MacroCall>; + #[derive(Debug, Eq, PartialEq)] -pub struct Body { +pub struct ExpressionStore { pub exprs: Arena<Expr>, pub pats: Arena<Pat>, pub bindings: Arena<Binding>, @@ -68,19 +88,9 @@ pub struct Body { /// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the /// top level expression, it will not be listed in here. pub binding_owners: FxHashMap<BindingId, ExprId>, - /// The patterns for the function's parameters. While the parameter types are - /// part of the function signature, the patterns are not (they don't change - /// the external type of the function). - /// - /// If this `Body` is for the body of a constant, this will just be - /// empty. - pub params: Box<[PatId]>, - pub self_param: Option<BindingId>, - /// The `ExprId` of the actual body expression. - pub body_expr: ExprId, pub types: TypesMap, - /// Block expressions in this body that may contain inner items. - block_scopes: Vec<BlockId>, + /// Block expressions in this store that may contain inner items. + block_scopes: Box<[BlockId]>, /// A map from binding to its hygiene ID. /// @@ -92,44 +102,13 @@ pub struct Body { binding_hygiene: FxHashMap<BindingId, HygieneId>, /// A map from an variable usages to their hygiene ID. /// - /// Expressions that can be recorded here are single segment path, although not all single segments path refer + /// Expressions (and destructuing patterns) that can be recorded here are single segment path, although not all single segments path refer /// to variables and have hygiene (some refer to items, we don't know at this stage). - expr_hygiene: FxHashMap<ExprId, HygieneId>, - /// A map from a destructuring assignment possible variable usages to their hygiene ID. - pat_hygiene: FxHashMap<PatId, HygieneId>, + ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, } -pub type ExprPtr = AstPtr<ast::Expr>; -pub type ExprSource = InFile<ExprPtr>; - -pub type PatPtr = AstPtr<ast::Pat>; -pub type PatSource = InFile<PatPtr>; - -pub type LabelPtr = AstPtr<ast::Label>; -pub type LabelSource = InFile<LabelPtr>; - -pub type FieldPtr = AstPtr<ast::RecordExprField>; -pub type FieldSource = InFile<FieldPtr>; - -pub type PatFieldPtr = AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>; -pub type PatFieldSource = InFile<PatFieldPtr>; - -pub type ExprOrPatPtr = AstPtr<Either<ast::Expr, ast::Pat>>; -pub type ExprOrPatSource = InFile<ExprOrPatPtr>; - -/// An item body together with the mapping from syntax nodes to HIR expression -/// IDs. This is needed to go from e.g. a position in a file to the HIR -/// expression containing it; but for type inference etc., we want to operate on -/// a structure that is agnostic to the actual positions of expressions in the -/// file, so that we don't recompute types whenever some whitespace is typed. -/// -/// One complication here is that, due to macro expansion, a single `Body` might -/// be spread across several files. So, for each ExprId and PatId, we record -/// both the HirFileId and the position inside the file. However, we only store -/// AST -> ExprId mapping for non-macro files, as it is not clear how to handle -/// this properly for macros. -#[derive(Default, Debug, Eq, PartialEq)] -pub struct BodySourceMap { +#[derive(Debug, Eq, PartialEq, Default)] +pub struct ExpressionStoreSourceMap { // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected). expr_map: FxHashMap<ExprSource, ExprOrPatId>, @@ -141,7 +120,6 @@ pub struct BodySourceMap { label_map: FxHashMap<LabelSource, LabelId>, label_map_back: ArenaMap<LabelId, LabelSource>, - self_param: Option<InFile<AstPtr<ast::SelfParam>>>, binding_definitions: FxHashMap<BindingId, SmallVec<[PatId; 4]>>, /// We don't create explicit nodes for record fields (`S { record_field: 92 }`). @@ -153,11 +131,25 @@ pub struct BodySourceMap { template_map: Option<Box<FormatTemplate>>, - expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>, + expansions: FxHashMap<InFile<MacroCallPtr>, MacroFileId>, - /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in + /// Diagnostics accumulated during lowering. These contain `AstPtr`s and so are stored in /// the source map (since they're just as volatile). - diagnostics: Vec<BodyDiagnostic>, + diagnostics: Vec<ExpressionStoreDiagnostics>, +} + +/// The body of an item (function, const etc.). +#[derive(Debug, Eq, PartialEq, Default)] +pub struct ExpressionStoreBuilder { + pub exprs: Arena<Expr>, + pub pats: Arena<Pat>, + pub bindings: Arena<Binding>, + pub labels: Arena<Label>, + pub binding_owners: FxHashMap<BindingId, ExprId>, + pub types: TypesMap, + block_scopes: Vec<BlockId>, + binding_hygiene: FxHashMap<BindingId, HygieneId>, + ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, } #[derive(Default, Debug, Eq, PartialEq)] @@ -171,166 +163,62 @@ struct FormatTemplate { /// The value stored for each capture is its template literal and offset inside it. The template literal /// is from the `format_args[_nl]!()` macro and so needs to be mapped up once to go to the user-written /// template. - implicit_capture_to_source: FxHashMap<ExprId, InFile<(AstPtr<ast::Expr>, TextRange)>>, + implicit_capture_to_source: FxHashMap<ExprId, InFile<(ExprPtr, TextRange)>>, } #[derive(Debug, Eq, PartialEq)] -pub enum BodyDiagnostic { +pub enum ExpressionStoreDiagnostics { InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions }, - MacroError { node: InFile<AstPtr<ast::MacroCall>>, err: ExpandError }, - UnresolvedMacroCall { node: InFile<AstPtr<ast::MacroCall>>, path: ModPath }, + MacroError { node: InFile<MacroCallPtr>, err: ExpandError }, + UnresolvedMacroCall { node: InFile<MacroCallPtr>, path: ModPath }, UnreachableLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name }, AwaitOutsideOfAsync { node: InFile<AstPtr<ast::AwaitExpr>>, location: String }, UndeclaredLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name }, } -impl Body { - pub(crate) fn body_with_source_map_query( - db: &dyn DefDatabase, - def: DefWithBodyId, - ) -> (Arc<Body>, Arc<BodySourceMap>) { - let _p = tracing::info_span!("body_with_source_map_query").entered(); - let mut params = None; - - let mut is_async_fn = false; - let InFile { file_id, value: body } = { - match def { - DefWithBodyId::FunctionId(f) => { - let data = db.function_data(f); - let f = f.lookup(db); - let src = f.source(db); - params = src.value.param_list().map(move |param_list| { - let item_tree = f.id.item_tree(db); - let func = &item_tree[f.id.value]; - let krate = f.container.module(db).krate; - let crate_graph = db.crate_graph(); - ( - param_list, - (0..func.params.len()).map(move |idx| { - item_tree - .attrs( - db, - krate, - AttrOwner::Param( - f.id.value, - Idx::from_raw(RawIdx::from(idx as u32)), - ), - ) - .is_cfg_enabled(&crate_graph[krate].cfg_options) - }), - ) - }); - is_async_fn = data.is_async(); - src.map(|it| it.body().map(ast::Expr::from)) - } - DefWithBodyId::ConstId(c) => { - let c = c.lookup(db); - let src = c.source(db); - src.map(|it| it.body()) - } - DefWithBodyId::StaticId(s) => { - let s = s.lookup(db); - let src = s.source(db); - src.map(|it| it.body()) - } - DefWithBodyId::VariantId(v) => { - let s = v.lookup(db); - let src = s.source(db); - src.map(|it| it.expr()) - } - DefWithBodyId::InTypeConstId(c) => c.lookup(db).id.map(|_| c.source(db).expr()), - } - }; - let module = def.module(db); - let expander = Expander::new(db, file_id, module); - let (mut body, mut source_map) = - Body::new(db, def, expander, params, body, module.krate, is_async_fn); - body.shrink_to_fit(); - source_map.shrink_to_fit(); - - (Arc::new(body), Arc::new(source_map)) - } - - pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> { - db.body_with_source_map(def).0 - } - - /// Returns an iterator over all block expressions in this body that define inner items. - pub fn blocks<'a>( - &'a self, - db: &'a dyn DefDatabase, - ) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + 'a { - self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block))) - } - - pub fn pretty_print( - &self, - db: &dyn DefDatabase, - owner: DefWithBodyId, - edition: Edition, - ) -> String { - pretty::print_body_hir(db, self, owner, edition) - } - - pub fn pretty_print_expr( - &self, - db: &dyn DefDatabase, - owner: DefWithBodyId, - expr: ExprId, - edition: Edition, - ) -> String { - pretty::print_expr_hir(db, self, owner, expr, edition) - } - - pub fn pretty_print_pat( - &self, - db: &dyn DefDatabase, - owner: DefWithBodyId, - pat: PatId, - oneline: bool, - edition: Edition, - ) -> String { - pretty::print_pat_hir(db, self, owner, pat, oneline, edition) - } - - fn new( - db: &dyn DefDatabase, - owner: DefWithBodyId, - expander: Expander, - params: Option<(ast::ParamList, impl Iterator<Item = bool>)>, - body: Option<ast::Expr>, - krate: CrateId, - is_async_fn: bool, - ) -> (Body, BodySourceMap) { - lower::lower(db, owner, expander, params, body, krate, is_async_fn) - } - - fn shrink_to_fit(&mut self) { +impl ExpressionStoreBuilder { + fn finish(self) -> ExpressionStore { let Self { - body_expr: _, - params: _, - self_param: _, block_scopes, - exprs, - labels, - pats, - bindings, - binding_owners, - binding_hygiene, - expr_hygiene, - pat_hygiene, - types, + mut exprs, + mut labels, + mut pats, + mut bindings, + mut binding_owners, + mut binding_hygiene, + mut ident_hygiene, + mut types, } = self; - block_scopes.shrink_to_fit(); exprs.shrink_to_fit(); labels.shrink_to_fit(); pats.shrink_to_fit(); bindings.shrink_to_fit(); binding_owners.shrink_to_fit(); binding_hygiene.shrink_to_fit(); - expr_hygiene.shrink_to_fit(); - pat_hygiene.shrink_to_fit(); + ident_hygiene.shrink_to_fit(); types.shrink_to_fit(); + + ExpressionStore { + exprs, + pats, + bindings, + labels, + binding_owners, + types, + block_scopes: block_scopes.into_boxed_slice(), + binding_hygiene, + ident_hygiene, + } + } +} + +impl ExpressionStore { + /// Returns an iterator over all block expressions in this store that define inner items. + pub fn blocks<'a>( + &'a self, + db: &'a dyn DefDatabase, + ) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + 'a { + self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block))) } pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) { @@ -658,11 +546,11 @@ impl Body { } pub fn expr_path_hygiene(&self, expr: ExprId) -> HygieneId { - self.expr_hygiene.get(&expr).copied().unwrap_or(HygieneId::ROOT) + self.ident_hygiene.get(&expr.into()).copied().unwrap_or(HygieneId::ROOT) } pub fn pat_path_hygiene(&self, pat: PatId) -> HygieneId { - self.pat_hygiene.get(&pat).copied().unwrap_or(HygieneId::ROOT) + self.ident_hygiene.get(&pat.into()).copied().unwrap_or(HygieneId::ROOT) } pub fn expr_or_pat_path_hygiene(&self, id: ExprOrPatId) -> HygieneId { @@ -673,27 +561,7 @@ impl Body { } } -impl Default for Body { - fn default() -> Self { - Self { - body_expr: dummy_expr_id(), - exprs: Default::default(), - pats: Default::default(), - bindings: Default::default(), - labels: Default::default(), - params: Default::default(), - block_scopes: Default::default(), - binding_owners: Default::default(), - self_param: Default::default(), - binding_hygiene: Default::default(), - expr_hygiene: Default::default(), - pat_hygiene: Default::default(), - types: Default::default(), - } - } -} - -impl Index<ExprId> for Body { +impl Index<ExprId> for ExpressionStore { type Output = Expr; fn index(&self, expr: ExprId) -> &Expr { @@ -701,7 +569,7 @@ impl Index<ExprId> for Body { } } -impl Index<PatId> for Body { +impl Index<PatId> for ExpressionStore { type Output = Pat; fn index(&self, pat: PatId) -> &Pat { @@ -709,7 +577,7 @@ impl Index<PatId> for Body { } } -impl Index<LabelId> for Body { +impl Index<LabelId> for ExpressionStore { type Output = Label; fn index(&self, label: LabelId) -> &Label { @@ -717,7 +585,7 @@ impl Index<LabelId> for Body { } } -impl Index<BindingId> for Body { +impl Index<BindingId> for ExpressionStore { type Output = Binding; fn index(&self, b: BindingId) -> &Binding { @@ -725,7 +593,7 @@ impl Index<BindingId> for Body { } } -impl Index<TypeRefId> for Body { +impl Index<TypeRefId> for ExpressionStore { type Output = TypeRef; fn index(&self, b: TypeRefId) -> &TypeRef { @@ -735,7 +603,7 @@ impl Index<TypeRefId> for Body { // FIXME: Change `node_` prefix to something more reasonable. // Perhaps `expr_syntax` and `expr_id`? -impl BodySourceMap { +impl ExpressionStoreSourceMap { pub fn expr_or_pat_syntax(&self, id: ExprOrPatId) -> Result<ExprOrPatSource, SyntheticSyntax> { match id { ExprOrPatId::ExprId(id) => self.expr_syntax(id).map(|it| it.map(AstPtr::wrap_left)), @@ -757,9 +625,7 @@ impl BodySourceMap { self.expansions.get(&src).cloned() } - pub fn macro_calls( - &self, - ) -> impl Iterator<Item = (InFile<AstPtr<ast::MacroCall>>, MacroFileId)> + '_ { + pub fn macro_calls(&self) -> impl Iterator<Item = (InFile<MacroCallPtr>, MacroFileId)> + '_ { self.expansions.iter().map(|(&a, &b)| (a, b)) } @@ -767,10 +633,6 @@ impl BodySourceMap { self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax) } - pub fn self_param_syntax(&self) -> Option<InFile<AstPtr<ast::SelfParam>>> { - self.self_param - } - pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> { self.pat_map.get(&node.map(AstPtr::new)).cloned() } @@ -801,9 +663,7 @@ impl BodySourceMap { self.expr_map.get(&src).copied() } - pub fn expansions( - &self, - ) -> impl Iterator<Item = (&InFile<AstPtr<ast::MacroCall>>, &MacroFileId)> { + pub fn expansions(&self) -> impl Iterator<Item = (&InFile<MacroCallPtr>, &MacroFileId)> { self.expansions.iter() } @@ -823,7 +683,7 @@ impl BodySourceMap { pub fn format_args_implicit_capture( &self, capture_expr: ExprId, - ) -> Option<InFile<(AstPtr<ast::Expr>, TextRange)>> { + ) -> Option<InFile<(ExprPtr, TextRange)>> { self.template_map.as_ref()?.implicit_capture_to_source.get(&capture_expr).copied() } @@ -837,14 +697,13 @@ impl BodySourceMap { .zip(self.template_map.as_ref()?.asm_to_captures.get(&expr).map(std::ops::Deref::deref)) } - /// Get a reference to the body source map's diagnostics. - pub fn diagnostics(&self) -> &[BodyDiagnostic] { + /// Get a reference to the source map's diagnostics. + pub fn diagnostics(&self) -> &[ExpressionStoreDiagnostics] { &self.diagnostics } fn shrink_to_fit(&mut self) { let Self { - self_param: _, expr_map, expr_map_back, pat_map, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs new file mode 100644 index 00000000000..a55fec4f8b1 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs @@ -0,0 +1,175 @@ +//! Defines `Body`: a lowered representation of functions, statics and +//! consts. +use std::ops; + +use hir_expand::{InFile, Lookup}; +use la_arena::{Idx, RawIdx}; +use span::Edition; +use syntax::ast; +use triomphe::Arc; + +use crate::{ + db::DefDatabase, + expander::Expander, + expr_store::{lower, pretty, ExpressionStore, ExpressionStoreSourceMap, SelfParamPtr}, + hir::{BindingId, ExprId, PatId}, + item_tree::AttrOwner, + src::HasSource, + DefWithBodyId, HasModule, +}; + +/// The body of an item (function, const etc.). +#[derive(Debug, Eq, PartialEq)] +pub struct Body { + pub store: ExpressionStore, + /// The patterns for the function's parameters. While the parameter types are + /// part of the function signature, the patterns are not (they don't change + /// the external type of the function). + /// + /// If this `Body` is for the body of a constant, this will just be + /// empty. + pub params: Box<[PatId]>, + pub self_param: Option<BindingId>, + /// The `ExprId` of the actual body expression. + pub body_expr: ExprId, +} + +impl ops::Deref for Body { + type Target = ExpressionStore; + + fn deref(&self) -> &Self::Target { + &self.store + } +} + +/// An item body together with the mapping from syntax nodes to HIR expression +/// IDs. This is needed to go from e.g. a position in a file to the HIR +/// expression containing it; but for type inference etc., we want to operate on +/// a structure that is agnostic to the actual positions of expressions in the +/// file, so that we don't recompute types whenever some whitespace is typed. +/// +/// One complication here is that, due to macro expansion, a single `Body` might +/// be spread across several files. So, for each ExprId and PatId, we record +/// both the HirFileId and the position inside the file. However, we only store +/// AST -> ExprId mapping for non-macro files, as it is not clear how to handle +/// this properly for macros. +#[derive(Default, Debug, Eq, PartialEq)] +pub struct BodySourceMap { + pub self_param: Option<InFile<SelfParamPtr>>, + pub store: ExpressionStoreSourceMap, +} + +impl ops::Deref for BodySourceMap { + type Target = ExpressionStoreSourceMap; + + fn deref(&self) -> &Self::Target { + &self.store + } +} + +impl Body { + pub(crate) fn body_with_source_map_query( + db: &dyn DefDatabase, + def: DefWithBodyId, + ) -> (Arc<Body>, Arc<BodySourceMap>) { + let _p = tracing::info_span!("body_with_source_map_query").entered(); + let mut params = None; + + let mut is_async_fn = false; + let InFile { file_id, value: body } = { + match def { + DefWithBodyId::FunctionId(f) => { + let data = db.function_data(f); + let f = f.lookup(db); + let src = f.source(db); + params = src.value.param_list().map(move |param_list| { + let item_tree = f.id.item_tree(db); + let func = &item_tree[f.id.value]; + let krate = f.container.module(db).krate; + let crate_graph = db.crate_graph(); + ( + param_list, + (0..func.params.len()).map(move |idx| { + item_tree + .attrs( + db, + krate, + AttrOwner::Param( + f.id.value, + Idx::from_raw(RawIdx::from(idx as u32)), + ), + ) + .is_cfg_enabled(&crate_graph[krate].cfg_options) + }), + ) + }); + is_async_fn = data.is_async(); + src.map(|it| it.body().map(ast::Expr::from)) + } + DefWithBodyId::ConstId(c) => { + let c = c.lookup(db); + let src = c.source(db); + src.map(|it| it.body()) + } + DefWithBodyId::StaticId(s) => { + let s = s.lookup(db); + let src = s.source(db); + src.map(|it| it.body()) + } + DefWithBodyId::VariantId(v) => { + let s = v.lookup(db); + let src = s.source(db); + src.map(|it| it.expr()) + } + DefWithBodyId::InTypeConstId(c) => c.lookup(db).id.map(|_| c.source(db).expr()), + } + }; + let module = def.module(db); + let expander = Expander::new(db, file_id, module); + let (body, mut source_map) = + lower::lower_body(db, def, expander, params, body, module.krate, is_async_fn); + source_map.store.shrink_to_fit(); + + (Arc::new(body), Arc::new(source_map)) + } + + pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> { + db.body_with_source_map(def).0 + } + + pub fn pretty_print( + &self, + db: &dyn DefDatabase, + owner: DefWithBodyId, + edition: Edition, + ) -> String { + pretty::print_body_hir(db, self, owner, edition) + } + + pub fn pretty_print_expr( + &self, + db: &dyn DefDatabase, + owner: DefWithBodyId, + expr: ExprId, + edition: Edition, + ) -> String { + pretty::print_expr_hir(db, self, owner, expr, edition) + } + + pub fn pretty_print_pat( + &self, + db: &dyn DefDatabase, + owner: DefWithBodyId, + pat: PatId, + oneline: bool, + edition: Edition, + ) -> String { + pretty::print_pat_hir(db, self, owner, pat, oneline, edition) + } +} + +impl BodySourceMap { + pub fn self_param_syntax(&self) -> Option<InFile<SelfParamPtr>> { + self.self_param + } +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 16c7b5ca00a..dfc716eb849 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -29,11 +29,14 @@ use triomphe::Arc; use crate::{ attr::Attrs, - body::{Body, BodyDiagnostic, BodySourceMap, ExprPtr, HygieneId, LabelPtr, PatPtr}, builtin_type::BuiltinUint, data::adt::StructKind, db::DefDatabase, expander::Expander, + expr_store::{ + Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder, + ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, PatPtr, + }, hir::{ format_args::{ self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind, @@ -55,11 +58,11 @@ use crate::{ type FxIndexSet<K> = indexmap::IndexSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>; -pub(super) fn lower( +pub(super) fn lower_body( db: &dyn DefDatabase, owner: DefWithBodyId, expander: Expander, - params: Option<(ast::ParamList, impl Iterator<Item = bool>)>, + parameters: Option<(ast::ParamList, impl Iterator<Item = bool>)>, body: Option<ast::Expr>, krate: CrateId, is_async_fn: bool, @@ -75,35 +78,146 @@ pub(super) fn lower( }; Arc::clone(span_map) }); - ExprCollector { - db, - owner, - krate, - def_map: expander.module.def_map(db), - source_map: BodySourceMap::default(), - ast_id_map: db.ast_id_map(expander.current_file_id()), - body: Body::default(), - expander, - current_try_block_label: None, - is_lowering_coroutine: false, - label_ribs: Vec::new(), - current_binding_owner: None, - awaitable_context: None, - current_span_map: span_map, - current_block_legacy_macro_defs_count: FxHashMap::default(), - } - .collect(params, body, is_async_fn) + + let mut self_param = None; + let mut source_map_self_param = None; + let mut params = vec![]; + let mut collector = ExprCollector::new(db, owner, expander, krate, span_map); + + let skip_body = match owner { + DefWithBodyId::FunctionId(it) => db.attrs(it.into()), + DefWithBodyId::StaticId(it) => db.attrs(it.into()), + DefWithBodyId::ConstId(it) => db.attrs(it.into()), + DefWithBodyId::InTypeConstId(_) => Attrs::EMPTY, + DefWithBodyId::VariantId(it) => db.attrs(it.into()), + } + .rust_analyzer_tool() + .any(|attr| *attr.path() == tool_path![skip]); + // If #[rust_analyzer::skip] annotated, only construct enough information for the signature + // and skip the body. + if skip_body { + if let Some((param_list, mut attr_enabled)) = parameters { + if let Some(self_param_syn) = + param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false)) + { + let is_mutable = + self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none(); + let binding_id: la_arena::Idx<Binding> = collector.alloc_binding( + Name::new_symbol_root(sym::self_.clone()), + BindingAnnotation::new(is_mutable, false), + ); + self_param = Some(binding_id); + source_map_self_param = + Some(collector.expander.in_file(AstPtr::new(&self_param_syn))); + } + params = param_list + .params() + .zip(attr_enabled) + .filter(|(_, enabled)| *enabled) + .map(|_| collector.missing_pat()) + .collect(); + }; + let body_expr = collector.missing_expr(); + return ( + Body { + store: collector.store.finish(), + params: params.into_boxed_slice(), + self_param, + body_expr, + }, + BodySourceMap { self_param: source_map_self_param, store: collector.source_map }, + ); + } + + if let Some((param_list, mut attr_enabled)) = parameters { + if let Some(self_param_syn) = + param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false)) + { + let is_mutable = + self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none(); + let binding_id: la_arena::Idx<Binding> = collector.alloc_binding( + Name::new_symbol_root(sym::self_.clone()), + BindingAnnotation::new(is_mutable, false), + ); + let hygiene = self_param_syn + .name() + .map(|name| collector.hygiene_id_for(name.syntax().text_range().start())) + .unwrap_or(HygieneId::ROOT); + if !hygiene.is_root() { + collector.store.binding_hygiene.insert(binding_id, hygiene); + } + self_param = Some(binding_id); + source_map_self_param = Some(collector.expander.in_file(AstPtr::new(&self_param_syn))); + } + + for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled) { + let param_pat = collector.collect_pat_top(param.pat()); + params.push(param_pat); + } + }; + + let body_expr = collector.collect( + body, + if is_async_fn { + Awaitable::Yes + } else { + match owner { + DefWithBodyId::FunctionId(..) => Awaitable::No("non-async function"), + DefWithBodyId::StaticId(..) => Awaitable::No("static"), + DefWithBodyId::ConstId(..) | DefWithBodyId::InTypeConstId(..) => { + Awaitable::No("constant") + } + DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"), + } + }, + ); + + ( + Body { + store: collector.store.finish(), + params: params.into_boxed_slice(), + self_param, + body_expr, + }, + BodySourceMap { self_param: source_map_self_param, store: collector.source_map }, + ) } +#[allow(dead_code)] +pub(super) fn lower( + db: &dyn DefDatabase, + owner: ExprStoreOwnerId, + expander: Expander, + body: Option<ast::Expr>, + krate: CrateId, +) -> (ExpressionStore, ExpressionStoreSourceMap) { + // We cannot leave the root span map empty and let any identifier from it be treated as root, + // because when inside nested macros `SyntaxContextId`s from the outer macro will be interleaved + // with the inner macro, and that will cause confusion because they won't be the same as `ROOT` + // even though they should be the same. Also, when the body comes from multiple expansions, their + // hygiene is different. + let span_map = expander.current_file_id().macro_file().map(|_| { + let SpanMap::ExpansionSpanMap(span_map) = expander.span_map(db) else { + panic!("in a macro file there should be `ExpansionSpanMap`"); + }; + Arc::clone(span_map) + }); + let mut expr_collector = ExprCollector::new(db, owner, expander, krate, span_map); + expr_collector.collect(body, Awaitable::No("?")); + (expr_collector.store.finish(), expr_collector.source_map) +} + +type ExprStoreOwnerId = DefWithBodyId; + struct ExprCollector<'a> { db: &'a dyn DefDatabase, expander: Expander, - owner: DefWithBodyId, + owner: ExprStoreOwnerId, def_map: Arc<DefMap>, ast_id_map: Arc<AstIdMap>, krate: CrateId, - body: Body, - source_map: BodySourceMap, + store: ExpressionStoreBuilder, + source_map: ExpressionStoreSourceMap, is_lowering_coroutine: bool, @@ -157,6 +271,7 @@ impl RibKind { } } +#[derive(PartialEq, Eq, Debug, Copy, Clone)] enum Awaitable { Yes, No(&'static str), @@ -180,12 +295,12 @@ impl BindingList { let id = *self.map.entry((name, hygiene)).or_insert_with_key(|(name, _)| { let id = ec.alloc_binding(name.clone(), mode); if !hygiene.is_root() { - ec.body.binding_hygiene.insert(id, hygiene); + ec.store.binding_hygiene.insert(id, hygiene); } id }); - if ec.body.bindings[id].mode != mode { - ec.body.bindings[id].problems = Some(BindingProblems::BoundInconsistently); + if ec.store.bindings[id].mode != mode { + ec.store.bindings[id].problems = Some(BindingProblems::BoundInconsistently); } self.check_is_used(ec, id); id @@ -195,11 +310,11 @@ impl BindingList { match self.is_used.get(&id) { None => { if self.reject_new { - ec.body.bindings[id].problems = Some(BindingProblems::NotBoundAcrossAll); + ec.store.bindings[id].problems = Some(BindingProblems::NotBoundAcrossAll); } } Some(true) => { - ec.body.bindings[id].problems = Some(BindingProblems::BoundMoreThanOnce); + ec.store.bindings[id].problems = Some(BindingProblems::BoundMoreThanOnce); } Some(false) => {} } @@ -208,93 +323,37 @@ impl BindingList { } impl ExprCollector<'_> { - fn collect( - mut self, - param_list: Option<(ast::ParamList, impl Iterator<Item = bool>)>, - body: Option<ast::Expr>, - is_async_fn: bool, - ) -> (Body, BodySourceMap) { - let skip_body = match self.owner { - DefWithBodyId::FunctionId(it) => self.db.attrs(it.into()), - DefWithBodyId::StaticId(it) => self.db.attrs(it.into()), - DefWithBodyId::ConstId(it) => self.db.attrs(it.into()), - DefWithBodyId::InTypeConstId(_) => Attrs::EMPTY, - DefWithBodyId::VariantId(it) => self.db.attrs(it.into()), + fn new( + db: &dyn DefDatabase, + owner: ExprStoreOwnerId, + expander: Expander, + krate: CrateId, + span_map: Option<Arc<ExpansionSpanMap>>, + ) -> ExprCollector<'_> { + ExprCollector { + db, + owner, + krate, + def_map: expander.module.def_map(db), + source_map: ExpressionStoreSourceMap::default(), + ast_id_map: db.ast_id_map(expander.current_file_id()), + store: ExpressionStoreBuilder::default(), + expander, + current_try_block_label: None, + is_lowering_coroutine: false, + label_ribs: Vec::new(), + current_binding_owner: None, + awaitable_context: None, + current_span_map: span_map, + current_block_legacy_macro_defs_count: FxHashMap::default(), } - .rust_analyzer_tool() - .any(|attr| *attr.path() == tool_path![skip]); - // If #[rust_analyzer::skip] annotated, only construct enough information for the signature - // and skip the body. - if skip_body { - self.body.body_expr = self.missing_expr(); - if let Some((param_list, mut attr_enabled)) = param_list { - if let Some(self_param) = - param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false)) - { - let is_mutable = - self_param.mut_token().is_some() && self_param.amp_token().is_none(); - let binding_id: la_arena::Idx<Binding> = self.alloc_binding( - Name::new_symbol_root(sym::self_.clone()), - BindingAnnotation::new(is_mutable, false), - ); - self.body.self_param = Some(binding_id); - self.source_map.self_param = - Some(self.expander.in_file(AstPtr::new(&self_param))); - } - self.body.params = param_list - .params() - .zip(attr_enabled) - .filter(|(_, enabled)| *enabled) - .map(|_| self.missing_pat()) - .collect(); - }; - return (self.body, self.source_map); - } - - self.awaitable_context.replace(if is_async_fn { - Awaitable::Yes - } else { - match self.owner { - DefWithBodyId::FunctionId(..) => Awaitable::No("non-async function"), - DefWithBodyId::StaticId(..) => Awaitable::No("static"), - DefWithBodyId::ConstId(..) | DefWithBodyId::InTypeConstId(..) => { - Awaitable::No("constant") - } - DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"), - } - }); - if let Some((param_list, mut attr_enabled)) = param_list { - let mut params = vec![]; - if let Some(self_param) = - param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false)) - { - let is_mutable = - self_param.mut_token().is_some() && self_param.amp_token().is_none(); - let binding_id: la_arena::Idx<Binding> = self.alloc_binding( - Name::new_symbol_root(sym::self_.clone()), - BindingAnnotation::new(is_mutable, false), - ); - let hygiene = self_param - .name() - .map(|name| self.hygiene_id_for(name.syntax().text_range().start())) - .unwrap_or(HygieneId::ROOT); - if !hygiene.is_root() { - self.body.binding_hygiene.insert(binding_id, hygiene); - } - self.body.self_param = Some(binding_id); - self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param))); - } + } - for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled) - { - let param_pat = self.collect_pat_top(param.pat()); - params.push(param_pat); - } - self.body.params = params.into_boxed_slice(); - }; - self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| { - if is_async_fn { - match body { + fn collect(&mut self, expr: Option<ast::Expr>, awaitable: Awaitable) -> ExprId { + self.awaitable_context.replace(awaitable); + self.with_label_rib(RibKind::Closure, |this| { + if awaitable == Awaitable::Yes { + match expr { Some(e) => { let syntax_ptr = AstPtr::new(&e); let expr = this.collect_expr(e); @@ -306,15 +365,13 @@ impl ExprCollector<'_> { None => this.missing_expr(), } } else { - this.collect_expr_opt(body) + this.collect_expr_opt(expr) } - }); - - (self.body, self.source_map) + }) } fn ctx(&mut self) -> LowerCtx<'_> { - self.expander.ctx(self.db, &mut self.body.types, &mut self.source_map.types) + self.expander.ctx(self.db, &mut self.store.types, &mut self.source_map.types) } fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { @@ -390,7 +447,7 @@ impl ExprCollector<'_> { parent: this.owner, root: inner_expr, }); - this.body.exprs[result_expr_id] = Expr::Const(it); + this.store.exprs[result_expr_id] = Expr::Const(it); this.current_binding_owner = prev_binding_owner; result_expr_id }) @@ -480,7 +537,7 @@ impl ExprCollector<'_> { .unwrap_or((Expr::Missing, HygieneId::ROOT)); let expr_id = self.alloc_expr(path, syntax_ptr); if !hygiene.is_root() { - self.body.expr_hygiene.insert(expr_id, hygiene); + self.store.ident_hygiene.insert(expr_id.into(), hygiene); } expr_id } @@ -562,10 +619,12 @@ impl ExprCollector<'_> { ast::Expr::AwaitExpr(e) => { let expr = self.collect_expr_opt(e.expr()); if let Awaitable::No(location) = self.is_lowering_awaitable_block() { - self.source_map.diagnostics.push(BodyDiagnostic::AwaitOutsideOfAsync { - node: InFile::new(self.expander.current_file_id(), AstPtr::new(&e)), - location: location.to_string(), - }); + self.source_map.diagnostics.push( + ExpressionStoreDiagnostics::AwaitOutsideOfAsync { + node: InFile::new(self.expander.current_file_id(), AstPtr::new(&e)), + location: location.to_string(), + }, + ); } self.alloc_expr(Expr::Await { expr }, syntax_ptr) } @@ -646,7 +705,7 @@ impl ExprCollector<'_> { this.is_lowering_coroutine = prev_is_lowering_coroutine; this.current_binding_owner = prev_binding_owner; this.current_try_block_label = prev_try_block_label; - this.body.exprs[result_expr_id] = Expr::Closure { + this.store.exprs[result_expr_id] = Expr::Closure { args: args.into(), arg_types: arg_types.into(), ret_type, @@ -752,7 +811,7 @@ impl ExprCollector<'_> { } fn parse_path(&mut self, path: ast::Path) -> Option<Path> { - self.expander.parse_path(self.db, path, &mut self.body.types, &mut self.source_map.types) + self.expander.parse_path(self.db, path, &mut self.store.types, &mut self.source_map.types) } fn collect_expr_path(&mut self, e: ast::PathExpr) -> Option<(Path, HygieneId)> { @@ -781,7 +840,7 @@ impl ExprCollector<'_> { let src = self.expander.in_file(AstPtr::new(&expr).wrap_left()); let expr = self.collect_expr(expr); // Do not use `alloc_pat_from_expr()` here, it will override the entry in `expr_map`. - let id = self.body.pats.alloc(Pat::Expr(expr)); + let id = self.store.pats.alloc(Pat::Expr(expr)); self.source_map.pat_map_back.insert(id, src); id }) @@ -835,7 +894,7 @@ impl ExprCollector<'_> { .unwrap_or((Pat::Missing, HygieneId::ROOT)); let pat_id = self.alloc_pat_from_expr(path, syntax_ptr); if !hygiene.is_root() { - self.body.pat_hygiene.insert(pat_id, hygiene); + self.store.ident_hygiene.insert(pat_id.into(), hygiene); } pat_id } @@ -967,7 +1026,7 @@ impl ExprCollector<'_> { ) -> ExprId { let (id, prev_owner) = self.initialize_binding_owner(syntax_ptr); let tmp = job(self); - self.body.exprs[id] = mem::replace(&mut self.body.exprs[tmp], Expr::Missing); + self.store.exprs[id] = mem::replace(&mut self.store.exprs[tmp], Expr::Missing); self.current_binding_owner = prev_owner; id } @@ -979,8 +1038,9 @@ impl ExprCollector<'_> { let Some(try_from_output) = self.lang_path(LangItem::TryTraitFromOutput) else { return self.collect_block(e); }; - let label = self - .alloc_label_desugared(Label { name: Name::generate_new_name(self.body.labels.len()) }); + let label = self.alloc_label_desugared(Label { + name: Name::generate_new_name(self.store.labels.len()), + }); let old_label = self.current_try_block_label.replace(label); let ptr = AstPtr::new(&e).upcast(); @@ -1006,7 +1066,7 @@ impl ExprCollector<'_> { ) } }; - let Expr::Block { tail, .. } = &mut self.body.exprs[expr_id] else { + let Expr::Block { tail, .. } = &mut self.store.exprs[expr_id] else { unreachable!("block was lowered to non-block"); }; *tail = Some(next_tail); @@ -1112,7 +1172,7 @@ impl ExprCollector<'_> { this.collect_expr_opt(e.loop_body().map(|it| it.into())) }), }; - let iter_name = Name::generate_new_name(self.body.exprs.len()); + let iter_name = Name::generate_new_name(self.store.exprs.len()); let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr); let iter_expr_mut = self.alloc_expr( Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut }, @@ -1177,7 +1237,7 @@ impl ExprCollector<'_> { let try_branch = self.alloc_expr(Expr::Path(try_branch), syntax_ptr); let expr = self .alloc_expr(Expr::Call { callee: try_branch, args: Box::new([operand]) }, syntax_ptr); - let continue_name = Name::generate_new_name(self.body.bindings.len()); + let continue_name = Name::generate_new_name(self.store.bindings.len()); let continue_binding = self.alloc_binding(continue_name.clone(), BindingAnnotation::Unannotated); let continue_bpat = @@ -1192,7 +1252,7 @@ impl ExprCollector<'_> { guard: None, expr: self.alloc_expr(Expr::Path(Path::from(continue_name)), syntax_ptr), }; - let break_name = Name::generate_new_name(self.body.bindings.len()); + let break_name = Name::generate_new_name(self.store.bindings.len()); let break_binding = self.alloc_binding(break_name.clone(), BindingAnnotation::Unannotated); let break_bpat = self.alloc_pat_desugared(Pat::Bind { id: break_binding, subpat: None }); self.add_definition_to_binding(break_binding, break_bpat); @@ -1261,17 +1321,19 @@ impl ExprCollector<'_> { Ok(res) => res, Err(UnresolvedMacro { path }) => { if record_diagnostics { - self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall { - node: InFile::new(outer_file, syntax_ptr), - path, - }); + self.source_map.diagnostics.push( + ExpressionStoreDiagnostics::UnresolvedMacroCall { + node: InFile::new(outer_file, syntax_ptr), + path, + }, + ); } return collector(self, None); } }; if record_diagnostics { if let Some(err) = res.err { - self.source_map.diagnostics.push(BodyDiagnostic::MacroError { + self.source_map.diagnostics.push(ExpressionStoreDiagnostics::MacroError { node: InFile::new(outer_file, syntax_ptr), err, }); @@ -1464,7 +1526,7 @@ impl ExprCollector<'_> { let (module, def_map) = match block_id.map(|block_id| (self.db.block_def_map(block_id), block_id)) { Some((def_map, block_id)) => { - self.body.block_scopes.push(block_id); + self.store.block_scopes.push(block_id); (def_map.module_id(DefMap::ROOT), def_map) } None => (self.expander.module, self.def_map.clone()), @@ -1621,7 +1683,7 @@ impl ExprCollector<'_> { pats.push(self.collect_pat(rest, binding_list)); for (&id, &is_used) in binding_list.is_used.iter() { if !is_used { - self.body.bindings[id].problems = + self.store.bindings[id].problems = Some(BindingProblems::NotBoundAcrossAll); } } @@ -1825,7 +1887,7 @@ impl ExprCollector<'_> { return Some(()); } - self.source_map.diagnostics.push(BodyDiagnostic::InactiveCode { + self.source_map.diagnostics.push(ExpressionStoreDiagnostics::InactiveCode { node: self.expander.in_file(SyntaxNodePtr::new(owner.syntax())), cfg, opts: self.expander.cfg_options().clone(), @@ -1853,7 +1915,7 @@ impl ExprCollector<'_> { fn resolve_label( &self, lifetime: Option<ast::Lifetime>, - ) -> Result<Option<LabelId>, BodyDiagnostic> { + ) -> Result<Option<LabelId>, ExpressionStoreDiagnostics> { let Some(lifetime) = lifetime else { return Ok(None) }; let (mut hygiene_id, mut hygiene_info) = match &self.current_span_map { None => (HygieneId::ROOT, None), @@ -1877,7 +1939,7 @@ impl ExprCollector<'_> { return if self.is_label_valid_from_rib(rib_idx) { Ok(Some(*id)) } else { - Err(BodyDiagnostic::UnreachableLabel { + Err(ExpressionStoreDiagnostics::UnreachableLabel { name, node: self.expander.in_file(AstPtr::new(&lifetime)), }) @@ -1903,7 +1965,7 @@ impl ExprCollector<'_> { } } - Err(BodyDiagnostic::UndeclaredLabel { + Err(ExpressionStoreDiagnostics::UndeclaredLabel { name, node: self.expander.in_file(AstPtr::new(&lifetime)), }) @@ -1934,7 +1996,7 @@ impl ExprCollector<'_> { f: impl FnOnce(&mut Self) -> T, ) -> T { self.label_ribs.push(LabelRib::new(RibKind::Normal( - self.body[label].name.clone(), + self.store.labels[label].name.clone(), label, hygiene, ))); @@ -2023,7 +2085,7 @@ impl ExprCollector<'_> { ); } if !hygiene.is_root() { - self.body.expr_hygiene.insert(expr_id, hygiene); + self.store.ident_hygiene.insert(expr_id.into(), hygiene); } expr_id }, @@ -2417,7 +2479,7 @@ fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)> impl ExprCollector<'_> { fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { let src = self.expander.in_file(ptr); - let id = self.body.exprs.alloc(expr); + let id = self.store.exprs.alloc(expr); self.source_map.expr_map_back.insert(id, src); self.source_map.expr_map.insert(src, id.into()); id @@ -2425,11 +2487,11 @@ impl ExprCollector<'_> { // FIXME: desugared exprs don't have ptr, that's wrong and should be fixed. // Migrate to alloc_expr_desugared_with_ptr and then rename back fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId { - self.body.exprs.alloc(expr) + self.store.exprs.alloc(expr) } fn alloc_expr_desugared_with_ptr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { let src = self.expander.in_file(ptr); - let id = self.body.exprs.alloc(expr); + let id = self.store.exprs.alloc(expr); self.source_map.expr_map_back.insert(id, src); // We intentionally don't fill this as it could overwrite a non-desugared entry // self.source_map.expr_map.insert(src, id); @@ -2440,45 +2502,45 @@ impl ExprCollector<'_> { } fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId { - let binding = self.body.bindings.alloc(Binding { name, mode, problems: None }); + let binding = self.store.bindings.alloc(Binding { name, mode, problems: None }); if let Some(owner) = self.current_binding_owner { - self.body.binding_owners.insert(binding, owner); + self.store.binding_owners.insert(binding, owner); } binding } fn alloc_pat_from_expr(&mut self, pat: Pat, ptr: ExprPtr) -> PatId { let src = self.expander.in_file(ptr); - let id = self.body.pats.alloc(pat); + let id = self.store.pats.alloc(pat); self.source_map.expr_map.insert(src, id.into()); self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_left)); id } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let src = self.expander.in_file(ptr); - let id = self.body.pats.alloc(pat); + let id = self.store.pats.alloc(pat); self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_right)); self.source_map.pat_map.insert(src, id); id } // FIXME: desugared pats don't have ptr, that's wrong and should be fixed somehow. fn alloc_pat_desugared(&mut self, pat: Pat) -> PatId { - self.body.pats.alloc(pat) + self.store.pats.alloc(pat) } fn missing_pat(&mut self) -> PatId { - self.body.pats.alloc(Pat::Missing) + self.store.pats.alloc(Pat::Missing) } fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId { let src = self.expander.in_file(ptr); - let id = self.body.labels.alloc(label); + let id = self.store.labels.alloc(label); self.source_map.label_map_back.insert(id, src); self.source_map.label_map.insert(src, id); id } // FIXME: desugared labels don't have ptr, that's wrong and should be fixed somehow. fn alloc_label_desugared(&mut self, label: Label) -> LabelId { - self.body.labels.alloc(label) + self.store.labels.alloc(label) } fn is_lowering_awaitable_block(&self) -> &Awaitable { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs index 68c7173d1e4..ab3d104b27f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs @@ -9,7 +9,7 @@ use syntax::{ use tt::TextRange; use crate::{ - body::lower::{ExprCollector, FxIndexSet}, + expr_store::lower::{ExprCollector, FxIndexSet}, hir::{AsmOperand, AsmOptions, Expr, ExprId, InlineAsm, InlineAsmRegOrRegClass}, }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs index 52b91b522a4..6a0b1e51979 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs @@ -60,7 +60,7 @@ pub(super) fn print_body_hir( let mut p = Printer { db, - body, + store: body, buf: header, indent_level: 0, line_format: LineFormat::Newline, @@ -103,14 +103,14 @@ pub(super) fn print_body_hir( pub(super) fn print_expr_hir( db: &dyn DefDatabase, - body: &Body, + store: &ExpressionStore, _owner: DefWithBodyId, expr: ExprId, edition: Edition, ) -> String { let mut p = Printer { db, - body, + store, buf: String::new(), indent_level: 0, line_format: LineFormat::Newline, @@ -122,7 +122,7 @@ pub(super) fn print_expr_hir( pub(super) fn print_pat_hir( db: &dyn DefDatabase, - body: &Body, + store: &ExpressionStore, _owner: DefWithBodyId, pat: PatId, oneline: bool, @@ -130,7 +130,7 @@ pub(super) fn print_pat_hir( ) -> String { let mut p = Printer { db, - body, + store, buf: String::new(), indent_level: 0, line_format: if oneline { LineFormat::Oneline } else { LineFormat::Newline }, @@ -157,7 +157,7 @@ macro_rules! wln { struct Printer<'a> { db: &'a dyn DefDatabase, - body: &'a Body, + store: &'a ExpressionStore, buf: String, indent_level: usize, line_format: LineFormat, @@ -233,7 +233,7 @@ impl Printer<'_> { } fn print_expr(&mut self, expr: ExprId) { - let expr = &self.body[expr]; + let expr = &self.store[expr]; match expr { Expr::Missing => w!(self, "�"), @@ -241,7 +241,7 @@ impl Printer<'_> { Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"), Expr::OffsetOf(offset_of) => { w!(self, "builtin#offset_of("); - self.print_type_ref(offset_of.container, &self.body.types); + self.print_type_ref(offset_of.container, &self.store.types); let edition = self.edition; w!( self, @@ -271,7 +271,7 @@ impl Printer<'_> { } Expr::Loop { body, label } => { if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name.display(self.db.upcast(), self.edition)); + w!(self, "{}: ", self.store[*lbl].name.display(self.db.upcast(), self.edition)); } w!(self, "loop "); self.print_expr(*body); @@ -295,7 +295,7 @@ impl Printer<'_> { if let Some(args) = generic_args { w!(self, "::<"); let edition = self.edition; - print_generic_args(self.db, args, &self.body.types, self, edition).unwrap(); + print_generic_args(self.db, args, &self.store.types, self, edition).unwrap(); w!(self, ">"); } w!(self, "("); @@ -330,13 +330,13 @@ impl Printer<'_> { Expr::Continue { label } => { w!(self, "continue"); if let Some(lbl) = label { - w!(self, " {}", self.body[*lbl].name.display(self.db.upcast(), self.edition)); + w!(self, " {}", self.store[*lbl].name.display(self.db.upcast(), self.edition)); } } Expr::Break { expr, label } => { w!(self, "break"); if let Some(lbl) = label { - w!(self, " {}", self.body[*lbl].name.display(self.db.upcast(), self.edition)); + w!(self, " {}", self.store[*lbl].name.display(self.db.upcast(), self.edition)); } if let Some(expr) = expr { self.whitespace(); @@ -404,7 +404,7 @@ impl Printer<'_> { Expr::Cast { expr, type_ref } => { self.print_expr(*expr); w!(self, " as "); - self.print_type_ref(*type_ref, &self.body.types); + self.print_type_ref(*type_ref, &self.store.types); } Expr::Ref { expr, rawness, mutability } => { w!(self, "&"); @@ -492,13 +492,13 @@ impl Printer<'_> { self.print_pat(*pat); if let Some(ty) = ty { w!(self, ": "); - self.print_type_ref(*ty, &self.body.types); + self.print_type_ref(*ty, &self.store.types); } } w!(self, "|"); if let Some(ret_ty) = ret_type { w!(self, " -> "); - self.print_type_ref(*ret_ty, &self.body.types); + self.print_type_ref(*ret_ty, &self.store.types); } self.whitespace(); self.print_expr(*body); @@ -534,7 +534,7 @@ impl Printer<'_> { Expr::Literal(lit) => self.print_literal(lit), Expr::Block { id: _, statements, tail, label } => { let label = label.map(|lbl| { - format!("{}: ", self.body[lbl].name.display(self.db.upcast(), self.edition)) + format!("{}: ", self.store[lbl].name.display(self.db.upcast(), self.edition)) }); self.print_block(label.as_deref(), statements, tail); } @@ -581,7 +581,7 @@ impl Printer<'_> { } fn print_pat(&mut self, pat: PatId) { - let pat = &self.body[pat]; + let pat = &self.store[pat]; match pat { Pat::Missing => w!(self, "�"), @@ -623,9 +623,9 @@ impl Printer<'_> { let field_name = arg.name.display(self.db.upcast(), edition).to_string(); let mut same_name = false; - if let Pat::Bind { id, subpat: None } = &self.body[arg.pat] { + if let Pat::Bind { id, subpat: None } = &self.store[arg.pat] { if let Binding { name, mode: BindingAnnotation::Unannotated, .. } = - &self.body.bindings[*id] + &self.store.bindings[*id] { if name.as_str() == field_name { same_name = true; @@ -734,7 +734,7 @@ impl Printer<'_> { self.print_pat(*pat); if let Some(ty) = type_ref { w!(self, ": "); - self.print_type_ref(*ty, &self.body.types); + self.print_type_ref(*ty, &self.store.types); } if let Some(init) = initializer { w!(self, " = "); @@ -799,11 +799,11 @@ impl Printer<'_> { fn print_path(&mut self, path: &Path) { let edition = self.edition; - print_path(self.db, path, &self.body.types, self, edition).unwrap(); + print_path(self.db, path, &self.store.types, self, edition).unwrap(); } fn print_binding(&mut self, id: BindingId) { - let Binding { name, mode, .. } = &self.body.bindings[id]; + let Binding { name, mode, .. } = &self.store.bindings[id]; let mode = match mode { BindingAnnotation::Unannotated => "", BindingAnnotation::Mutable => "mut ", diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs index 08af470b965..859a706177a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs @@ -4,8 +4,8 @@ use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx}; use triomphe::Arc; use crate::{ - body::{Body, HygieneId}, db::DefDatabase, + expr_store::{Body, ExpressionStore, HygieneId}, hir::{Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement}, BlockId, ConstBlockId, DefWithBodyId, }; @@ -53,7 +53,7 @@ pub struct ScopeData { impl ExprScopes { pub(crate) fn expr_scopes_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> { let body = db.body(def); - let mut scopes = ExprScopes::new(&body, |const_block| { + let mut scopes = ExprScopes::new_body(&body, |const_block| { db.lookup_intern_anonymous_const(const_block).root }); scopes.shrink_to_fit(); @@ -104,7 +104,7 @@ fn empty_entries(idx: usize) -> IdxRange<ScopeEntry> { } impl ExprScopes { - fn new( + fn new_body( body: &Body, resolve_const_block: impl (Fn(ConstBlockId) -> ExprId) + Copy, ) -> ExprScopes { @@ -179,28 +179,28 @@ impl ExprScopes { fn add_bindings( &mut self, - body: &Body, + store: &ExpressionStore, scope: ScopeId, binding: BindingId, hygiene: HygieneId, ) { - let Binding { name, .. } = &body.bindings[binding]; + let Binding { name, .. } = &store.bindings[binding]; let entry = self.scope_entries.alloc(ScopeEntry { name: name.clone(), binding, hygiene }); self.scopes[scope].entries = IdxRange::new_inclusive(self.scopes[scope].entries.start()..=entry); } - fn add_pat_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { - let pattern = &body[pat]; + fn add_pat_bindings(&mut self, store: &ExpressionStore, scope: ScopeId, pat: PatId) { + let pattern = &store[pat]; if let Pat::Bind { id, .. } = *pattern { - self.add_bindings(body, scope, id, body.binding_hygiene(id)); + self.add_bindings(store, scope, id, store.binding_hygiene(id)); } - pattern.walk_child_pats(|pat| self.add_pat_bindings(body, scope, pat)); + pattern.walk_child_pats(|pat| self.add_pat_bindings(store, scope, pat)); } - fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) { - params.iter().for_each(|pat| self.add_pat_bindings(body, scope, *pat)); + fn add_params_bindings(&mut self, store: &ExpressionStore, scope: ScopeId, params: &[PatId]) { + params.iter().for_each(|pat| self.add_pat_bindings(store, scope, *pat)); } fn set_scope(&mut self, node: ExprId, scope: ScopeId) { @@ -218,7 +218,7 @@ impl ExprScopes { fn compute_block_scopes( statements: &[Statement], tail: Option<ExprId>, - body: &Body, + store: &ExpressionStore, scopes: &mut ExprScopes, scope: &mut ScopeId, resolve_const_block: impl (Fn(ConstBlockId) -> ExprId) + Copy, @@ -227,17 +227,17 @@ fn compute_block_scopes( match stmt { Statement::Let { pat, initializer, else_branch, .. } => { if let Some(expr) = initializer { - compute_expr_scopes(*expr, body, scopes, scope, resolve_const_block); + compute_expr_scopes(*expr, store, scopes, scope, resolve_const_block); } if let Some(expr) = else_branch { - compute_expr_scopes(*expr, body, scopes, scope, resolve_const_block); + compute_expr_scopes(*expr, store, scopes, scope, resolve_const_block); } *scope = scopes.new_scope(*scope); - scopes.add_pat_bindings(body, *scope, *pat); + scopes.add_pat_bindings(store, *scope, *pat); } Statement::Expr { expr, .. } => { - compute_expr_scopes(*expr, body, scopes, scope, resolve_const_block); + compute_expr_scopes(*expr, store, scopes, scope, resolve_const_block); } Statement::Item(Item::MacroDef(macro_id)) => { *scope = scopes.new_macro_def_scope(*scope, macro_id.clone()); @@ -246,32 +246,32 @@ fn compute_block_scopes( } } if let Some(expr) = tail { - compute_expr_scopes(expr, body, scopes, scope, resolve_const_block); + compute_expr_scopes(expr, store, scopes, scope, resolve_const_block); } } fn compute_expr_scopes( expr: ExprId, - body: &Body, + store: &ExpressionStore, scopes: &mut ExprScopes, scope: &mut ScopeId, resolve_const_block: impl (Fn(ConstBlockId) -> ExprId) + Copy, ) { let make_label = - |label: &Option<LabelId>| label.map(|label| (label, body.labels[label].name.clone())); + |label: &Option<LabelId>| label.map(|label| (label, store.labels[label].name.clone())); let compute_expr_scopes = |scopes: &mut ExprScopes, expr: ExprId, scope: &mut ScopeId| { - compute_expr_scopes(expr, body, scopes, scope, resolve_const_block) + compute_expr_scopes(expr, store, scopes, scope, resolve_const_block) }; scopes.set_scope(expr, *scope); - match &body[expr] { + match &store[expr] { Expr::Block { statements, tail, id, label } => { let mut scope = scopes.new_block_scope(*scope, *id, make_label(label)); // Overwrite the old scope for the block expr, so that every block scope can be found // via the block itself (important for blocks that only contain items, no expressions). scopes.set_scope(expr, scope); - compute_block_scopes(statements, *tail, body, scopes, &mut scope, resolve_const_block); + compute_block_scopes(statements, *tail, store, scopes, &mut scope, resolve_const_block); } Expr::Const(id) => { let mut scope = scopes.root_scope(); @@ -282,7 +282,7 @@ fn compute_expr_scopes( // Overwrite the old scope for the block expr, so that every block scope can be found // via the block itself (important for blocks that only contain items, no expressions). scopes.set_scope(expr, scope); - compute_block_scopes(statements, *tail, body, scopes, &mut scope, resolve_const_block); + compute_block_scopes(statements, *tail, store, scopes, &mut scope, resolve_const_block); } Expr::Loop { body: body_expr, label } => { let mut scope = scopes.new_labeled_scope(*scope, make_label(label)); @@ -290,14 +290,14 @@ fn compute_expr_scopes( } Expr::Closure { args, body: body_expr, .. } => { let mut scope = scopes.new_scope(*scope); - scopes.add_params_bindings(body, scope, args); + scopes.add_params_bindings(store, scope, args); compute_expr_scopes(scopes, *body_expr, &mut scope); } Expr::Match { expr, arms } => { compute_expr_scopes(scopes, *expr, scope); for arm in arms.iter() { let mut scope = scopes.new_scope(*scope); - scopes.add_pat_bindings(body, scope, arm.pat); + scopes.add_pat_bindings(store, scope, arm.pat); if let Some(guard) = arm.guard { scope = scopes.new_scope(scope); compute_expr_scopes(scopes, guard, &mut scope); @@ -316,9 +316,9 @@ fn compute_expr_scopes( &Expr::Let { pat, expr } => { compute_expr_scopes(scopes, expr, scope); *scope = scopes.new_scope(*scope); - scopes.add_pat_bindings(body, *scope, pat); + scopes.add_pat_bindings(store, *scope, pat); } - _ => body.walk_child_exprs(expr, |e| compute_expr_scopes(scopes, e, scope)), + _ => store.walk_child_exprs(expr, |e| compute_expr_scopes(scopes, e, scope)), }; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs index edc7c4c1f21..9bf1ddb4793 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs @@ -1,6 +1,7 @@ mod block; use expect_test::{expect, Expect}; +use la_arena::RawIdx; use test_fixture::WithFixture; use crate::{test_db::TestDB, ModuleDefId}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs index e136dd18a55..e136dd18a55 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs index 7b3f1d06d21..e2b36da79b2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs @@ -433,7 +433,7 @@ impl GenericParams { GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params), GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params), GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params), - GenericDefId::ConstId(_) => ( + GenericDefId::ConstId(_) | GenericDefId::StaticId(_) => ( Arc::new(GenericParams { type_or_consts: Default::default(), lifetimes: Default::default(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs index 85963469430..0dcddf162b2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs @@ -19,7 +19,7 @@ use std::fmt; use hir_expand::{name::Name, MacroDefId}; use intern::Symbol; -use la_arena::{Idx, RawIdx}; +use la_arena::Idx; use rustc_apfloat::ieee::{Half as f16, Quad as f128}; use syntax::ast; use type_ref::TypeRefId; @@ -37,13 +37,10 @@ pub type BindingId = Idx<Binding>; pub type ExprId = Idx<Expr>; -/// FIXME: this is a hacky function which should be removed -pub(crate) fn dummy_expr_id() -> ExprId { - ExprId::from_raw(RawIdx::from(u32::MAX)) -} - pub type PatId = Idx<Pat>; +// FIXME: Encode this as a single u32, we won't ever reach all 32 bits especially given these counts +// are local to the body. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum ExprOrPatId { ExprId(ExprId), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index c78818c642c..c8efd904320 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -42,7 +42,7 @@ pub mod lang_item; pub mod hir; pub use self::hir::type_ref; -pub mod body; +pub mod expr_store; pub mod resolver; pub mod nameres; @@ -693,6 +693,7 @@ impl TypeOwnerId { Some(match self { TypeOwnerId::FunctionId(it) => GenericDefId::FunctionId(it), TypeOwnerId::ConstId(it) => GenericDefId::ConstId(it), + TypeOwnerId::StaticId(it) => GenericDefId::StaticId(it), TypeOwnerId::AdtId(it) => GenericDefId::AdtId(it), TypeOwnerId::TraitId(it) => GenericDefId::TraitId(it), TypeOwnerId::TraitAliasId(it) => GenericDefId::TraitAliasId(it), @@ -701,7 +702,7 @@ impl TypeOwnerId { TypeOwnerId::EnumVariantId(it) => { GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent)) } - TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None, + TypeOwnerId::InTypeConstId(_) => return None, }) } } @@ -743,6 +744,7 @@ impl From<GenericDefId> for TypeOwnerId { GenericDefId::TypeAliasId(it) => it.into(), GenericDefId::ImplId(it) => it.into(), GenericDefId::ConstId(it) => it.into(), + GenericDefId::StaticId(it) => it.into(), } } } @@ -851,7 +853,7 @@ impl GeneralConstId { pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> { match self { GeneralConstId::ConstId(it) => Some(it.into()), - GeneralConstId::StaticId(_) => None, + GeneralConstId::StaticId(it) => Some(it.into()), GeneralConstId::ConstBlockId(it) => it.lookup(db).parent.as_generic_def_id(db), GeneralConstId::InTypeConstId(it) => it.lookup(db).owner.as_generic_def_id(db), } @@ -897,7 +899,7 @@ impl DefWithBodyId { pub fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> { match self { DefWithBodyId::FunctionId(f) => Some(f.into()), - DefWithBodyId::StaticId(_) => None, + DefWithBodyId::StaticId(s) => Some(s.into()), DefWithBodyId::ConstId(c) => Some(c.into()), DefWithBodyId::VariantId(c) => Some(c.lookup(db).parent.into()), // FIXME: stable rust doesn't allow generics in constants, but we should @@ -922,23 +924,28 @@ impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId); #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub enum GenericDefId { - FunctionId(FunctionId), AdtId(AdtId), - TraitId(TraitId), - TraitAliasId(TraitAliasId), - TypeAliasId(TypeAliasId), - ImplId(ImplId), // consts can have type parameters from their parents (i.e. associated consts of traits) ConstId(ConstId), + FunctionId(FunctionId), + ImplId(ImplId), + // can't actually have generics currently, but they might in the future + // More importantly, this completes the set of items that contain type references + // which is to be used by the signature expression store in the future. + StaticId(StaticId), + TraitAliasId(TraitAliasId), + TraitId(TraitId), + TypeAliasId(TypeAliasId), } impl_from!( - FunctionId, AdtId(StructId, EnumId, UnionId), - TraitId, - TraitAliasId, - TypeAliasId, + ConstId, + FunctionId, ImplId, - ConstId + StaticId, + TraitAliasId, + TraitId, + TypeAliasId for GenericDefId ); @@ -969,6 +976,7 @@ impl GenericDefId { GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it), GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it), GenericDefId::ConstId(it) => (it.lookup(db).id.file_id(), None), + GenericDefId::StaticId(it) => (it.lookup(db).id.file_id(), None), } } @@ -1350,6 +1358,7 @@ impl HasModule for GenericDefId { GenericDefId::TypeAliasId(it) => it.module(db), GenericDefId::ImplId(it) => it.module(db), GenericDefId::ConstId(it) => it.module(db), + GenericDefId::StaticId(it) => it.module(db), } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 8c556d8a8c3..7e13ae2f7a1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -10,13 +10,13 @@ use smallvec::{smallvec, SmallVec}; use triomphe::Arc; use crate::{ - body::{ - scope::{ExprScopes, ScopeId}, - HygieneId, - }, builtin_type::BuiltinType, data::ExternCrateDeclData, db::DefDatabase, + expr_store::{ + scope::{ExprScopes, ScopeId}, + HygieneId, + }, generics::{GenericParams, TypeOrConstParamData}, hir::{BindingId, ExprId, LabelId}, item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE}, @@ -1264,6 +1264,7 @@ impl HasResolver for GenericDefId { GenericDefId::TypeAliasId(inner) => inner.resolver(db), GenericDefId::ImplId(inner) => inner.resolver(db), GenericDefId::ConstId(inner) => inner.resolver(db), + GenericDefId::StaticId(inner) => inner.resolver(db), } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 142766c039b..836a236444c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -3,7 +3,7 @@ use base_db::{ra_salsa::Cycle, CrateId}; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use hir_def::{ - body::{Body, HygieneId}, + expr_store::{Body, HygieneId}, hir::{Expr, ExprId}, path::Path, resolver::{Resolver, ValueNs}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 7f9f0c0de19..0b5f1319243 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -36,7 +36,7 @@ use crate::{ }; pub(crate) use hir_def::{ - body::Body, + expr_store::Body, hir::{Expr, ExprId, MatchArm, Pat, PatId, Statement}, LocalFieldId, VariantId, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs index c5d8c956615..b0f9fc53e29 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs @@ -11,7 +11,8 @@ pub(crate) mod pat_analysis; use chalk_ir::Mutability; use hir_def::{ - body::Body, data::adt::VariantData, hir::PatId, AdtId, EnumVariantId, LocalFieldId, VariantId, + data::adt::VariantData, expr_store::Body, hir::PatId, AdtId, EnumVariantId, LocalFieldId, + VariantId, }; use hir_expand::name::Name; use span::Edition; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index 5b0041d4727..99ec1951a37 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -5,7 +5,7 @@ use std::mem; use either::Either; use hir_def::{ - body::Body, + expr_store::Body, hir::{Expr, ExprId, ExprOrPatId, Pat, PatId, Statement, UnaryOp}, path::Path, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs index abbf2a4f2ef..18cf6e5ce36 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs @@ -262,7 +262,8 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<Generic GenericDefId::FunctionId(it) => it.lookup(db).container, GenericDefId::TypeAliasId(it) => it.lookup(db).container, GenericDefId::ConstId(it) => it.lookup(db).container, - GenericDefId::AdtId(_) + GenericDefId::StaticId(_) + | GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) | GenericDefId::TraitAliasId(_) => return None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 25bb3a76de2..3c258e3c4cf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -34,9 +34,9 @@ use chalk_ir::{ }; use either::Either; use hir_def::{ - body::{Body, HygieneId}, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, data::{ConstData, StaticData}, + expr_store::{Body, HygieneId}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, lang_item::{LangItem, LangItemTarget}, layout::Integer, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs index 032dc37899d..b85378531ad 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs @@ -5,7 +5,7 @@ use std::cell::RefCell; use std::ops::{Deref, DerefMut}; -use hir_def::body::HygieneId; +use hir_def::expr_store::HygieneId; use hir_def::hir::ExprOrPatId; use hir_def::path::{Path, PathSegment, PathSegments}; use hir_def::resolver::{ResolveValueResult, Resolver, TypeNs}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index 00398f019da..ca8d5bae5e5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -3,7 +3,7 @@ use std::iter::repeat_with; use hir_def::{ - body::Body, + expr_store::Body, hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId}, path::Path, }; @@ -528,7 +528,7 @@ impl InferenceContext<'_> { self.infer_expr(expr, &Expectation::has_type(expected.clone()), ExprIsRead::Yes) } - fn is_non_ref_pat(&mut self, body: &hir_def::body::Body, pat: PatId) -> bool { + fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bool { match &body[pat] { Pat::Tuple { .. } | Pat::TupleStruct { .. } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 73bcefaf2a9..36ec60a7a2f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -86,10 +86,9 @@ impl InferenceContext<'_> { } }; - let generic_def_id = value_def.to_generic_def_id(self.db); - let Some(generic_def) = generic_def_id else { - // `value_def` is the kind of item that can never be generic (i.e. statics, at least - // currently). We can just skip the binders to get its type. + let generic_def = value_def.to_generic_def_id(self.db); + if let GenericDefId::StaticId(_) = generic_def { + // `Static` is the kind of item that can never be generic currently. We can just skip the binders to get its type. let (ty, binders) = self.db.value_ty(value_def)?.into_value_and_skipped_binders(); stdx::always!(binders.is_empty(Interner), "non-empty binders for non-generic def",); return Some(ValuePathResolution::NonGeneric(ty)); @@ -122,7 +121,7 @@ impl InferenceContext<'_> { } let parent_substs = self_subst.or_else(|| { - let generics = generics(self.db.upcast(), generic_def_id?); + let generics = generics(self.db.upcast(), generic_def); let parent_params_len = generics.parent_generics()?.len(); let parent_args = &substs[substs.len() - parent_params_len..]; Some(Substitution::from_iter(Interner, parent_args)) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 432b8f4d94e..db13e1fd354 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -23,10 +23,10 @@ use chalk_ir::{ use either::Either; use hir_def::{ - body::HygieneId, builtin_type::BuiltinType, data::{adt::StructKind, TraitFlags}, expander::Expander, + expr_store::HygieneId, generics::{ GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, @@ -2471,14 +2471,14 @@ pub enum ValueTyDefId { impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId); impl ValueTyDefId { - pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> Option<GenericDefId> { + pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> GenericDefId { match self { - Self::FunctionId(id) => Some(id.into()), - Self::StructId(id) => Some(id.into()), - Self::UnionId(id) => Some(id.into()), - Self::EnumVariantId(var) => Some(var.lookup(db.upcast()).parent.into()), - Self::ConstId(id) => Some(id.into()), - Self::StaticId(_) => None, + Self::FunctionId(id) => id.into(), + Self::StructId(id) => id.into(), + Self::UnionId(id) => id.into(), + Self::EnumVariantId(var) => var.lookup(db.upcast()).parent.into(), + Self::ConstId(id) => id.into(), + Self::StaticId(id) => id.into(), } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 59c583afb2a..84d8950b1aa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -16,7 +16,7 @@ use base_db::CrateId; use chalk_ir::Mutability; use either::Either; use hir_def::{ - body::Body, + expr_store::Body, hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId}, DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index dcae6877ba8..8e4c4db1020 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -6,9 +6,9 @@ use base_db::CrateId; use chalk_ir::{cast::Cast, Mutability}; use either::Either; use hir_def::{ - body::HygieneId, builtin_type::BuiltinType, data::adt::{StructFlags, VariantData}, + expr_store::HygieneId, lang_item::LangItem, layout::{TagEncoding, Variants}, resolver::{HasResolver, TypeNs, ValueNs}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 1d1044df6e9..cc6ed122af4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -5,8 +5,8 @@ use std::{fmt::Write, iter, mem}; use base_db::ra_salsa::Cycle; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ - body::{Body, HygieneId}, data::adt::{StructKind, VariantData}, + expr_store::{Body, HygieneId}, hir::{ ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs index 06765a104cb..2a26101ac43 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs @@ -6,7 +6,7 @@ use std::{ }; use either::Either; -use hir_def::{body::Body, hir::BindingId}; +use hir_def::{expr_store::Body, hir::BindingId}; use hir_expand::{name::Name, Lookup}; use la_arena::ArenaMap; use span::Edition; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 00da9b25176..69ec35f406d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -18,8 +18,8 @@ use std::sync::LazyLock; use base_db::SourceDatabaseFileInputExt as _; use expect_test::Expect; use hir_def::{ - body::{Body, BodySourceMap}, db::DefDatabase, + expr_store::{Body, BodySourceMap}, hir::{ExprId, Pat, PatId}, item_scope::ItemScope, nameres::DefMap, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index afd163fbd96..3a22158ce6f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -1028,6 +1028,7 @@ struct FixedPoint<T, U, V>(&'static FixedPoint<(), T, U>, V); } GenericDefId::ImplId(_) => return None, GenericDefId::ConstId(_) => return None, + GenericDefId::StaticId(_) => return None, }, )) }) diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index fc77d1889c8..066a322e32b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs @@ -411,7 +411,7 @@ impl AnyDiagnostic { pub(crate) fn body_validation_diagnostic( db: &dyn HirDatabase, diagnostic: BodyValidationDiagnostic, - source_map: &hir_def::body::BodySourceMap, + source_map: &hir_def::expr_store::BodySourceMap, ) -> Option<AnyDiagnostic> { match diagnostic { BodyValidationDiagnostic::RecordMissingFields { record, variant, missed_fields } => { @@ -547,7 +547,7 @@ impl AnyDiagnostic { def: DefWithBodyId, d: &InferenceDiagnostic, outer_types_source_map: &TypesSourceMap, - source_map: &hir_def::body::BodySourceMap, + source_map: &hir_def::expr_store::BodySourceMap, ) -> Option<AnyDiagnostic> { let expr_syntax = |expr| { source_map.expr_syntax(expr).inspect_err(|_| stdx::never!("synthetic syntax")).ok() diff --git a/src/tools/rust-analyzer/crates/hir/src/from_id.rs b/src/tools/rust-analyzer/crates/hir/src/from_id.rs index 2ad39817b2f..537401afdc3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/from_id.rs +++ b/src/tools/rust-analyzer/crates/hir/src/from_id.rs @@ -183,6 +183,7 @@ impl From<GenericDef> for GenericDefId { GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), GenericDef::Impl(it) => GenericDefId::ImplId(it.id), GenericDef::Const(it) => GenericDefId::ConstId(it.id), + GenericDef::Static(it) => GenericDefId::StaticId(it.id), } } } @@ -197,6 +198,7 @@ impl From<GenericDefId> for GenericDef { GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), GenericDefId::ImplId(it) => GenericDef::Impl(it.into()), GenericDefId::ConstId(it) => GenericDef::Const(it.into()), + GenericDefId::StaticId(it) => GenericDef::Static(it.into()), } } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 407b1b94eda..27723cbc16a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -42,8 +42,8 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateId, CrateOrigin}; use either::Either; use hir_def::{ - body::BodyDiagnostic, data::{adt::VariantData, TraitFlags}, + expr_store::ExpressionStoreDiagnostics, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat}, item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode}, @@ -1892,10 +1892,10 @@ impl DefWithBody { for diag in source_map.diagnostics() { acc.push(match diag { - BodyDiagnostic::InactiveCode { node, cfg, opts } => { + ExpressionStoreDiagnostics::InactiveCode { node, cfg, opts } => { InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into() } - BodyDiagnostic::MacroError { node, err } => { + ExpressionStoreDiagnostics::MacroError { node, err } => { let RenderedExpandError { message, error, kind } = err.render_to_string(db.upcast()); @@ -1919,20 +1919,22 @@ impl DefWithBody { } .into() } - BodyDiagnostic::UnresolvedMacroCall { node, path } => UnresolvedMacroCall { - macro_call: (*node).map(|ast_ptr| ast_ptr.into()), - precise_location: None, - path: path.clone(), - is_bang: true, + ExpressionStoreDiagnostics::UnresolvedMacroCall { node, path } => { + UnresolvedMacroCall { + macro_call: (*node).map(|ast_ptr| ast_ptr.into()), + precise_location: None, + path: path.clone(), + is_bang: true, + } + .into() } - .into(), - BodyDiagnostic::AwaitOutsideOfAsync { node, location } => { + ExpressionStoreDiagnostics::AwaitOutsideOfAsync { node, location } => { AwaitOutsideOfAsync { node: *node, location: location.clone() }.into() } - BodyDiagnostic::UnreachableLabel { node, name } => { + ExpressionStoreDiagnostics::UnreachableLabel { node, name } => { UnreachableLabel { node: *node, name: name.clone() }.into() } - BodyDiagnostic::UndeclaredLabel { node, name } => { + ExpressionStoreDiagnostics::UndeclaredLabel { node, name } => { UndeclaredLabel { node: *node, name: name.clone() }.into() } }); @@ -3456,6 +3458,7 @@ pub enum GenericDef { Impl(Impl), // consts can have type parameters from their parents (i.e. associated consts of traits) Const(Const), + Static(Static), } impl_from!( Function, @@ -3464,7 +3467,8 @@ impl_from!( TraitAlias, TypeAlias, Impl, - Const + Const, + Static for GenericDef ); @@ -3514,6 +3518,7 @@ impl GenericDef { GenericDef::TypeAlias(it) => it.id.into(), GenericDef::Impl(it) => it.id.into(), GenericDef::Const(it) => it.id.into(), + GenericDef::Static(it) => it.id.into(), } } @@ -3571,6 +3576,7 @@ impl GenericDef { item_tree_source_maps.impl_(id.value).generics() } GenericDefId::ConstId(_) => return, + GenericDefId::StaticId(_) => return, }, }; diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index b699ccde412..496b6566bd1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -14,7 +14,7 @@ use crate::{ }; use either::Either; use hir_def::{ - body::{ + expr_store::{ scope::{ExprScopes, ScopeId}, Body, BodySourceMap, HygieneId, }, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index d12bda0816f..bad53608056 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -986,6 +986,7 @@ impl From<GenericDef> for Definition { GenericDef::TypeAlias(it) => it.into(), GenericDef::Impl(it) => it.into(), GenericDef::Const(it) => it.into(), + GenericDef::Static(it) => it.into(), } } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 7fc563a4241..7963e8ae4f7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -354,6 +354,7 @@ impl Definition { hir::GenericDef::TypeAlias(it) => it.source(db).map(|src| src.syntax().cloned()), hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()), hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), }; return match def { Some(def) => SearchScope::file_range( diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index 40f3406b72d..c996230c3a1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -434,6 +434,7 @@ fn definition_owner_name(db: &RootDatabase, def: Definition, edition: Edition) - None => it.name(db), } } + hir::GenericDef::Static(it) => Some(it.name(db)), }, Definition::DeriveHelper(derive_helper) => Some(derive_helper.derive().name(db)), d => { diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index f8c60418eb0..f9972116004 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -321,7 +321,9 @@ fn signature_help_for_generics( format_to!(res.signature, "type {}", it.name(db).display(db, edition)); } // These don't have generic args that can be specified - hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) => return None, + hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) | hir::GenericDef::Static(_) => { + return None + } } let params = generics_def.params(sema.db); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 18c27c84496..cd709afe091 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -13,7 +13,7 @@ use hir::{ ModuleDef, Name, }; use hir_def::{ - body::BodySourceMap, + expr_store::BodySourceMap, hir::{ExprId, PatId}, SyntheticSyntax, }; |
