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.rs137
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)))
}
}