Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store/lower.rs')
| -rw-r--r-- | crates/hir-def/src/expr_store/lower.rs | 137 |
1 files changed, 72 insertions, 65 deletions
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index e3bfc5b753..26a50b5325 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -5,14 +5,13 @@ mod asm; mod generics; mod path; -use std::mem; +use std::{cell::OnceCell, mem}; use base_db::FxIndexSet; use cfg::CfgOptions; use either::Either; use hir_expand::{ HirFileId, InFile, MacroDefId, - mod_path::tool_path, name::{AsName, Name}, span_map::SpanMapRef, }; @@ -34,6 +33,7 @@ use tt::TextRange; use crate::{ AdtId, BlockId, BlockLoc, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, ModuleDefId, ModuleId, TraitId, TypeAliasId, UnresolvedMacro, + attrs::AttrFlags, builtin_type::BuiltinUint, db::DefDatabase, expr_store::{ @@ -57,7 +57,7 @@ use crate::{ }, item_scope::BuiltinShadowMode, item_tree::FieldsShape, - lang_item::LangItem, + lang_item::{LangItemTarget, LangItems}, nameres::{DefMap, LocalDefMap, MacroSubNs, block_def_map}, type_ref::{ ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness, @@ -87,14 +87,16 @@ pub(super) fn lower_body( let mut params = vec![]; let mut collector = ExprCollector::new(db, module, current_file_id); - 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::VariantId(it) => db.attrs(it.into()), - } - .rust_analyzer_tool() - .any(|attr| *attr.path() == tool_path![skip]); + let skip_body = AttrFlags::query( + db, + match owner { + DefWithBodyId::FunctionId(it) => it.into(), + DefWithBodyId::StaticId(it) => it.into(), + DefWithBodyId::ConstId(it) => it.into(), + DefWithBodyId::VariantId(it) => it.into(), + }, + ) + .contains(AttrFlags::RUST_ANALYZER_SKIP); // If #[rust_analyzer::skip] annotated, only construct enough information for the signature // and skip the body. if skip_body { @@ -416,6 +418,7 @@ pub struct ExprCollector<'db> { def_map: &'db DefMap, local_def_map: &'db LocalDefMap, module: ModuleId, + lang_items: OnceCell<&'db LangItems>, pub store: ExpressionStoreBuilder, // state stuff @@ -513,7 +516,7 @@ impl BindingList { } } -impl ExprCollector<'_> { +impl<'db> ExprCollector<'db> { pub fn new( db: &dyn DefDatabase, module: ModuleId, @@ -527,6 +530,7 @@ impl ExprCollector<'_> { module, def_map, local_def_map, + lang_items: OnceCell::new(), store: ExpressionStoreBuilder::default(), expander, current_try_block_label: None, @@ -540,6 +544,11 @@ impl ExprCollector<'_> { } #[inline] + pub(crate) fn lang_items(&self) -> &'db LangItems { + self.lang_items.get_or_init(|| crate::lang_item::lang_items(self.db, self.module.krate)) + } + + #[inline] pub(crate) fn span_map(&self) -> SpanMapRef<'_> { self.expander.span_map() } @@ -1654,7 +1663,7 @@ impl ExprCollector<'_> { /// `try { <stmts>; }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(()) }` /// and save the `<new_label>` to use it as a break target for desugaring of the `?` operator. fn desugar_try_block(&mut self, e: BlockExpr) -> ExprId { - let try_from_output = self.lang_path(LangItem::TryTraitFromOutput); + let try_from_output = self.lang_path(self.lang_items().TryTraitFromOutput); let label = self.alloc_label_desugared(Label { name: Name::generate_new_name(self.store.labels.len()), }); @@ -1753,10 +1762,11 @@ impl ExprCollector<'_> { /// } /// ``` fn collect_for_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::ForExpr) -> ExprId { - let into_iter_fn = self.lang_path(LangItem::IntoIterIntoIter); - let iter_next_fn = self.lang_path(LangItem::IteratorNext); - let option_some = self.lang_path(LangItem::OptionSome); - let option_none = self.lang_path(LangItem::OptionNone); + let lang_items = self.lang_items(); + let into_iter_fn = self.lang_path(lang_items.IntoIterIntoIter); + let iter_next_fn = self.lang_path(lang_items.IteratorNext); + let option_some = self.lang_path(lang_items.OptionSome); + let option_none = self.lang_path(lang_items.OptionNone); let head = self.collect_expr_opt(e.iterable()); let into_iter_fn_expr = self.alloc_expr(into_iter_fn.map_or(Expr::Missing, Expr::Path), syntax_ptr); @@ -1836,10 +1846,11 @@ impl ExprCollector<'_> { /// } /// ``` fn collect_try_operator(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::TryExpr) -> ExprId { - let try_branch = self.lang_path(LangItem::TryTraitBranch); - let cf_continue = self.lang_path(LangItem::ControlFlowContinue); - let cf_break = self.lang_path(LangItem::ControlFlowBreak); - let try_from_residual = self.lang_path(LangItem::TryTraitFromResidual); + let lang_items = self.lang_items(); + let try_branch = self.lang_path(lang_items.TryTraitBranch); + let cf_continue = self.lang_path(lang_items.ControlFlowContinue); + let cf_break = self.lang_path(lang_items.ControlFlowBreak); + let try_from_residual = self.lang_path(lang_items.TryTraitFromResidual); let operand = self.collect_expr_opt(e.expr()); let try_branch = self.alloc_expr(try_branch.map_or(Expr::Missing, Expr::Path), syntax_ptr); let expr = self @@ -2489,7 +2500,7 @@ impl ExprCollector<'_> { /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when /// not. fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> bool { - let enabled = self.expander.is_cfg_enabled(self.db, owner, self.cfg_options); + let enabled = self.expander.is_cfg_enabled(owner, self.cfg_options); match enabled { Ok(()) => true, Err(cfg) => { @@ -2773,11 +2784,10 @@ impl ExprCollector<'_> { // Assume that rustc version >= 1.89.0 iff lang item `format_arguments` exists // but `format_unsafe_arg` does not - let fmt_args = - || crate::lang_item::lang_item(self.db, self.module.krate(), LangItem::FormatArguments); - let fmt_unsafe_arg = - || crate::lang_item::lang_item(self.db, self.module.krate(), LangItem::FormatUnsafeArg); - let use_format_args_since_1_89_0 = fmt_args().is_some() && fmt_unsafe_arg().is_none(); + let lang_items = self.lang_items(); + let fmt_args = lang_items.FormatArguments; + let fmt_unsafe_arg = lang_items.FormatUnsafeArg; + let use_format_args_since_1_89_0 = fmt_args.is_some() && fmt_unsafe_arg.is_none(); let idx = if use_format_args_since_1_89_0 { self.collect_format_args_impl(syntax_ptr, fmt, argmap, lit_pieces, format_options) @@ -2856,16 +2866,13 @@ impl ExprCollector<'_> { // unsafe { ::core::fmt::UnsafeArg::new() } // ) - let new_v1_formatted = LangItem::FormatArguments.ty_rel_path( - self.db, - self.module.krate(), + let lang_items = self.lang_items(); + let new_v1_formatted = self.ty_rel_lang_path( + lang_items.FormatArguments, Name::new_symbol_root(sym::new_v1_formatted), ); - let unsafe_arg_new = LangItem::FormatUnsafeArg.ty_rel_path( - self.db, - self.module.krate(), - Name::new_symbol_root(sym::new), - ); + let unsafe_arg_new = + self.ty_rel_lang_path(lang_items.FormatUnsafeArg, Name::new_symbol_root(sym::new)); let new_v1_formatted = self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); @@ -3044,9 +3051,8 @@ impl ExprCollector<'_> { // ) // } - let new_v1_formatted = LangItem::FormatArguments.ty_rel_path( - self.db, - self.module.krate(), + let new_v1_formatted = self.ty_rel_lang_path( + self.lang_items().FormatArguments, Name::new_symbol_root(sym::new_v1_formatted), ); let new_v1_formatted = @@ -3099,6 +3105,7 @@ impl ExprCollector<'_> { placeholder: &FormatPlaceholder, argmap: &mut FxIndexSet<(usize, ArgumentType)>, ) -> ExprId { + let lang_items = self.lang_items(); let position = match placeholder.argument.index { Ok(arg_index) => { let (i, _) = @@ -3159,15 +3166,14 @@ impl ExprCollector<'_> { let width = RecordLitField { name: Name::new_symbol_root(sym::width), expr: width_expr }; self.alloc_expr_desugared(Expr::RecordLit { - path: LangItem::FormatPlaceholder.path(self.db, self.module.krate()).map(Box::new), + path: self.lang_path(lang_items.FormatPlaceholder).map(Box::new), fields: Box::new([position, flags, precision, width]), spread: None, }) } else { let format_placeholder_new = { - let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path( - self.db, - self.module.krate(), + let format_placeholder_new = self.ty_rel_lang_path( + lang_items.FormatPlaceholder, Name::new_symbol_root(sym::new), ); match format_placeholder_new { @@ -3188,9 +3194,8 @@ impl ExprCollector<'_> { ))); let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' ')))); let align = { - let align = LangItem::FormatAlignment.ty_rel_path( - self.db, - self.module.krate(), + let align = self.ty_rel_lang_path( + lang_items.FormatAlignment, match alignment { Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), @@ -3234,6 +3239,7 @@ impl ExprCollector<'_> { count: &Option<FormatCount>, argmap: &mut FxIndexSet<(usize, ArgumentType)>, ) -> ExprId { + let lang_items = self.lang_items(); match count { Some(FormatCount::Literal(n)) => { let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( @@ -3241,11 +3247,9 @@ impl ExprCollector<'_> { // FIXME: Change this to Some(BuiltinUint::U16) once we drop support for toolchains < 1.88 None, ))); - let count_is = match LangItem::FormatCount.ty_rel_path( - self.db, - self.module.krate(), - Name::new_symbol_root(sym::Is), - ) { + let count_is = match self + .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Is)) + { Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), None => self.missing_expr(), }; @@ -3259,11 +3263,9 @@ impl ExprCollector<'_> { i as u128, Some(BuiltinUint::Usize), ))); - let count_param = match LangItem::FormatCount.ty_rel_path( - self.db, - self.module.krate(), - Name::new_symbol_root(sym::Param), - ) { + let count_param = match self + .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Param)) + { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), }; @@ -3277,11 +3279,9 @@ impl ExprCollector<'_> { self.missing_expr() } } - None => match LangItem::FormatCount.ty_rel_path( - self.db, - self.module.krate(), - Name::new_symbol_root(sym::Implied), - ) { + None => match self + .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Implied)) + { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), }, @@ -3299,9 +3299,8 @@ impl ExprCollector<'_> { use ArgumentType::*; use FormatTrait::*; - let new_fn = match LangItem::FormatArgument.ty_rel_path( - self.db, - self.module.krate(), + let new_fn = match self.ty_rel_lang_path( + self.lang_items().FormatArgument, Name::new_symbol_root(match ty { Format(Display) => sym::new_display, Format(Debug) => sym::new_debug, @@ -3323,8 +3322,16 @@ impl ExprCollector<'_> { // endregion: format - fn lang_path(&self, lang: LangItem) -> Option<Path> { - lang.path(self.db, self.module.krate()) + fn lang_path(&self, lang: Option<impl Into<LangItemTarget>>) -> Option<Path> { + Some(Path::LangItem(lang?.into(), None)) + } + + fn ty_rel_lang_path( + &self, + lang: Option<impl Into<LangItemTarget>>, + relative_name: Name, + ) -> Option<Path> { + Some(Path::LangItem(lang?.into(), Some(relative_name))) } } |