Merge pull request #21149 from ChayimFriedman2/lang-items
perf: Use one query per crate for lang items, not one per lang item
This commit is contained in:
commit
bc662f19bb
60 changed files with 1034 additions and 1065 deletions
|
|
@ -27,7 +27,6 @@ use crate::{
|
|||
VariantId,
|
||||
db::DefDatabase,
|
||||
item_tree::block_item_tree_query,
|
||||
lang_item::LangItem,
|
||||
nameres::{ModuleOrigin, ModuleSource},
|
||||
src::{HasChildSource, HasSource},
|
||||
};
|
||||
|
|
@ -209,8 +208,8 @@ impl Attrs {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn lang_item(&self) -> Option<LangItem> {
|
||||
self.by_key(sym::lang).string_value().and_then(LangItem::from_symbol)
|
||||
pub fn lang_item(&self) -> Option<&Symbol> {
|
||||
self.by_key(sym::lang).string_value()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ use crate::{
|
|||
hir::generics::GenericParams,
|
||||
import_map::ImportMap,
|
||||
item_tree::{ItemTree, file_item_tree_query},
|
||||
lang_item::{self, LangItem},
|
||||
nameres::crate_def_map,
|
||||
signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature,
|
||||
|
|
@ -254,10 +253,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
|
|||
#[salsa::invoke_interned(AttrsWithOwner::attrs_query)]
|
||||
fn attrs(&self, def: AttrDefId) -> Attrs;
|
||||
|
||||
#[salsa::transparent]
|
||||
#[salsa::invoke(lang_item::lang_attr)]
|
||||
fn lang_attr(&self, def: AttrDefId) -> Option<LangItem>;
|
||||
|
||||
// endregion:attrs
|
||||
|
||||
#[salsa::invoke(ImportMap::import_map_query)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ mod asm;
|
|||
mod generics;
|
||||
mod path;
|
||||
|
||||
use std::mem;
|
||||
use std::{cell::OnceCell, mem};
|
||||
|
||||
use base_db::FxIndexSet;
|
||||
use cfg::CfgOptions;
|
||||
|
|
@ -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,
|
||||
|
|
@ -416,6 +416,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 +514,7 @@ impl BindingList {
|
|||
}
|
||||
}
|
||||
|
||||
impl ExprCollector<'_> {
|
||||
impl<'db> ExprCollector<'db> {
|
||||
pub fn new(
|
||||
db: &dyn DefDatabase,
|
||||
module: ModuleId,
|
||||
|
|
@ -527,6 +528,7 @@ impl ExprCollector<'_> {
|
|||
module,
|
||||
def_map,
|
||||
local_def_map,
|
||||
lang_items: OnceCell::new(),
|
||||
store: ExpressionStoreBuilder::default(),
|
||||
expander,
|
||||
current_try_block_label: None,
|
||||
|
|
@ -539,6 +541,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 +1661,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 +1760,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 +1844,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
|
||||
|
|
@ -2773,11 +2782,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 +2864,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 +3049,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 +3103,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 +3164,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 +3192,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 +3237,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 +3245,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 +3261,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 +3277,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 +3297,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 +3320,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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1091,15 +1091,15 @@ impl Printer<'_> {
|
|||
}};
|
||||
}
|
||||
match *it {
|
||||
LangItemTarget::ImplDef(it) => w!(self, "{it:?}"),
|
||||
LangItemTarget::ImplId(it) => w!(self, "{it:?}"),
|
||||
LangItemTarget::EnumId(it) => write_name!(it),
|
||||
LangItemTarget::Function(it) => write_name!(it),
|
||||
LangItemTarget::Static(it) => write_name!(it),
|
||||
LangItemTarget::Struct(it) => write_name!(it),
|
||||
LangItemTarget::Union(it) => write_name!(it),
|
||||
LangItemTarget::TypeAlias(it) => write_name!(it),
|
||||
LangItemTarget::Trait(it) => write_name!(it),
|
||||
LangItemTarget::EnumVariant(it) => write_name!(it),
|
||||
LangItemTarget::FunctionId(it) => write_name!(it),
|
||||
LangItemTarget::StaticId(it) => write_name!(it),
|
||||
LangItemTarget::StructId(it) => write_name!(it),
|
||||
LangItemTarget::UnionId(it) => write_name!(it),
|
||||
LangItemTarget::TypeAliasId(it) => write_name!(it),
|
||||
LangItemTarget::TraitId(it) => write_name!(it),
|
||||
LangItemTarget::EnumVariantId(it) => write_name!(it),
|
||||
}
|
||||
|
||||
if let Some(s) = s {
|
||||
|
|
|
|||
|
|
@ -2,101 +2,36 @@
|
|||
//!
|
||||
//! This attribute to tell the compiler about semi built-in std library
|
||||
//! features, such as Fn family of traits.
|
||||
use hir_expand::name::Name;
|
||||
use intern::{Symbol, sym};
|
||||
use rustc_hash::FxHashMap;
|
||||
use stdx::impl_from;
|
||||
|
||||
use crate::{
|
||||
AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId,
|
||||
StaticId, StructId, TraitId, TypeAliasId, UnionId,
|
||||
db::DefDatabase,
|
||||
expr_store::path::Path,
|
||||
nameres::{assoc::TraitItems, crate_def_map, crate_local_def_map},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum LangItemTarget {
|
||||
EnumId(EnumId),
|
||||
Function(FunctionId),
|
||||
ImplDef(ImplId),
|
||||
Static(StaticId),
|
||||
Struct(StructId),
|
||||
Union(UnionId),
|
||||
TypeAlias(TypeAliasId),
|
||||
Trait(TraitId),
|
||||
EnumVariant(EnumVariantId),
|
||||
FunctionId(FunctionId),
|
||||
ImplId(ImplId),
|
||||
StaticId(StaticId),
|
||||
StructId(StructId),
|
||||
UnionId(UnionId),
|
||||
TypeAliasId(TypeAliasId),
|
||||
TraitId(TraitId),
|
||||
EnumVariantId(EnumVariantId),
|
||||
}
|
||||
|
||||
impl LangItemTarget {
|
||||
pub fn as_enum(self) -> Option<EnumId> {
|
||||
match self {
|
||||
LangItemTarget::EnumId(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_function(self) -> Option<FunctionId> {
|
||||
match self {
|
||||
LangItemTarget::Function(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_impl_def(self) -> Option<ImplId> {
|
||||
match self {
|
||||
LangItemTarget::ImplDef(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_static(self) -> Option<StaticId> {
|
||||
match self {
|
||||
LangItemTarget::Static(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_struct(self) -> Option<StructId> {
|
||||
match self {
|
||||
LangItemTarget::Struct(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_trait(self) -> Option<TraitId> {
|
||||
match self {
|
||||
LangItemTarget::Trait(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_enum_variant(self) -> Option<EnumVariantId> {
|
||||
match self {
|
||||
LangItemTarget::EnumVariant(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_type_alias(self) -> Option<TypeAliasId> {
|
||||
match self {
|
||||
LangItemTarget::TypeAlias(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_adt(self) -> Option<AdtId> {
|
||||
match self {
|
||||
LangItemTarget::Union(it) => Some(it.into()),
|
||||
LangItemTarget::EnumId(it) => Some(it.into()),
|
||||
LangItemTarget::Struct(it) => Some(it.into()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_from!(
|
||||
EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId for LangItemTarget
|
||||
);
|
||||
|
||||
/// Salsa query. This will look for lang items in a specific crate.
|
||||
#[salsa_macros::tracked(returns(ref))]
|
||||
pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangItems>> {
|
||||
pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> LangItems {
|
||||
let _p = tracing::info_span!("crate_lang_items_query").entered();
|
||||
|
||||
let mut lang_items = LangItems::default();
|
||||
|
|
@ -105,15 +40,11 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt
|
|||
|
||||
for (_, module_data) in crate_def_map.modules() {
|
||||
for impl_def in module_data.scope.impls() {
|
||||
lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef);
|
||||
lang_items.collect_lang_item(db, impl_def);
|
||||
for &(_, assoc) in impl_def.impl_items(db).items.iter() {
|
||||
match assoc {
|
||||
AssocItemId::FunctionId(f) => {
|
||||
lang_items.collect_lang_item(db, f, LangItemTarget::Function)
|
||||
}
|
||||
AssocItemId::TypeAliasId(t) => {
|
||||
lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias)
|
||||
}
|
||||
AssocItemId::FunctionId(f) => lang_items.collect_lang_item(db, f),
|
||||
AssocItemId::TypeAliasId(t) => lang_items.collect_lang_item(db, t),
|
||||
AssocItemId::ConstId(_) => (),
|
||||
}
|
||||
}
|
||||
|
|
@ -122,62 +53,55 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt
|
|||
for def in module_data.scope.declarations() {
|
||||
match def {
|
||||
ModuleDefId::TraitId(trait_) => {
|
||||
lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait);
|
||||
lang_items.collect_lang_item(db, trait_);
|
||||
TraitItems::query(db, trait_).items.iter().for_each(|&(_, assoc_id)| {
|
||||
match assoc_id {
|
||||
AssocItemId::FunctionId(f) => {
|
||||
lang_items.collect_lang_item(db, f, LangItemTarget::Function);
|
||||
lang_items.collect_lang_item(db, f);
|
||||
}
|
||||
AssocItemId::TypeAliasId(alias) => {
|
||||
lang_items.collect_lang_item(db, alias, LangItemTarget::TypeAlias)
|
||||
lang_items.collect_lang_item(db, alias)
|
||||
}
|
||||
AssocItemId::ConstId(_) => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
ModuleDefId::AdtId(AdtId::EnumId(e)) => {
|
||||
lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
|
||||
lang_items.collect_lang_item(db, e);
|
||||
e.enum_variants(db).variants.iter().for_each(|&(id, _, _)| {
|
||||
lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
|
||||
lang_items.collect_lang_item(db, id);
|
||||
});
|
||||
}
|
||||
ModuleDefId::AdtId(AdtId::StructId(s)) => {
|
||||
lang_items.collect_lang_item(db, s, LangItemTarget::Struct);
|
||||
lang_items.collect_lang_item(db, s);
|
||||
}
|
||||
ModuleDefId::AdtId(AdtId::UnionId(u)) => {
|
||||
lang_items.collect_lang_item(db, u, LangItemTarget::Union);
|
||||
lang_items.collect_lang_item(db, u);
|
||||
}
|
||||
ModuleDefId::FunctionId(f) => {
|
||||
lang_items.collect_lang_item(db, f, LangItemTarget::Function);
|
||||
lang_items.collect_lang_item(db, f);
|
||||
}
|
||||
ModuleDefId::StaticId(s) => {
|
||||
lang_items.collect_lang_item(db, s, LangItemTarget::Static);
|
||||
lang_items.collect_lang_item(db, s);
|
||||
}
|
||||
ModuleDefId::TypeAliasId(t) => {
|
||||
lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias);
|
||||
lang_items.collect_lang_item(db, t);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if lang_items.items.is_empty() { None } else { Some(Box::new(lang_items)) }
|
||||
lang_items
|
||||
}
|
||||
|
||||
/// Salsa query. Look for a lang item, starting from the specified crate and recursively
|
||||
/// Salsa query. Look for a lang items, starting from the specified crate and recursively
|
||||
/// traversing its dependencies.
|
||||
#[salsa_macros::tracked]
|
||||
pub fn lang_item(
|
||||
db: &dyn DefDatabase,
|
||||
start_crate: Crate,
|
||||
item: LangItem,
|
||||
) -> Option<LangItemTarget> {
|
||||
let _p = tracing::info_span!("lang_item_query").entered();
|
||||
if let Some(target) =
|
||||
crate_lang_items(db, start_crate).as_ref().and_then(|it| it.items.get(&item).copied())
|
||||
{
|
||||
return Some(target);
|
||||
}
|
||||
#[salsa_macros::tracked(returns(ref))]
|
||||
pub fn lang_items(db: &dyn DefDatabase, start_crate: Crate) -> LangItems {
|
||||
let _p = tracing::info_span!("lang_items_query").entered();
|
||||
|
||||
let mut result = crate_lang_items(db, start_crate).clone();
|
||||
|
||||
// Our `CrateGraph` eagerly inserts sysroot dependencies like `core` or `std` into dependencies
|
||||
// even if the target crate has `#![no_std]`, `#![no_core]` or shadowed sysroot dependencies
|
||||
|
|
@ -186,42 +110,29 @@ pub fn lang_item(
|
|||
// while nameres.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust-analyzer/pull/20475 for details.
|
||||
crate_local_def_map(db, start_crate).local(db).extern_prelude().find_map(|(_, (krate, _))| {
|
||||
for (_, (krate, _)) in crate_local_def_map(db, start_crate).local(db).extern_prelude() {
|
||||
// Some crates declares themselves as extern crate like `extern crate self as core`.
|
||||
// Ignore these to prevent cycles.
|
||||
if krate.krate == start_crate { None } else { lang_item(db, krate.krate, item) }
|
||||
})
|
||||
}
|
||||
if krate.krate != start_crate {
|
||||
result.merge_prefer_self(lang_items(db, krate.krate));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LangItems {
|
||||
items: FxHashMap<LangItem, LangItemTarget>,
|
||||
result
|
||||
}
|
||||
|
||||
impl LangItems {
|
||||
pub fn target(&self, item: LangItem) -> Option<LangItemTarget> {
|
||||
self.items.get(&item).copied()
|
||||
}
|
||||
|
||||
fn collect_lang_item<T>(
|
||||
&mut self,
|
||||
db: &dyn DefDatabase,
|
||||
item: T,
|
||||
constructor: fn(T) -> LangItemTarget,
|
||||
) where
|
||||
T: Into<AttrDefId> + Copy,
|
||||
fn collect_lang_item<T>(&mut self, db: &dyn DefDatabase, item: T)
|
||||
where
|
||||
T: Into<AttrDefId> + Into<LangItemTarget> + Copy,
|
||||
{
|
||||
let _p = tracing::info_span!("collect_lang_item").entered();
|
||||
if let Some(lang_item) = lang_attr(db, item.into()) {
|
||||
self.items.entry(lang_item).or_insert_with(|| constructor(item));
|
||||
if let Some(lang_item) = db.attrs(item.into()).lang_item() {
|
||||
self.assign_lang_item(lang_item, item.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lang_attr(db: &dyn DefDatabase, item: AttrDefId) -> Option<LangItem> {
|
||||
db.attrs(item).lang_item()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(as_deref))]
|
||||
pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
|
||||
let mut traits = Vec::new();
|
||||
|
|
@ -249,173 +160,151 @@ pub enum GenericRequirement {
|
|||
|
||||
macro_rules! language_item_table {
|
||||
(
|
||||
$( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
|
||||
$( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $method:ident, $target:ident, $generics:expr; )*
|
||||
) => {
|
||||
|
||||
/// A representation of all the valid language items in Rust.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum LangItem {
|
||||
#[allow(non_snake_case)] // FIXME: Should we remove this?
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct LangItems {
|
||||
$(
|
||||
#[doc = concat!("The `", stringify!($name), "` lang item.")]
|
||||
$(#[$attr])*
|
||||
$variant,
|
||||
pub $lang_item: Option<$target>,
|
||||
)*
|
||||
}
|
||||
|
||||
impl LangItem {
|
||||
pub fn name(self) -> &'static str {
|
||||
match self {
|
||||
$( LangItem::$variant => stringify!($name), )*
|
||||
}
|
||||
impl LangItems {
|
||||
/// Merges `self` with `other`, with preference to `self` items.
|
||||
fn merge_prefer_self(&mut self, other: &Self) {
|
||||
$( self.$lang_item = self.$lang_item.or(other.$lang_item); )*
|
||||
}
|
||||
|
||||
/// Opposite of [`LangItem::name`]
|
||||
pub fn from_symbol(sym: &Symbol) -> Option<Self> {
|
||||
match sym {
|
||||
$(sym if *sym == $module::$name => Some(LangItem::$variant), )*
|
||||
_ => None,
|
||||
fn assign_lang_item(&mut self, name: &Symbol, target: LangItemTarget) {
|
||||
match name {
|
||||
$(
|
||||
_ if *name == $module::$name => {
|
||||
if let LangItemTarget::$target(target) = target {
|
||||
self.$lang_item = Some(target);
|
||||
}
|
||||
}
|
||||
)*
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LangItem {
|
||||
pub fn resolve_function(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<FunctionId> {
|
||||
lang_item(db, start_crate, self).and_then(|t| t.as_function())
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum LangItemEnum {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
$lang_item,
|
||||
)*
|
||||
}
|
||||
|
||||
pub fn resolve_trait(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<TraitId> {
|
||||
lang_item(db, start_crate, self).and_then(|t| t.as_trait())
|
||||
}
|
||||
|
||||
pub fn resolve_adt(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<AdtId> {
|
||||
lang_item(db, start_crate, self).and_then(|t| t.as_adt())
|
||||
}
|
||||
|
||||
pub fn resolve_enum(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<EnumId> {
|
||||
lang_item(db, start_crate, self).and_then(|t| t.as_enum())
|
||||
}
|
||||
|
||||
pub fn resolve_type_alias(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
start_crate: Crate,
|
||||
) -> Option<TypeAliasId> {
|
||||
lang_item(db, start_crate, self).and_then(|t| t.as_type_alias())
|
||||
}
|
||||
|
||||
/// Opposite of [`LangItem::name`]
|
||||
pub fn from_name(name: &hir_expand::name::Name) -> Option<Self> {
|
||||
Self::from_symbol(name.symbol())
|
||||
}
|
||||
|
||||
pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option<Path> {
|
||||
let t = lang_item(db, start_crate, *self)?;
|
||||
Some(Path::LangItem(t, None))
|
||||
}
|
||||
|
||||
pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option<Path> {
|
||||
let t = lang_item(db, start_crate, *self)?;
|
||||
Some(Path::LangItem(t, Some(seg)))
|
||||
impl LangItemEnum {
|
||||
#[inline]
|
||||
pub fn from_lang_items(self, lang_items: &LangItems) -> Option<LangItemTarget> {
|
||||
match self {
|
||||
$( LangItemEnum::$lang_item => lang_items.$lang_item.map(Into::into), )*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
language_item_table! {
|
||||
// Variant name, Name, Getter method name, Target Generic requirements;
|
||||
Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
MetaSized, sym::meta_sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
PointeeSized, sym::pointee_sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
Sized, sym::sized, sized_trait, TraitId, GenericRequirement::Exact(0);
|
||||
MetaSized, sym::meta_sized, sized_trait, TraitId, GenericRequirement::Exact(0);
|
||||
PointeeSized, sym::pointee_sized, sized_trait, TraitId, GenericRequirement::Exact(0);
|
||||
Unsize, sym::unsize, unsize_trait, TraitId, GenericRequirement::Minimum(1);
|
||||
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
|
||||
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
|
||||
StructuralPeq, sym::structural_peq, structural_peq_trait, TraitId, GenericRequirement::None;
|
||||
/// Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize).
|
||||
StructuralTeq, sym::structural_teq, structural_teq_trait, Target::Trait, GenericRequirement::None;
|
||||
Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
|
||||
Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
|
||||
StructuralTeq, sym::structural_teq, structural_teq_trait, TraitId, GenericRequirement::None;
|
||||
Copy, sym::copy, copy_trait, TraitId, GenericRequirement::Exact(0);
|
||||
Clone, sym::clone, clone_trait, TraitId, GenericRequirement::None;
|
||||
Sync, sym::sync, sync_trait, TraitId, GenericRequirement::Exact(0);
|
||||
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, TraitId, GenericRequirement::None;
|
||||
/// The associated item of the [`DiscriminantKind`] trait.
|
||||
Discriminant, sym::discriminant_type, discriminant_type, Target::AssocTy, GenericRequirement::None;
|
||||
Discriminant, sym::discriminant_type, discriminant_type, TypeAliasId, GenericRequirement::None;
|
||||
|
||||
PointeeTrait, sym::pointee_trait, pointee_trait, Target::Trait, GenericRequirement::None;
|
||||
Metadata, sym::metadata_type, metadata_type, Target::AssocTy, GenericRequirement::None;
|
||||
DynMetadata, sym::dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None;
|
||||
PointeeTrait, sym::pointee_trait, pointee_trait, TraitId, GenericRequirement::None;
|
||||
Metadata, sym::metadata_type, metadata_type, TypeAliasId, GenericRequirement::None;
|
||||
DynMetadata, sym::dyn_metadata, dyn_metadata, StructId, GenericRequirement::None;
|
||||
|
||||
Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
Freeze, sym::freeze, freeze_trait, TraitId, GenericRequirement::Exact(0);
|
||||
|
||||
FnPtrTrait, sym::fn_ptr_trait, fn_ptr_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
FnPtrAddr, sym::fn_ptr_addr, fn_ptr_addr, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
FnPtrTrait, sym::fn_ptr_trait, fn_ptr_trait, TraitId, GenericRequirement::Exact(0);
|
||||
FnPtrAddr, sym::fn_ptr_addr, fn_ptr_addr, FunctionId, GenericRequirement::None;
|
||||
|
||||
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
|
||||
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
|
||||
Drop, sym::drop, drop_trait, TraitId, GenericRequirement::None;
|
||||
Destruct, sym::destruct, destruct_trait, TraitId, GenericRequirement::None;
|
||||
|
||||
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, TraitId, GenericRequirement::Minimum(1);
|
||||
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, TraitId, GenericRequirement::Minimum(1);
|
||||
|
||||
// language items relating to transmutability
|
||||
TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0);
|
||||
TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(3);
|
||||
TransmuteOpts, sym::transmute_opts, transmute_opts, StructId, GenericRequirement::Exact(0);
|
||||
TransmuteTrait, sym::transmute_trait, transmute_trait, TraitId, GenericRequirement::Exact(3);
|
||||
|
||||
Add, sym::add, add_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Sub, sym::sub, sub_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Mul, sym::mul, mul_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Div, sym::div, div_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Rem, sym::rem, rem_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Neg, sym::neg, neg_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
Not, sym::not, not_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
BitXor, sym::bitxor, bitxor_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
BitAnd, sym::bitand, bitand_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
BitOr, sym::bitor, bitor_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Shl, sym::shl, shl_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Shr, sym::shr, shr_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
AddAssign, sym::add_assign, add_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
SubAssign, sym::sub_assign, sub_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
MulAssign, sym::mul_assign, mul_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
DivAssign, sym::div_assign, div_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
RemAssign, sym::rem_assign, rem_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
BitXorAssign, sym::bitxor_assign, bitxor_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
BitAndAssign, sym::bitand_assign, bitand_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
BitOrAssign, sym::bitor_assign, bitor_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
ShlAssign, sym::shl_assign, shl_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
ShrAssign, sym::shr_assign, shr_assign_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Index, sym::index, index_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
IndexMut, sym::index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Add, sym::add, add_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Sub, sym::sub, sub_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Mul, sym::mul, mul_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Div, sym::div, div_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Rem, sym::rem, rem_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Neg, sym::neg, neg_trait, TraitId, GenericRequirement::Exact(0);
|
||||
Not, sym::not, not_trait, TraitId, GenericRequirement::Exact(0);
|
||||
BitXor, sym::bitxor, bitxor_trait, TraitId, GenericRequirement::Exact(1);
|
||||
BitAnd, sym::bitand, bitand_trait, TraitId, GenericRequirement::Exact(1);
|
||||
BitOr, sym::bitor, bitor_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Shl, sym::shl, shl_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Shr, sym::shr, shr_trait, TraitId, GenericRequirement::Exact(1);
|
||||
AddAssign, sym::add_assign, add_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
SubAssign, sym::sub_assign, sub_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
MulAssign, sym::mul_assign, mul_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
DivAssign, sym::div_assign, div_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
RemAssign, sym::rem_assign, rem_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
BitXorAssign, sym::bitxor_assign, bitxor_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
BitAndAssign, sym::bitand_assign, bitand_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
BitOrAssign, sym::bitor_assign, bitor_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
ShlAssign, sym::shl_assign, shl_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
ShrAssign, sym::shr_assign, shr_assign_trait, TraitId, GenericRequirement::Exact(1);
|
||||
Index, sym::index, index_trait, TraitId, GenericRequirement::Exact(1);
|
||||
IndexMut, sym::index_mut, index_mut_trait, TraitId, GenericRequirement::Exact(1);
|
||||
|
||||
UnsafeCell, sym::unsafe_cell, unsafe_cell_type, Target::Struct, GenericRequirement::None;
|
||||
UnsafePinned, sym::unsafe_pinned, unsafe_pinned_type, Target::Struct, GenericRequirement::None;
|
||||
VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None;
|
||||
UnsafeCell, sym::unsafe_cell, unsafe_cell_type, StructId, GenericRequirement::None;
|
||||
UnsafePinned, sym::unsafe_pinned, unsafe_pinned_type, StructId, GenericRequirement::None;
|
||||
VaList, sym::va_list, va_list, StructId, GenericRequirement::None;
|
||||
|
||||
Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None;
|
||||
Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None;
|
||||
ReceiverTarget, sym::receiver_target, receiver_target, Target::AssocTy, GenericRequirement::None;
|
||||
Deref, sym::deref, deref_trait, TraitId, GenericRequirement::Exact(0);
|
||||
DerefMut, sym::deref_mut, deref_mut_trait, TraitId, GenericRequirement::Exact(0);
|
||||
DerefTarget, sym::deref_target, deref_target, TypeAliasId, GenericRequirement::None;
|
||||
Receiver, sym::receiver, receiver_trait, TraitId, GenericRequirement::None;
|
||||
ReceiverTarget, sym::receiver_target, receiver_target, TypeAliasId, GenericRequirement::None;
|
||||
|
||||
Fn, sym::fn_, fn_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
FnOnce, sym::fn_once, fn_once_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
AsyncFn, sym::async_fn, async_fn_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
Fn, sym::fn_, fn_trait, TraitId, GenericRequirement::Exact(1);
|
||||
FnMut, sym::fn_mut, fn_mut_trait, TraitId, GenericRequirement::Exact(1);
|
||||
FnOnce, sym::fn_once, fn_once_trait, TraitId, GenericRequirement::Exact(1);
|
||||
AsyncFn, sym::async_fn, async_fn_trait, TraitId, GenericRequirement::Exact(1);
|
||||
AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, TraitId, GenericRequirement::Exact(1);
|
||||
AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, TraitId, GenericRequirement::Exact(1);
|
||||
|
||||
CallRefFuture, sym::call_ref_future, call_ref_future_ty, Target::AssocTy, GenericRequirement::None;
|
||||
CallOnceFuture, sym::call_once_future, call_once_future_ty, Target::AssocTy, GenericRequirement::None;
|
||||
AsyncFnOnceOutput, sym::async_fn_once_output, async_fn_once_output_ty, Target::AssocTy, GenericRequirement::None;
|
||||
CallRefFuture, sym::call_ref_future, call_ref_future_ty, TypeAliasId, GenericRequirement::None;
|
||||
CallOnceFuture, sym::call_once_future, call_once_future_ty, TypeAliasId, GenericRequirement::None;
|
||||
AsyncFnOnceOutput, sym::async_fn_once_output, async_fn_once_output_ty, TypeAliasId, GenericRequirement::None;
|
||||
|
||||
FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None;
|
||||
FnOnceOutput, sym::fn_once_output, fn_once_output, TypeAliasId, GenericRequirement::None;
|
||||
|
||||
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None;
|
||||
Coroutine, sym::coroutine, coroutine_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
CoroutineReturn, sym::coroutine_return, coroutine_return_ty, Target::AssocTy, GenericRequirement::None;
|
||||
CoroutineYield, sym::coroutine_yield, coroutine_yield_ty, Target::AssocTy, GenericRequirement::None;
|
||||
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
|
||||
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;
|
||||
Future, sym::future_trait, future_trait, TraitId, GenericRequirement::Exact(0);
|
||||
CoroutineState, sym::coroutine_state, coroutine_state, EnumId, GenericRequirement::None;
|
||||
Coroutine, sym::coroutine, coroutine_trait, TraitId, GenericRequirement::Minimum(1);
|
||||
CoroutineReturn, sym::coroutine_return, coroutine_return_ty, TypeAliasId, GenericRequirement::None;
|
||||
CoroutineYield, sym::coroutine_yield, coroutine_yield_ty, TypeAliasId, GenericRequirement::None;
|
||||
Unpin, sym::unpin, unpin_trait, TraitId, GenericRequirement::None;
|
||||
Pin, sym::pin, pin_type, StructId, GenericRequirement::None;
|
||||
|
||||
PartialEq, sym::eq, eq_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
PartialOrd, sym::partial_ord, partial_ord_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
CVoid, sym::c_void, c_void, Target::Enum, GenericRequirement::None;
|
||||
PartialEq, sym::eq, eq_trait, TraitId, GenericRequirement::Exact(1);
|
||||
PartialOrd, sym::partial_ord, partial_ord_trait, TraitId, GenericRequirement::Exact(1);
|
||||
CVoid, sym::c_void, c_void, EnumId, GenericRequirement::None;
|
||||
|
||||
// A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
|
||||
// various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
|
||||
|
|
@ -424,107 +313,107 @@ language_item_table! {
|
|||
// in the sense that a crate is not required to have it defined to use it, but a final product
|
||||
// is required to define it somewhere. Additionally, there are restrictions on crates that use
|
||||
// a weak lang item, but do not have it defined.
|
||||
Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::Exact(0);
|
||||
PanicNounwind, sym::panic_nounwind, panic_nounwind, Target::Fn, GenericRequirement::Exact(0);
|
||||
PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None;
|
||||
PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None;
|
||||
ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None;
|
||||
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0);
|
||||
PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0);
|
||||
PanicInfo, sym::panic_info, panic_info, Target::Struct, GenericRequirement::None;
|
||||
PanicLocation, sym::panic_location, panic_location, Target::Struct, GenericRequirement::None;
|
||||
PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None;
|
||||
PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, Target::Fn, GenericRequirement::Exact(0);
|
||||
PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None;
|
||||
Panic, sym::panic, panic_fn, FunctionId, GenericRequirement::Exact(0);
|
||||
PanicNounwind, sym::panic_nounwind, panic_nounwind, FunctionId, GenericRequirement::Exact(0);
|
||||
PanicFmt, sym::panic_fmt, panic_fmt, FunctionId, GenericRequirement::None;
|
||||
PanicDisplay, sym::panic_display, panic_display, FunctionId, GenericRequirement::None;
|
||||
ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, FunctionId, GenericRequirement::None;
|
||||
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, FunctionId, GenericRequirement::Exact(0);
|
||||
PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, FunctionId, GenericRequirement::Exact(0);
|
||||
PanicInfo, sym::panic_info, panic_info, StructId, GenericRequirement::None;
|
||||
PanicLocation, sym::panic_location, panic_location, StructId, GenericRequirement::None;
|
||||
PanicImpl, sym::panic_impl, panic_impl, FunctionId, GenericRequirement::None;
|
||||
PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, FunctionId, GenericRequirement::Exact(0);
|
||||
PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, FunctionId, GenericRequirement::None;
|
||||
/// libstd panic entry point. Necessary for const eval to be able to catch it
|
||||
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
|
||||
BeginPanic, sym::begin_panic, begin_panic_fn, FunctionId, GenericRequirement::None;
|
||||
|
||||
// Lang items needed for `format_args!()`.
|
||||
FormatAlignment, sym::format_alignment, format_alignment, Target::Enum, GenericRequirement::None;
|
||||
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
|
||||
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
|
||||
FormatCount, sym::format_count, format_count, Target::Enum, GenericRequirement::None;
|
||||
FormatPlaceholder, sym::format_placeholder, format_placeholder, Target::Struct, GenericRequirement::None;
|
||||
FormatUnsafeArg, sym::format_unsafe_arg, format_unsafe_arg, Target::Struct, GenericRequirement::None;
|
||||
FormatAlignment, sym::format_alignment, format_alignment, EnumId, GenericRequirement::None;
|
||||
FormatArgument, sym::format_argument, format_argument, StructId, GenericRequirement::None;
|
||||
FormatArguments, sym::format_arguments, format_arguments, StructId, GenericRequirement::None;
|
||||
FormatCount, sym::format_count, format_count, EnumId, GenericRequirement::None;
|
||||
FormatPlaceholder, sym::format_placeholder, format_placeholder, StructId, GenericRequirement::None;
|
||||
FormatUnsafeArg, sym::format_unsafe_arg, format_unsafe_arg, StructId, GenericRequirement::None;
|
||||
|
||||
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
|
||||
BoxFree, sym::box_free, box_free_fn, Target::Fn, GenericRequirement::Minimum(1);
|
||||
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
|
||||
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
|
||||
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, FunctionId, GenericRequirement::None;
|
||||
BoxFree, sym::box_free, box_free_fn, FunctionId, GenericRequirement::Minimum(1);
|
||||
DropInPlace, sym::drop_in_place, drop_in_place_fn, FunctionId, GenericRequirement::Minimum(1);
|
||||
AllocLayout, sym::alloc_layout, alloc_layout, StructId, GenericRequirement::None;
|
||||
|
||||
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
|
||||
Start, sym::start, start_fn, FunctionId, GenericRequirement::Exact(1);
|
||||
|
||||
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
|
||||
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;
|
||||
EhPersonality, sym::eh_personality, eh_personality, FunctionId, GenericRequirement::None;
|
||||
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, StaticId, GenericRequirement::None;
|
||||
|
||||
OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);
|
||||
OwnedBox, sym::owned_box, owned_box, StructId, GenericRequirement::Minimum(1);
|
||||
|
||||
PhantomData, sym::phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1);
|
||||
PhantomData, sym::phantom_data, phantom_data, StructId, GenericRequirement::Exact(1);
|
||||
|
||||
ManuallyDrop, sym::manually_drop, manually_drop, Target::Struct, GenericRequirement::None;
|
||||
ManuallyDrop, sym::manually_drop, manually_drop, StructId, GenericRequirement::None;
|
||||
|
||||
MaybeUninit, sym::maybe_uninit, maybe_uninit, Target::Union, GenericRequirement::None;
|
||||
MaybeUninit, sym::maybe_uninit, maybe_uninit, UnionId, GenericRequirement::None;
|
||||
|
||||
/// Align offset for stride != 1; must not panic.
|
||||
AlignOffset, sym::align_offset, align_offset_fn, Target::Fn, GenericRequirement::None;
|
||||
AlignOffset, sym::align_offset, align_offset_fn, FunctionId, GenericRequirement::None;
|
||||
|
||||
Termination, sym::termination, termination, Target::Trait, GenericRequirement::None;
|
||||
Termination, sym::termination, termination, TraitId, GenericRequirement::None;
|
||||
|
||||
Try, sym::Try, try_trait, Target::Trait, GenericRequirement::None;
|
||||
Try, sym::Try, try_trait, TraitId, GenericRequirement::None;
|
||||
|
||||
Tuple, sym::tuple_trait, tuple_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
Tuple, sym::tuple_trait, tuple_trait, TraitId, GenericRequirement::Exact(0);
|
||||
|
||||
SliceLen, sym::slice_len_fn, slice_len_fn, Target::Method(MethodKind::Inherent), GenericRequirement::None;
|
||||
SliceLen, sym::slice_len_fn, slice_len_fn, FunctionId, GenericRequirement::None;
|
||||
|
||||
// Language items from AST lowering
|
||||
TryTraitFromResidual, sym::from_residual, from_residual_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
TryTraitFromOutput, sym::from_output, from_output_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None;
|
||||
TryTraitFromResidual, sym::from_residual, from_residual_fn, FunctionId, GenericRequirement::None;
|
||||
TryTraitFromOutput, sym::from_output, from_output_fn, FunctionId, GenericRequirement::None;
|
||||
TryTraitBranch, sym::branch, branch_fn, FunctionId, GenericRequirement::None;
|
||||
TryTraitFromYeet, sym::from_yeet, from_yeet_fn, FunctionId, GenericRequirement::None;
|
||||
|
||||
PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0);
|
||||
PointerLike, sym::pointer_like, pointer_like, TraitId, GenericRequirement::Exact(0);
|
||||
|
||||
ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
ConstParamTy, sym::const_param_ty, const_param_ty_trait, TraitId, GenericRequirement::Exact(0);
|
||||
|
||||
Poll, sym::Poll, poll, Target::Enum, GenericRequirement::None;
|
||||
PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None;
|
||||
PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None;
|
||||
Poll, sym::Poll, poll, EnumId, GenericRequirement::None;
|
||||
PollReady, sym::Ready, poll_ready_variant, EnumVariantId, GenericRequirement::None;
|
||||
PollPending, sym::Pending, poll_pending_variant, EnumVariantId, GenericRequirement::None;
|
||||
|
||||
// FIXME(swatinem): the following lang items are used for async lowering and
|
||||
// should become obsolete eventually.
|
||||
ResumeTy, sym::ResumeTy, resume_ty, Target::Struct, GenericRequirement::None;
|
||||
GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None;
|
||||
ResumeTy, sym::ResumeTy, resume_ty, StructId, GenericRequirement::None;
|
||||
GetContext, sym::get_context, get_context_fn, FunctionId, GenericRequirement::None;
|
||||
|
||||
Context, sym::Context, context, Target::Struct, GenericRequirement::None;
|
||||
FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
FutureOutput, sym::future_output, future_output, Target::TypeAlias, GenericRequirement::None;
|
||||
Context, sym::Context, context, StructId, GenericRequirement::None;
|
||||
FuturePoll, sym::poll, future_poll_fn, FunctionId, GenericRequirement::None;
|
||||
FutureOutput, sym::future_output, future_output, TypeAliasId, GenericRequirement::None;
|
||||
|
||||
Option, sym::Option, option_type, Target::Enum, GenericRequirement::None;
|
||||
OptionSome, sym::Some, option_some_variant, Target::Variant, GenericRequirement::None;
|
||||
OptionNone, sym::None, option_none_variant, Target::Variant, GenericRequirement::None;
|
||||
Option, sym::Option, option_type, EnumId, GenericRequirement::None;
|
||||
OptionSome, sym::Some, option_some_variant, EnumVariantId, GenericRequirement::None;
|
||||
OptionNone, sym::None, option_none_variant, EnumVariantId, GenericRequirement::None;
|
||||
|
||||
ResultOk, sym::Ok, result_ok_variant, Target::Variant, GenericRequirement::None;
|
||||
ResultErr, sym::Err, result_err_variant, Target::Variant, GenericRequirement::None;
|
||||
ResultOk, sym::Ok, result_ok_variant, EnumVariantId, GenericRequirement::None;
|
||||
ResultErr, sym::Err, result_err_variant, EnumVariantId, GenericRequirement::None;
|
||||
|
||||
ControlFlowContinue, sym::Continue, cf_continue_variant, Target::Variant, GenericRequirement::None;
|
||||
ControlFlowBreak, sym::Break, cf_break_variant, Target::Variant, GenericRequirement::None;
|
||||
ControlFlowContinue, sym::Continue, cf_continue_variant, EnumVariantId, GenericRequirement::None;
|
||||
ControlFlowBreak, sym::Break, cf_break_variant, EnumVariantId, GenericRequirement::None;
|
||||
|
||||
IntoFutureIntoFuture, sym::into_future, into_future_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false}), GenericRequirement::None;
|
||||
Iterator, sym::iterator, iterator, Target::Trait, GenericRequirement::None;
|
||||
IntoFutureIntoFuture, sym::into_future, into_future_fn, FunctionId, GenericRequirement::None;
|
||||
IntoIterIntoIter, sym::into_iter, into_iter_fn, FunctionId, GenericRequirement::None;
|
||||
IteratorNext, sym::next, next_fn, FunctionId, GenericRequirement::None;
|
||||
Iterator, sym::iterator, iterator, TraitId, GenericRequirement::None;
|
||||
|
||||
PinNewUnchecked, sym::new_unchecked, new_unchecked_fn, Target::Method(MethodKind::Inherent), GenericRequirement::None;
|
||||
PinNewUnchecked, sym::new_unchecked, new_unchecked_fn, FunctionId, GenericRequirement::None;
|
||||
|
||||
RangeFrom, sym::RangeFrom, range_from_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeFull, sym::RangeFull, range_full_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeInclusiveStruct, sym::RangeInclusive, range_inclusive_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeInclusiveNew, sym::range_inclusive_new, range_inclusive_new_method, Target::Method(MethodKind::Inherent), GenericRequirement::None;
|
||||
Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeFrom, sym::RangeFrom, range_from_struct, StructId, GenericRequirement::None;
|
||||
RangeFull, sym::RangeFull, range_full_struct, StructId, GenericRequirement::None;
|
||||
RangeInclusiveStruct, sym::RangeInclusive, range_inclusive_struct, StructId, GenericRequirement::None;
|
||||
RangeInclusiveNew, sym::range_inclusive_new, range_inclusive_new_method, FunctionId, GenericRequirement::None;
|
||||
Range, sym::Range, range_struct, StructId, GenericRequirement::None;
|
||||
RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, StructId, GenericRequirement::None;
|
||||
RangeTo, sym::RangeTo, range_to_struct, StructId, GenericRequirement::None;
|
||||
|
||||
String, sym::String, string, Target::Struct, GenericRequirement::None;
|
||||
CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None;
|
||||
Ordering, sym::Ordering, ordering, Target::Enum, GenericRequirement::None;
|
||||
String, sym::String, string, StructId, GenericRequirement::None;
|
||||
CStr, sym::CStr, c_str, StructId, GenericRequirement::None;
|
||||
Ordering, sym::Ordering, ordering, EnumId, GenericRequirement::None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,15 +186,15 @@ impl<'db> Resolver<'db> {
|
|||
Path::Normal(it) => &it.mod_path,
|
||||
Path::LangItem(l, seg) => {
|
||||
let type_ns = match *l {
|
||||
LangItemTarget::Union(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
|
||||
LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
|
||||
LangItemTarget::UnionId(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::TypeAliasId(it) => TypeNs::TypeAliasId(it),
|
||||
LangItemTarget::StructId(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::EnumVariantId(it) => TypeNs::EnumVariantId(it),
|
||||
LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::Trait(it) => TypeNs::TraitId(it),
|
||||
LangItemTarget::Function(_)
|
||||
| LangItemTarget::ImplDef(_)
|
||||
| LangItemTarget::Static(_) => return None,
|
||||
LangItemTarget::TraitId(it) => TypeNs::TraitId(it),
|
||||
LangItemTarget::FunctionId(_)
|
||||
| LangItemTarget::ImplId(_)
|
||||
| LangItemTarget::StaticId(_) => return None,
|
||||
};
|
||||
return Some((
|
||||
type_ns,
|
||||
|
|
@ -334,14 +334,14 @@ impl<'db> Resolver<'db> {
|
|||
return Some((
|
||||
ResolveValueResult::ValueNs(
|
||||
match *l {
|
||||
LangItemTarget::Function(it) => ValueNs::FunctionId(it),
|
||||
LangItemTarget::Static(it) => ValueNs::StaticId(it),
|
||||
LangItemTarget::Struct(it) => ValueNs::StructId(it),
|
||||
LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
|
||||
LangItemTarget::Union(_)
|
||||
| LangItemTarget::ImplDef(_)
|
||||
| LangItemTarget::TypeAlias(_)
|
||||
| LangItemTarget::Trait(_)
|
||||
LangItemTarget::FunctionId(it) => ValueNs::FunctionId(it),
|
||||
LangItemTarget::StaticId(it) => ValueNs::StaticId(it),
|
||||
LangItemTarget::StructId(it) => ValueNs::StructId(it),
|
||||
LangItemTarget::EnumVariantId(it) => ValueNs::EnumVariantId(it),
|
||||
LangItemTarget::UnionId(_)
|
||||
| LangItemTarget::ImplId(_)
|
||||
| LangItemTarget::TypeAliasId(_)
|
||||
| LangItemTarget::TraitId(_)
|
||||
| LangItemTarget::EnumId(_) => return None,
|
||||
},
|
||||
None,
|
||||
|
|
@ -351,15 +351,15 @@ impl<'db> Resolver<'db> {
|
|||
}
|
||||
Path::LangItem(l, Some(_)) => {
|
||||
let type_ns = match *l {
|
||||
LangItemTarget::Union(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
|
||||
LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
|
||||
LangItemTarget::UnionId(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::TypeAliasId(it) => TypeNs::TypeAliasId(it),
|
||||
LangItemTarget::StructId(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::EnumVariantId(it) => TypeNs::EnumVariantId(it),
|
||||
LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
|
||||
LangItemTarget::Trait(it) => TypeNs::TraitId(it),
|
||||
LangItemTarget::Function(_)
|
||||
| LangItemTarget::ImplDef(_)
|
||||
| LangItemTarget::Static(_) => return None,
|
||||
LangItemTarget::TraitId(it) => TypeNs::TraitId(it),
|
||||
LangItemTarget::FunctionId(_)
|
||||
| LangItemTarget::ImplId(_)
|
||||
| LangItemTarget::StaticId(_) => return None,
|
||||
};
|
||||
// Remaining segments start from 0 because lang paths have no segments other than the remaining.
|
||||
return Some((
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ use crate::{
|
|||
},
|
||||
hir::{ExprId, PatId, generics::GenericParams},
|
||||
item_tree::{FieldsShape, RawVisibility, visibility_from_ast},
|
||||
lang_item::LangItem,
|
||||
src::HasSource,
|
||||
type_ref::{TraitRef, TypeBound, TypeRefId},
|
||||
};
|
||||
|
|
@ -86,11 +85,11 @@ impl StructSignature {
|
|||
}
|
||||
if let Some(lang) = attrs.lang_item() {
|
||||
match lang {
|
||||
LangItem::PhantomData => flags |= StructFlags::IS_PHANTOM_DATA,
|
||||
LangItem::OwnedBox => flags |= StructFlags::IS_BOX,
|
||||
LangItem::ManuallyDrop => flags |= StructFlags::IS_MANUALLY_DROP,
|
||||
LangItem::UnsafeCell => flags |= StructFlags::IS_UNSAFE_CELL,
|
||||
LangItem::UnsafePinned => flags |= StructFlags::IS_UNSAFE_PINNED,
|
||||
_ if *lang == sym::phantom_data => flags |= StructFlags::IS_PHANTOM_DATA,
|
||||
_ if *lang == sym::owned_box => flags |= StructFlags::IS_BOX,
|
||||
_ if *lang == sym::manually_drop => flags |= StructFlags::IS_MANUALLY_DROP,
|
||||
_ if *lang == sym::unsafe_cell => flags |= StructFlags::IS_UNSAFE_CELL,
|
||||
_ if *lang == sym::unsafe_pinned => flags |= StructFlags::IS_UNSAFE_PINNED,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use hir_def::{TraitId, TypeAliasId, lang_item::LangItem};
|
||||
use hir_def::{TraitId, TypeAliasId};
|
||||
use rustc_type_ir::inherent::{IntoKind, Ty as _};
|
||||
use tracing::debug;
|
||||
use triomphe::Arc;
|
||||
|
|
@ -38,7 +38,7 @@ pub fn autoderef<'db>(
|
|||
env: Arc<TraitEnvironment<'db>>,
|
||||
ty: Canonical<'db, Ty<'db>>,
|
||||
) -> impl Iterator<Item = Ty<'db>> + use<'db> {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
let (ty, _) = infcx.instantiate_canonical(&ty);
|
||||
let autoderef = Autoderef::new(&infcx, &env, ty);
|
||||
|
|
@ -301,36 +301,28 @@ where
|
|||
self.infcx().interner
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn db(&self) -> &'db dyn HirDatabase {
|
||||
self.interner().db
|
||||
}
|
||||
|
||||
fn autoderef_traits(&mut self) -> Option<AutoderefTraits> {
|
||||
let lang_items = self.interner().lang_items();
|
||||
match &mut self.traits {
|
||||
Some(it) => Some(*it),
|
||||
None => {
|
||||
let traits = if self.use_receiver_trait {
|
||||
(|| {
|
||||
Some(AutoderefTraits {
|
||||
trait_: LangItem::Receiver
|
||||
.resolve_trait(self.db(), self.env().krate)?,
|
||||
trait_target: LangItem::ReceiverTarget
|
||||
.resolve_type_alias(self.db(), self.env().krate)?,
|
||||
trait_: lang_items.Receiver?,
|
||||
trait_target: lang_items.ReceiverTarget?,
|
||||
})
|
||||
})()
|
||||
.or_else(|| {
|
||||
Some(AutoderefTraits {
|
||||
trait_: LangItem::Deref.resolve_trait(self.db(), self.env().krate)?,
|
||||
trait_target: LangItem::DerefTarget
|
||||
.resolve_type_alias(self.db(), self.env().krate)?,
|
||||
trait_: lang_items.Deref?,
|
||||
trait_target: lang_items.DerefTarget?,
|
||||
})
|
||||
})?
|
||||
} else {
|
||||
AutoderefTraits {
|
||||
trait_: LangItem::Deref.resolve_trait(self.db(), self.env().krate)?,
|
||||
trait_target: LangItem::DerefTarget
|
||||
.resolve_type_alias(self.db(), self.env().krate)?,
|
||||
trait_: lang_items.Deref?,
|
||||
trait_target: lang_items.DerefTarget?,
|
||||
}
|
||||
};
|
||||
Some(*self.traits.insert(traits))
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ pub fn intern_const_ref<'a>(
|
|||
ty: Ty<'a>,
|
||||
krate: Crate,
|
||||
) -> Const<'a> {
|
||||
let interner = DbInterner::new_with(db, Some(krate), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let layout = db.layout_of_ty(ty, TraitEnvironment::empty(krate));
|
||||
let kind = match value {
|
||||
LiteralConstRef::Int(i) => {
|
||||
|
|
@ -128,7 +128,7 @@ pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option<u128>, krate: Cr
|
|||
intern_const_ref(
|
||||
db,
|
||||
&value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt),
|
||||
Ty::new_uint(DbInterner::new_with(db, Some(krate), None), rustc_type_ir::UintTy::Usize),
|
||||
Ty::new_uint(DbInterner::new_no_crate(db), rustc_type_ir::UintTy::Usize),
|
||||
krate,
|
||||
)
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ pub(crate) fn const_eval_discriminant_variant<'db>(
|
|||
db: &'db dyn HirDatabase,
|
||||
variant_id: EnumVariantId,
|
||||
) -> Result<i128, ConstEvalError<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let def = variant_id.into();
|
||||
let body = db.body(def);
|
||||
let loc = variant_id.lookup(db);
|
||||
|
|
@ -292,7 +292,7 @@ pub(crate) fn const_eval_static_query<'db>(
|
|||
db: &'db dyn HirDatabase,
|
||||
def: StaticId,
|
||||
) -> Result<Const<'db>, ConstEvalError<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let body = db.monomorphized_mir_body(
|
||||
def.into(),
|
||||
GenericArgs::new_from_iter(interner, []),
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ fn pretty_print_err(e: ConstEvalError<'_>, db: &TestDB) -> String {
|
|||
|
||||
fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEvalError<'_>> {
|
||||
let _tracing = setup_tracing();
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let module_id = db.module_for_file(file_id.file_id(db));
|
||||
let def_map = module_id.def_map(db);
|
||||
let scope = &def_map[module_id.local_id].scope;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use base_db::Crate;
|
|||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, DefWithBodyId, HasModule, ItemContainerId, Lookup,
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
resolver::{HasResolver, ValueNs},
|
||||
};
|
||||
use intern::sym;
|
||||
|
|
@ -79,7 +79,7 @@ impl BodyValidationDiagnostic {
|
|||
let infer = db.infer(owner);
|
||||
let body = db.body(owner);
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx =
|
||||
interner.infer_ctxt().build(TypingMode::typeck_for_body(interner, owner.into()));
|
||||
let mut validator = ExprValidator {
|
||||
|
|
@ -187,7 +187,7 @@ impl<'db> ExprValidator<'db> {
|
|||
};
|
||||
|
||||
let checker = filter_map_next_checker.get_or_insert_with(|| {
|
||||
FilterMapNextChecker::new(&self.owner.resolver(self.db()), self.db())
|
||||
FilterMapNextChecker::new(self.infcx.interner.lang_items(), self.db())
|
||||
});
|
||||
|
||||
if checker.check(call_id, receiver, &callee).is_some() {
|
||||
|
|
@ -497,11 +497,9 @@ struct FilterMapNextChecker<'db> {
|
|||
}
|
||||
|
||||
impl<'db> FilterMapNextChecker<'db> {
|
||||
fn new(resolver: &hir_def::resolver::Resolver<'db>, db: &'db dyn HirDatabase) -> Self {
|
||||
fn new(lang_items: &'db LangItems, db: &'db dyn HirDatabase) -> Self {
|
||||
// Find and store the FunctionIds for Iterator::filter_map and Iterator::next
|
||||
let (next_function_id, filter_map_function_id) = match LangItem::IteratorNext
|
||||
.resolve_function(db, resolver.krate())
|
||||
{
|
||||
let (next_function_id, filter_map_function_id) = match lang_items.IteratorNext {
|
||||
Some(next_function_id) => (
|
||||
Some(next_function_id),
|
||||
match next_function_id.lookup(db).container {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use hir_def::{
|
|||
hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
|
||||
item_scope::ItemInNs,
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
nameres::DefMap,
|
||||
signatures::VariantFields,
|
||||
type_ref::{
|
||||
|
|
@ -61,7 +61,7 @@ use crate::{
|
|||
infer::{DbInternerInferExt, traits::ObligationCause},
|
||||
},
|
||||
primitive,
|
||||
utils::{self, detect_variant_from_bytes},
|
||||
utils::{detect_variant_from_bytes, fn_traits},
|
||||
};
|
||||
|
||||
pub trait HirWrite: fmt::Write {
|
||||
|
|
@ -309,8 +309,7 @@ pub trait HirDisplay<'db> {
|
|||
allow_opaque: bool,
|
||||
) -> Result<String, DisplaySourceCodeError> {
|
||||
let mut result = String::new();
|
||||
let interner =
|
||||
DbInterner::new_with(db, Some(module_id.krate()), module_id.containing_block());
|
||||
let interner = DbInterner::new_with(db, module_id.krate(), module_id.containing_block());
|
||||
match self.hir_fmt(&mut HirFormatter {
|
||||
db,
|
||||
interner,
|
||||
|
|
@ -392,6 +391,11 @@ impl<'db> HirFormatter<'_, 'db> {
|
|||
self.display_target.edition
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn lang_items(&self) -> &'db LangItems {
|
||||
self.interner.lang_items()
|
||||
}
|
||||
|
||||
pub fn write_joined<T: HirDisplay<'db>>(
|
||||
&mut self,
|
||||
iter: impl IntoIterator<Item = T>,
|
||||
|
|
@ -544,7 +548,7 @@ impl<'db, T: HirDisplay<'db>> HirDisplayWrapper<'_, 'db, T> {
|
|||
DisplayKind::SourceCode { target_module_id, .. } => target_module_id.containing_block(),
|
||||
DisplayKind::Diagnostics | DisplayKind::Test => None,
|
||||
};
|
||||
let interner = DbInterner::new_with(self.db, Some(krate), block);
|
||||
let interner = DbInterner::new_with(self.db, krate, block);
|
||||
self.t.hir_fmt(&mut HirFormatter {
|
||||
db: self.db,
|
||||
interner,
|
||||
|
|
@ -1102,7 +1106,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
bounds.iter().any(|bound| match bound.skip_binder() {
|
||||
ExistentialPredicate::Trait(trait_ref) => {
|
||||
let trait_ = trait_ref.def_id.0;
|
||||
fn_traits(db, trait_).any(|it| it == trait_)
|
||||
fn_traits(f.lang_items()).any(|it| it == trait_)
|
||||
}
|
||||
_ => false,
|
||||
});
|
||||
|
|
@ -1146,7 +1150,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
let contains_impl_fn = bounds().any(|bound| {
|
||||
if let ClauseKind::Trait(trait_ref) = bound.kind().skip_binder() {
|
||||
let trait_ = trait_ref.def_id().0;
|
||||
fn_traits(db, trait_).any(|it| it == trait_)
|
||||
fn_traits(f.lang_items()).any(|it| it == trait_)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
@ -1588,8 +1592,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
..
|
||||
}
|
||||
| hir_def::hir::Expr::Async { .. } => {
|
||||
let future_trait =
|
||||
LangItem::Future.resolve_trait(db, owner.module(db).krate());
|
||||
let future_trait = f.lang_items().Future;
|
||||
let output = future_trait.and_then(|t| {
|
||||
t.trait_items(db)
|
||||
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
|
||||
|
|
@ -1799,11 +1802,6 @@ impl<'db> HirDisplay<'db> for Term<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = TraitId> + '_ {
|
||||
let krate = trait_.lookup(db).container.krate();
|
||||
utils::fn_traits(db, krate)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum SizedByDefault {
|
||||
NotSized,
|
||||
|
|
@ -1815,7 +1813,7 @@ impl SizedByDefault {
|
|||
match self {
|
||||
Self::NotSized => false,
|
||||
Self::Sized { anchor } => {
|
||||
let sized_trait = LangItem::Sized.resolve_trait(db, anchor);
|
||||
let sized_trait = hir_def::lang_item::lang_items(db, anchor).Sized;
|
||||
Some(trait_) == sized_trait
|
||||
}
|
||||
}
|
||||
|
|
@ -1868,7 +1866,7 @@ fn write_bounds_like_dyn_trait<'db>(
|
|||
}
|
||||
}
|
||||
if !is_fn_trait {
|
||||
is_fn_trait = fn_traits(f.db, trait_).any(|it| it == trait_);
|
||||
is_fn_trait = fn_traits(f.lang_items()).any(|it| it == trait_);
|
||||
}
|
||||
if !is_fn_trait && angle_open {
|
||||
write!(f, ">")?;
|
||||
|
|
@ -1966,7 +1964,7 @@ fn write_bounds_like_dyn_trait<'db>(
|
|||
write!(f, ">")?;
|
||||
}
|
||||
if let SizedByDefault::Sized { anchor } = default_sized {
|
||||
let sized_trait = LangItem::Sized.resolve_trait(f.db, anchor);
|
||||
let sized_trait = hir_def::lang_item::lang_items(f.db, anchor).Sized;
|
||||
if !is_sized {
|
||||
if !first {
|
||||
write!(f, " + ")?;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Utilities for computing drop info about types.
|
||||
|
||||
use hir_def::{AdtId, lang_item::LangItem, signatures::StructFlags};
|
||||
use hir_def::{AdtId, signatures::StructFlags};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike};
|
||||
use stdx::never;
|
||||
|
|
@ -8,22 +8,22 @@ use triomphe::Arc;
|
|||
|
||||
use crate::{
|
||||
TraitEnvironment, consteval,
|
||||
db::HirDatabase,
|
||||
method_resolution::TraitImpls,
|
||||
next_solver::{
|
||||
SimplifiedType, Ty, TyKind,
|
||||
DbInterner, SimplifiedType, Ty, TyKind,
|
||||
infer::{InferCtxt, traits::ObligationCause},
|
||||
obligation_ctxt::ObligationCtxt,
|
||||
},
|
||||
};
|
||||
|
||||
fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
||||
fn has_destructor(interner: DbInterner<'_>, adt: AdtId) -> bool {
|
||||
let db = interner.db;
|
||||
let module = match adt {
|
||||
AdtId::EnumId(id) => db.lookup_intern_enum(id).container,
|
||||
AdtId::StructId(id) => db.lookup_intern_struct(id).container,
|
||||
AdtId::UnionId(id) => db.lookup_intern_union(id).container,
|
||||
};
|
||||
let Some(drop_trait) = LangItem::Drop.resolve_trait(db, module.krate()) else {
|
||||
let Some(drop_trait) = interner.lang_items().Drop else {
|
||||
return false;
|
||||
};
|
||||
let impls = match module.containing_block() {
|
||||
|
|
@ -73,7 +73,7 @@ fn has_drop_glue_impl<'db>(
|
|||
match ty.kind() {
|
||||
TyKind::Adt(adt_def, subst) => {
|
||||
let adt_id = adt_def.def_id().0;
|
||||
if has_destructor(db, adt_id) {
|
||||
if has_destructor(infcx.interner, adt_id) {
|
||||
return DropGlue::HasDropGlue;
|
||||
}
|
||||
match adt_id {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::ops::ControlFlow;
|
|||
use hir_def::{
|
||||
AssocItemId, ConstId, CrateRootModuleId, FunctionId, GenericDefId, HasModule, TraitId,
|
||||
TypeAliasId, TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId,
|
||||
lang_item::LangItem, signatures::TraitFlags,
|
||||
signatures::TraitFlags,
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::{
|
||||
|
|
@ -53,7 +53,7 @@ pub fn dyn_compatibility(
|
|||
db: &dyn HirDatabase,
|
||||
trait_: TraitId,
|
||||
) -> Option<DynCompatibilityViolation> {
|
||||
let interner = DbInterner::new_with(db, Some(trait_.krate(db)), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
for super_trait in elaborate::supertrait_def_ids(interner, trait_.into()) {
|
||||
if let Some(v) = db.dyn_compatibility_of_trait(super_trait.0) {
|
||||
return if super_trait.0 == trait_ {
|
||||
|
|
@ -75,7 +75,7 @@ pub fn dyn_compatibility_with_callback<F>(
|
|||
where
|
||||
F: FnMut(DynCompatibilityViolation) -> ControlFlow<()>,
|
||||
{
|
||||
let interner = DbInterner::new_with(db, Some(trait_.krate(db)), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
for super_trait in elaborate::supertrait_def_ids(interner, trait_.into()).skip(1) {
|
||||
if db.dyn_compatibility_of_trait(super_trait.0).is_some() {
|
||||
cb(DynCompatibilityViolation::HasNonCompatibleSuperTrait(trait_))?;
|
||||
|
|
@ -131,11 +131,11 @@ pub fn dyn_compatibility_of_trait_query(
|
|||
|
||||
pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
|
||||
let krate = def.module(db).krate();
|
||||
let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else {
|
||||
let interner = DbInterner::new_with(db, krate, None);
|
||||
let Some(sized) = interner.lang_items().Sized else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let interner = DbInterner::new_with(db, Some(krate), None);
|
||||
let predicates = GenericPredicates::query_explicit(db, def);
|
||||
// FIXME: We should use `explicit_predicates_of` here, which hasn't been implemented to
|
||||
// rust-analyzer yet
|
||||
|
|
@ -234,34 +234,34 @@ fn contains_illegal_self_type_reference<'db, T: rustc_type_ir::TypeVisitable<DbI
|
|||
&mut self,
|
||||
ty: <DbInterner<'db> as rustc_type_ir::Interner>::Ty,
|
||||
) -> Self::Result {
|
||||
let interner = DbInterner::new_with(self.db, None, None);
|
||||
let interner = DbInterner::new_no_crate(self.db);
|
||||
match ty.kind() {
|
||||
rustc_type_ir::TyKind::Param(param) if param.index == 0 => ControlFlow::Break(()),
|
||||
rustc_type_ir::TyKind::Param(_) => ControlFlow::Continue(()),
|
||||
rustc_type_ir::TyKind::Alias(AliasTyKind::Projection, proj) => match self
|
||||
.allow_self_projection
|
||||
{
|
||||
AllowSelfProjection::Yes => {
|
||||
let trait_ = proj.trait_def_id(DbInterner::new_with(self.db, None, None));
|
||||
let trait_ = match trait_ {
|
||||
SolverDefId::TraitId(id) => id,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if self.super_traits.is_none() {
|
||||
self.super_traits = Some(
|
||||
elaborate::supertrait_def_ids(interner, self.trait_.into())
|
||||
.map(|super_trait| super_trait.0)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
rustc_type_ir::TyKind::Alias(AliasTyKind::Projection, proj) => {
|
||||
match self.allow_self_projection {
|
||||
AllowSelfProjection::Yes => {
|
||||
let trait_ = proj.trait_def_id(interner);
|
||||
let trait_ = match trait_ {
|
||||
SolverDefId::TraitId(id) => id,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if self.super_traits.is_none() {
|
||||
self.super_traits = Some(
|
||||
elaborate::supertrait_def_ids(interner, self.trait_.into())
|
||||
.map(|super_trait| super_trait.0)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
AllowSelfProjection::No => ty.super_visit_with(self),
|
||||
}
|
||||
AllowSelfProjection::No => ty.super_visit_with(self),
|
||||
},
|
||||
}
|
||||
_ => ty.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
|
|
@ -401,7 +401,8 @@ fn receiver_is_dispatchable<'db>(
|
|||
) -> bool {
|
||||
let sig = sig.instantiate_identity();
|
||||
|
||||
let interner: DbInterner<'_> = DbInterner::new_with(db, Some(trait_.krate(db)), None);
|
||||
let module = trait_.module(db);
|
||||
let interner = DbInterner::new_with(db, module.krate(), module.containing_block());
|
||||
let self_param_id = TypeParamId::from_unchecked(TypeOrConstParamId {
|
||||
parent: trait_.into(),
|
||||
local_id: LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)),
|
||||
|
|
@ -419,16 +420,13 @@ fn receiver_is_dispatchable<'db>(
|
|||
return false;
|
||||
};
|
||||
|
||||
let krate = func.module(db).krate();
|
||||
let traits = (
|
||||
LangItem::Unsize.resolve_trait(db, krate),
|
||||
LangItem::DispatchFromDyn.resolve_trait(db, krate),
|
||||
);
|
||||
let lang_items = interner.lang_items();
|
||||
let traits = (lang_items.Unsize, lang_items.DispatchFromDyn);
|
||||
let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let meta_sized_did = LangItem::MetaSized.resolve_trait(db, krate);
|
||||
let meta_sized_did = lang_items.MetaSized;
|
||||
let Some(meta_sized_did) = meta_sized_did else {
|
||||
return false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ use hir_def::{
|
|||
ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
|
||||
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
||||
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
|
||||
lang_item::{LangItem, LangItemTarget, lang_item},
|
||||
lang_item::LangItems,
|
||||
layout::Integer,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||
signatures::{ConstSignature, StaticSignature},
|
||||
|
|
@ -168,7 +168,7 @@ pub(crate) fn infer_cycle_result(
|
|||
) -> Arc<InferenceResult<'_>> {
|
||||
Arc::new(InferenceResult {
|
||||
has_errors: true,
|
||||
..InferenceResult::new(Ty::new_error(DbInterner::new_with(db, None, None), ErrorGuaranteed))
|
||||
..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -834,6 +834,7 @@ pub(crate) struct InferenceContext<'body, 'db> {
|
|||
pub(crate) edition: Edition,
|
||||
pub(crate) generic_def: GenericDefId,
|
||||
pub(crate) table: unify::InferenceTable<'db>,
|
||||
pub(crate) lang_items: &'db LangItems,
|
||||
/// The traits in scope, disregarding block modules. This is used for caching purposes.
|
||||
traits_in_scope: FxHashSet<TraitId>,
|
||||
pub(crate) result: InferenceResult<'db>,
|
||||
|
|
@ -939,6 +940,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
unstable_features: MethodResolutionUnstableFeatures::from_def_map(
|
||||
resolver.top_level_def_map(),
|
||||
),
|
||||
lang_items: table.interner().lang_items(),
|
||||
edition: resolver.krate().data(db).edition,
|
||||
table,
|
||||
tuple_field_accesses_rev: Default::default(),
|
||||
|
|
@ -1854,21 +1856,13 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
|
||||
let krate = self.resolver.krate();
|
||||
lang_item(self.db, krate, item)
|
||||
}
|
||||
|
||||
fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
|
||||
trait_.trait_items(self.db).associated_type_by_name(&Name::new_symbol_root(sym::Output))
|
||||
}
|
||||
|
||||
fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
|
||||
let ItemContainerId::TraitId(trait_) = self
|
||||
.resolve_lang_item(LangItem::IntoFutureIntoFuture)?
|
||||
.as_function()?
|
||||
.lookup(self.db)
|
||||
.container
|
||||
let ItemContainerId::TraitId(trait_) =
|
||||
self.lang_items.IntoFutureIntoFuture?.lookup(self.db).container
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
|
@ -1876,42 +1870,42 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
}
|
||||
|
||||
fn resolve_boxed_box(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::OwnedBox)?.as_struct()?;
|
||||
let struct_ = self.lang_items.OwnedBox?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_full(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::RangeFull)?.as_struct()?;
|
||||
let struct_ = self.lang_items.RangeFull?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::Range)?.as_struct()?;
|
||||
let struct_ = self.lang_items.Range?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_inclusive(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::RangeInclusiveStruct)?.as_struct()?;
|
||||
let struct_ = self.lang_items.RangeInclusiveStruct?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_from(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::RangeFrom)?.as_struct()?;
|
||||
let struct_ = self.lang_items.RangeFrom?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_to(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::RangeTo)?.as_struct()?;
|
||||
let struct_ = self.lang_items.RangeTo?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::RangeToInclusive)?.as_struct()?;
|
||||
let struct_ = self.lang_items.RangeToInclusive?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_va_list(&self) -> Option<AdtId> {
|
||||
let struct_ = self.resolve_lang_item(LangItem::VaList)?.as_struct()?;
|
||||
let struct_ = self.lang_items.VaList?;
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use std::{iter, mem, ops::ControlFlow};
|
|||
use hir_def::{
|
||||
TraitId,
|
||||
hir::{ClosureKind, ExprId, PatId},
|
||||
lang_item::LangItem,
|
||||
type_ref::TypeRefId,
|
||||
};
|
||||
use rustc_type_ir::{
|
||||
|
|
@ -220,11 +219,12 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
}
|
||||
|
||||
fn fn_trait_kind_from_def_id(&self, trait_id: TraitId) -> Option<rustc_type_ir::ClosureKind> {
|
||||
let lang_item = self.db.lang_attr(trait_id.into())?;
|
||||
match lang_item {
|
||||
LangItem::Fn => Some(rustc_type_ir::ClosureKind::Fn),
|
||||
LangItem::FnMut => Some(rustc_type_ir::ClosureKind::FnMut),
|
||||
LangItem::FnOnce => Some(rustc_type_ir::ClosureKind::FnOnce),
|
||||
match trait_id {
|
||||
_ if self.lang_items.Fn == Some(trait_id) => Some(rustc_type_ir::ClosureKind::Fn),
|
||||
_ if self.lang_items.FnMut == Some(trait_id) => Some(rustc_type_ir::ClosureKind::FnMut),
|
||||
_ if self.lang_items.FnOnce == Some(trait_id) => {
|
||||
Some(rustc_type_ir::ClosureKind::FnOnce)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -233,11 +233,14 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
&self,
|
||||
trait_id: TraitId,
|
||||
) -> Option<rustc_type_ir::ClosureKind> {
|
||||
let lang_item = self.db.lang_attr(trait_id.into())?;
|
||||
match lang_item {
|
||||
LangItem::AsyncFn => Some(rustc_type_ir::ClosureKind::Fn),
|
||||
LangItem::AsyncFnMut => Some(rustc_type_ir::ClosureKind::FnMut),
|
||||
LangItem::AsyncFnOnce => Some(rustc_type_ir::ClosureKind::FnOnce),
|
||||
match trait_id {
|
||||
_ if self.lang_items.AsyncFn == Some(trait_id) => Some(rustc_type_ir::ClosureKind::Fn),
|
||||
_ if self.lang_items.AsyncFnMut == Some(trait_id) => {
|
||||
Some(rustc_type_ir::ClosureKind::FnMut)
|
||||
}
|
||||
_ if self.lang_items.AsyncFnOnce == Some(trait_id) => {
|
||||
Some(rustc_type_ir::ClosureKind::FnOnce)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -433,21 +436,20 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
projection: PolyProjectionPredicate<'db>,
|
||||
) -> Option<PolyFnSig<'db>> {
|
||||
let SolverDefId::TypeAliasId(def_id) = projection.item_def_id() else { unreachable!() };
|
||||
let lang_item = self.db.lang_attr(def_id.into());
|
||||
|
||||
// For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
|
||||
// for closures and async closures, respectively.
|
||||
match closure_kind {
|
||||
ClosureKind::Closure if lang_item == Some(LangItem::FnOnceOutput) => {
|
||||
ClosureKind::Closure if Some(def_id) == self.lang_items.FnOnceOutput => {
|
||||
self.extract_sig_from_projection(projection)
|
||||
}
|
||||
ClosureKind::Async if lang_item == Some(LangItem::AsyncFnOnceOutput) => {
|
||||
ClosureKind::Async if Some(def_id) == self.lang_items.AsyncFnOnceOutput => {
|
||||
self.extract_sig_from_projection(projection)
|
||||
}
|
||||
// It's possible we've passed the closure to a (somewhat out-of-fashion)
|
||||
// `F: FnOnce() -> Fut, Fut: Future<Output = T>` style bound. Let's still
|
||||
// guide inference here, since it's beneficial for the user.
|
||||
ClosureKind::Async if lang_item == Some(LangItem::FnOnceOutput) => {
|
||||
ClosureKind::Async if Some(def_id) == self.lang_items.FnOnceOutput => {
|
||||
self.extract_sig_from_projection_and_future_bound(projection)
|
||||
}
|
||||
_ => None,
|
||||
|
|
@ -538,7 +540,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
&& let ret_projection = bound.predicate.kind().rebind(ret_projection)
|
||||
&& let Some(ret_projection) = ret_projection.no_bound_vars()
|
||||
&& let SolverDefId::TypeAliasId(assoc_type) = ret_projection.def_id()
|
||||
&& self.db.lang_attr(assoc_type.into()) == Some(LangItem::FutureOutput)
|
||||
&& Some(assoc_type) == self.lang_items.FutureOutput
|
||||
{
|
||||
return_ty = Some(ret_projection.term.expect_type());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ impl<'db> CapturedItem<'db> {
|
|||
}
|
||||
|
||||
pub fn ty(&self, db: &'db dyn HirDatabase, subst: GenericArgs<'db>) -> Ty<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
self.ty.instantiate(interner, subst.split_closure_args_untupled().parent_args)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
use hir_def::{
|
||||
CallableDefId,
|
||||
hir::{ExprId, ExprOrPatId},
|
||||
lang_item::LangItem,
|
||||
signatures::FunctionSignature,
|
||||
};
|
||||
use intern::sym;
|
||||
|
|
@ -612,10 +611,8 @@ where
|
|||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
|
||||
let traits = (
|
||||
LangItem::Unsize.resolve_trait(self.db(), self.env().krate),
|
||||
LangItem::CoerceUnsized.resolve_trait(self.db(), self.env().krate),
|
||||
);
|
||||
let lang_items = self.interner().lang_items();
|
||||
let traits = (lang_items.Unsize, lang_items.CoerceUnsized);
|
||||
let (Some(unsize_did), Some(coerce_unsized_did)) = traits else {
|
||||
debug!("missing Unsize or CoerceUnsized traits");
|
||||
return Err(TypeError::Mismatch);
|
||||
|
|
@ -1578,7 +1575,7 @@ fn coerce<'db>(
|
|||
env: Arc<TraitEnvironment<'db>>,
|
||||
tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
|
||||
) -> Result<(Vec<Adjustment<'db>>, Ty<'db>), TypeError<DbInterner<'db>>> {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
let ((ty1_with_vars, ty2_with_vars), vars) = infcx.instantiate_canonical(tys);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ use hir_def::{
|
|||
Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId,
|
||||
LabelId, Literal, Pat, PatId, Statement, UnaryOp,
|
||||
},
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
resolver::ValueNs,
|
||||
};
|
||||
use hir_def::{FunctionId, hir::ClosureKind};
|
||||
|
|
@ -877,14 +876,10 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
Literal::CString(..) => Ty::new_ref(
|
||||
self.interner(),
|
||||
self.types.re_static,
|
||||
self.resolve_lang_item(LangItem::CStr)
|
||||
.and_then(LangItemTarget::as_struct)
|
||||
.map_or_else(
|
||||
|| self.err_ty(),
|
||||
|strukt| {
|
||||
Ty::new_adt(self.interner(), strukt.into(), self.types.empty_args)
|
||||
},
|
||||
),
|
||||
self.lang_items.CStr.map_or_else(
|
||||
|| self.err_ty(),
|
||||
|strukt| Ty::new_adt(self.interner(), strukt.into(), self.types.empty_args),
|
||||
),
|
||||
Mutability::Not,
|
||||
),
|
||||
Literal::Char(..) => self.types.char,
|
||||
|
|
@ -1283,7 +1278,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
}
|
||||
}
|
||||
}
|
||||
let Some(trait_) = fn_x.get_id(self.db, self.table.trait_env.krate) else {
|
||||
let Some(trait_) = fn_x.get_id(self.lang_items) else {
|
||||
return;
|
||||
};
|
||||
let trait_data = trait_.trait_items(self.db);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
}
|
||||
|
||||
fn infer_mut_expr(&mut self, tgt_expr: ExprId, mut mutability: Mutability) {
|
||||
let krate = self.krate();
|
||||
if let Some(adjustments) = self.result.expr_adjustments.get_mut(&tgt_expr) {
|
||||
let mut adjustments = adjustments.iter_mut().rev().peekable();
|
||||
while let Some(adj) = adjustments.next() {
|
||||
|
|
@ -32,7 +31,6 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
};
|
||||
if let Some(infer_ok) = Self::try_mutable_overloaded_place_op(
|
||||
&self.table,
|
||||
krate,
|
||||
source_ty,
|
||||
None,
|
||||
PlaceOp::Deref,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::collections::hash_map;
|
||||
|
||||
use hir_def::{GenericParamId, TraitId, hir::ExprId, lang_item::LangItem};
|
||||
use hir_def::{GenericParamId, TraitId, hir::ExprId};
|
||||
use intern::{Symbol, sym};
|
||||
use rustc_ast_ir::Mutability;
|
||||
use rustc_type_ir::inherent::{IntoKind, Ty as _};
|
||||
|
|
@ -355,17 +355,18 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
|
|||
|
||||
fn lang_item_for_bin_op(&self, op: BinaryOp) -> (Symbol, Option<TraitId>) {
|
||||
let (method_name, trait_lang_item) =
|
||||
crate::lang_items::lang_items_for_bin_op(op).expect("invalid operator provided");
|
||||
(method_name, trait_lang_item.resolve_trait(self.db, self.krate()))
|
||||
crate::lang_items::lang_items_for_bin_op(self.lang_items, op)
|
||||
.expect("invalid operator provided");
|
||||
(method_name, trait_lang_item)
|
||||
}
|
||||
|
||||
fn lang_item_for_unop(&self, op: UnaryOp) -> (Symbol, Option<TraitId>) {
|
||||
let (method_name, trait_lang_item) = match op {
|
||||
UnaryOp::Not => (sym::not, LangItem::Not),
|
||||
UnaryOp::Neg => (sym::neg, LangItem::Neg),
|
||||
UnaryOp::Not => (sym::not, self.lang_items.Not),
|
||||
UnaryOp::Neg => (sym::neg, self.lang_items.Neg),
|
||||
UnaryOp::Deref => panic!("Deref is not overloadable"),
|
||||
};
|
||||
(method_name, trait_lang_item.resolve_trait(self.db, self.krate()))
|
||||
(method_name, trait_lang_item)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//! Inference of *place operators*: deref and indexing (operators that create places, as opposed to values).
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{hir::ExprId, lang_item::LangItem};
|
||||
use hir_def::hir::ExprId;
|
||||
use intern::sym;
|
||||
use rustc_ast_ir::Mutability;
|
||||
use rustc_type_ir::inherent::{IntoKind, Ty as _};
|
||||
|
|
@ -187,8 +186,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
|
|||
debug!("try_overloaded_place_op({:?},{:?})", base_ty, op);
|
||||
|
||||
let (Some(imm_tr), imm_op) = (match op {
|
||||
PlaceOp::Deref => (LangItem::Deref.resolve_trait(self.db, self.krate()), sym::deref),
|
||||
PlaceOp::Index => (LangItem::Index.resolve_trait(self.db, self.krate()), sym::index),
|
||||
PlaceOp::Deref => (self.lang_items.Deref, sym::deref),
|
||||
PlaceOp::Index => (self.lang_items.Index, sym::index),
|
||||
}) else {
|
||||
// Bail if `Deref` or `Index` isn't defined.
|
||||
return None;
|
||||
|
|
@ -209,16 +208,16 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
|
|||
|
||||
pub(super) fn try_mutable_overloaded_place_op(
|
||||
table: &InferenceTable<'db>,
|
||||
krate: Crate,
|
||||
base_ty: Ty<'db>,
|
||||
opt_rhs_ty: Option<Ty<'db>>,
|
||||
op: PlaceOp,
|
||||
) -> Option<InferOk<'db, MethodCallee<'db>>> {
|
||||
debug!("try_mutable_overloaded_place_op({:?},{:?})", base_ty, op);
|
||||
|
||||
let lang_items = table.interner().lang_items();
|
||||
let (Some(mut_tr), mut_op) = (match op {
|
||||
PlaceOp::Deref => (LangItem::DerefMut.resolve_trait(table.db, krate), sym::deref_mut),
|
||||
PlaceOp::Index => (LangItem::IndexMut.resolve_trait(table.db, krate), sym::index_mut),
|
||||
PlaceOp::Deref => (lang_items.DerefMut, sym::deref_mut),
|
||||
PlaceOp::Index => (lang_items.IndexMut, sym::index_mut),
|
||||
}) else {
|
||||
// Bail if `DerefMut` or `IndexMut` isn't defined.
|
||||
return None;
|
||||
|
|
@ -276,8 +275,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
|
|||
))
|
||||
}
|
||||
};
|
||||
let method =
|
||||
Self::try_mutable_overloaded_place_op(&self.table, self.krate(), base_ty, arg_ty, op);
|
||||
let method = Self::try_mutable_overloaded_place_op(&self.table, base_ty, arg_ty, op);
|
||||
let method = match method {
|
||||
Some(ok) => self.table.register_infer_ok(ok),
|
||||
// Couldn't find the mutable variant of the place op, keep the
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use hir_def::{AdtId, DefWithBodyId, GenericParamId, lang_item::LangItem};
|
||||
use hir_def::{AdtId, DefWithBodyId, GenericParamId};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
|
@ -113,7 +113,7 @@ fn could_unify_impl<'db>(
|
|||
tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
|
||||
select: for<'a> fn(&mut ObligationCtxt<'a, 'db>) -> Vec<NextSolverError<'db>>,
|
||||
) -> bool {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
let cause = ObligationCause::dummy();
|
||||
let at = infcx.at(&cause, env.env);
|
||||
|
|
@ -148,7 +148,7 @@ impl<'db> InferenceTable<'db> {
|
|||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
owner: Option<DefWithBodyId>,
|
||||
) -> Self {
|
||||
let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
|
||||
let interner = DbInterner::new_with(db, trait_env.krate, trait_env.block);
|
||||
let typing_mode = match owner {
|
||||
Some(owner) => TypingMode::typeck_for_body(interner, owner.into()),
|
||||
// IDE things wants to reveal opaque types.
|
||||
|
|
@ -174,7 +174,7 @@ impl<'db> InferenceTable<'db> {
|
|||
}
|
||||
|
||||
pub(crate) fn type_var_is_sized(&self, self_ty: TyVid) -> bool {
|
||||
let Some(sized_did) = LangItem::Sized.resolve_trait(self.db, self.trait_env.krate) else {
|
||||
let Some(sized_did) = self.interner().lang_items().Sized else {
|
||||
return true;
|
||||
};
|
||||
self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| {
|
||||
|
|
@ -520,13 +520,13 @@ impl<'db> InferenceTable<'db> {
|
|||
ty: Ty<'db>,
|
||||
num_args: usize,
|
||||
) -> Option<(FnTrait, Vec<Ty<'db>>, Ty<'db>)> {
|
||||
let lang_items = self.interner().lang_items();
|
||||
for (fn_trait_name, output_assoc_name, subtraits) in [
|
||||
(FnTrait::FnOnce, sym::Output, &[FnTrait::Fn, FnTrait::FnMut][..]),
|
||||
(FnTrait::AsyncFnMut, sym::CallRefFuture, &[FnTrait::AsyncFn]),
|
||||
(FnTrait::AsyncFnOnce, sym::CallOnceFuture, &[]),
|
||||
] {
|
||||
let krate = self.trait_env.krate;
|
||||
let fn_trait = fn_trait_name.get_id(self.db, krate)?;
|
||||
let fn_trait = fn_trait_name.get_id(lang_items)?;
|
||||
let trait_data = fn_trait.trait_items(self.db);
|
||||
let output_assoc_type =
|
||||
trait_data.associated_type_by_name(&Name::new_symbol_root(output_assoc_name))?;
|
||||
|
|
@ -558,7 +558,7 @@ impl<'db> InferenceTable<'db> {
|
|||
self.register_obligation(pred);
|
||||
let return_ty = self.normalize_alias_ty(projection);
|
||||
for &fn_x in subtraits {
|
||||
let fn_x_trait = fn_x.get_id(self.db, krate)?;
|
||||
let fn_x_trait = fn_x.get_id(lang_items)?;
|
||||
let trait_ref = TraitRef::new(self.interner(), fn_x_trait.into(), args);
|
||||
let pred = Predicate::upcast_from(trait_ref, self.interner());
|
||||
if !self.try_obligation(pred).no_solution() {
|
||||
|
|
@ -658,7 +658,7 @@ impl<'db> InferenceTable<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
let Some(sized) = LangItem::Sized.resolve_trait(self.db, self.trait_env.krate) else {
|
||||
let Some(sized) = self.interner().lang_items().Sized else {
|
||||
return false;
|
||||
};
|
||||
let sized_pred = Predicate::upcast_from(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Functions to detect special lang items
|
||||
|
||||
use hir_def::{AdtId, lang_item::LangItem, signatures::StructFlags};
|
||||
use hir_def::{AdtId, TraitId, lang_item::LangItems, signatures::StructFlags};
|
||||
use intern::{Symbol, sym};
|
||||
|
||||
use crate::db::HirDatabase;
|
||||
|
|
@ -10,48 +10,51 @@ pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
|||
db.struct_signature(id).flags.contains(StructFlags::IS_BOX)
|
||||
}
|
||||
|
||||
pub fn lang_items_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Symbol, LangItem)> {
|
||||
pub fn lang_items_for_bin_op(
|
||||
lang_items: &LangItems,
|
||||
op: syntax::ast::BinaryOp,
|
||||
) -> Option<(Symbol, Option<TraitId>)> {
|
||||
use syntax::ast::{ArithOp, BinaryOp, CmpOp, Ordering};
|
||||
Some(match op {
|
||||
BinaryOp::LogicOp(_) => return None,
|
||||
BinaryOp::ArithOp(aop) => match aop {
|
||||
ArithOp::Add => (sym::add, LangItem::Add),
|
||||
ArithOp::Mul => (sym::mul, LangItem::Mul),
|
||||
ArithOp::Sub => (sym::sub, LangItem::Sub),
|
||||
ArithOp::Div => (sym::div, LangItem::Div),
|
||||
ArithOp::Rem => (sym::rem, LangItem::Rem),
|
||||
ArithOp::Shl => (sym::shl, LangItem::Shl),
|
||||
ArithOp::Shr => (sym::shr, LangItem::Shr),
|
||||
ArithOp::BitXor => (sym::bitxor, LangItem::BitXor),
|
||||
ArithOp::BitOr => (sym::bitor, LangItem::BitOr),
|
||||
ArithOp::BitAnd => (sym::bitand, LangItem::BitAnd),
|
||||
ArithOp::Add => (sym::add, lang_items.Add),
|
||||
ArithOp::Mul => (sym::mul, lang_items.Mul),
|
||||
ArithOp::Sub => (sym::sub, lang_items.Sub),
|
||||
ArithOp::Div => (sym::div, lang_items.Div),
|
||||
ArithOp::Rem => (sym::rem, lang_items.Rem),
|
||||
ArithOp::Shl => (sym::shl, lang_items.Shl),
|
||||
ArithOp::Shr => (sym::shr, lang_items.Shr),
|
||||
ArithOp::BitXor => (sym::bitxor, lang_items.BitXor),
|
||||
ArithOp::BitOr => (sym::bitor, lang_items.BitOr),
|
||||
ArithOp::BitAnd => (sym::bitand, lang_items.BitAnd),
|
||||
},
|
||||
BinaryOp::Assignment { op: Some(aop) } => match aop {
|
||||
ArithOp::Add => (sym::add_assign, LangItem::AddAssign),
|
||||
ArithOp::Mul => (sym::mul_assign, LangItem::MulAssign),
|
||||
ArithOp::Sub => (sym::sub_assign, LangItem::SubAssign),
|
||||
ArithOp::Div => (sym::div_assign, LangItem::DivAssign),
|
||||
ArithOp::Rem => (sym::rem_assign, LangItem::RemAssign),
|
||||
ArithOp::Shl => (sym::shl_assign, LangItem::ShlAssign),
|
||||
ArithOp::Shr => (sym::shr_assign, LangItem::ShrAssign),
|
||||
ArithOp::BitXor => (sym::bitxor_assign, LangItem::BitXorAssign),
|
||||
ArithOp::BitOr => (sym::bitor_assign, LangItem::BitOrAssign),
|
||||
ArithOp::BitAnd => (sym::bitand_assign, LangItem::BitAndAssign),
|
||||
ArithOp::Add => (sym::add_assign, lang_items.AddAssign),
|
||||
ArithOp::Mul => (sym::mul_assign, lang_items.MulAssign),
|
||||
ArithOp::Sub => (sym::sub_assign, lang_items.SubAssign),
|
||||
ArithOp::Div => (sym::div_assign, lang_items.DivAssign),
|
||||
ArithOp::Rem => (sym::rem_assign, lang_items.RemAssign),
|
||||
ArithOp::Shl => (sym::shl_assign, lang_items.ShlAssign),
|
||||
ArithOp::Shr => (sym::shr_assign, lang_items.ShrAssign),
|
||||
ArithOp::BitXor => (sym::bitxor_assign, lang_items.BitXorAssign),
|
||||
ArithOp::BitOr => (sym::bitor_assign, lang_items.BitOrAssign),
|
||||
ArithOp::BitAnd => (sym::bitand_assign, lang_items.BitAndAssign),
|
||||
},
|
||||
BinaryOp::CmpOp(cop) => match cop {
|
||||
CmpOp::Eq { negated: false } => (sym::eq, LangItem::PartialEq),
|
||||
CmpOp::Eq { negated: true } => (sym::ne, LangItem::PartialEq),
|
||||
CmpOp::Eq { negated: false } => (sym::eq, lang_items.PartialEq),
|
||||
CmpOp::Eq { negated: true } => (sym::ne, lang_items.PartialEq),
|
||||
CmpOp::Ord { ordering: Ordering::Less, strict: false } => {
|
||||
(sym::le, LangItem::PartialOrd)
|
||||
(sym::le, lang_items.PartialOrd)
|
||||
}
|
||||
CmpOp::Ord { ordering: Ordering::Less, strict: true } => {
|
||||
(sym::lt, LangItem::PartialOrd)
|
||||
(sym::lt, lang_items.PartialOrd)
|
||||
}
|
||||
CmpOp::Ord { ordering: Ordering::Greater, strict: false } => {
|
||||
(sym::ge, LangItem::PartialOrd)
|
||||
(sym::ge, lang_items.PartialOrd)
|
||||
}
|
||||
CmpOp::Ord { ordering: Ordering::Greater, strict: true } => {
|
||||
(sym::gt, LangItem::PartialOrd)
|
||||
(sym::gt, lang_items.PartialOrd)
|
||||
}
|
||||
},
|
||||
BinaryOp::Assignment { op: None } => return None,
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ fn layout_of_simd_ty<'db>(
|
|||
let Some(TyKind::Array(e_ty, e_len)) = fields
|
||||
.next()
|
||||
.filter(|_| fields.next().is_none())
|
||||
.map(|f| (*f.1).instantiate(DbInterner::new_with(db, None, None), args).kind())
|
||||
.map(|f| (*f.1).instantiate(DbInterner::new_no_crate(db), args).kind())
|
||||
else {
|
||||
return Err(LayoutError::InvalidSimdType);
|
||||
};
|
||||
|
|
@ -161,7 +161,7 @@ pub fn layout_of_ty_query<'db>(
|
|||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
let krate = trait_env.krate;
|
||||
let interner = DbInterner::new_with(db, Some(krate), trait_env.block);
|
||||
let interner = DbInterner::new_with(db, krate, trait_env.block);
|
||||
let Ok(target) = db.target_data_layout(krate) else {
|
||||
return Err(LayoutError::TargetLayoutNotAvailable);
|
||||
};
|
||||
|
|
@ -401,7 +401,7 @@ fn field_ty<'a>(
|
|||
fd: LocalFieldId,
|
||||
args: &GenericArgs<'a>,
|
||||
) -> Ty<'a> {
|
||||
db.field_types(def)[fd].instantiate(DbInterner::new_with(db, None, None), args)
|
||||
db.field_types(def)[fd].instantiate(DbInterner::new_no_crate(db), args)
|
||||
}
|
||||
|
||||
fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ fn eval_goal(
|
|||
})
|
||||
.unwrap();
|
||||
crate::attach_db(&db, || {
|
||||
let interner = DbInterner::new_with(&db, None, None);
|
||||
let interner = DbInterner::new_no_crate(&db);
|
||||
let goal_ty = match adt_or_type_alias_id {
|
||||
Either::Left(adt_id) => crate::next_solver::Ty::new_adt(
|
||||
interner,
|
||||
|
|
|
|||
|
|
@ -477,14 +477,14 @@ pub fn callable_sig_from_fn_trait<'db>(
|
|||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
) -> Option<(FnTrait, PolyFnSig<'db>)> {
|
||||
let krate = trait_env.krate;
|
||||
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
|
||||
let mut table = InferenceTable::new(db, trait_env.clone(), None);
|
||||
let lang_items = table.interner().lang_items();
|
||||
|
||||
let fn_once_trait = FnTrait::FnOnce.get_id(lang_items)?;
|
||||
let output_assoc_type = fn_once_trait
|
||||
.trait_items(db)
|
||||
.associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
|
||||
|
||||
let mut table = InferenceTable::new(db, trait_env.clone(), None);
|
||||
|
||||
// Register two obligations:
|
||||
// - Self: FnOnce<?args_ty>
|
||||
// - <Self as FnOnce<?args_ty>>::Output == ?ret_ty
|
||||
|
|
@ -502,7 +502,7 @@ pub fn callable_sig_from_fn_trait<'db>(
|
|||
table.register_obligation(pred);
|
||||
let return_ty = table.normalize_alias_ty(projection);
|
||||
for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] {
|
||||
let fn_x_trait = fn_x.get_id(db, krate)?;
|
||||
let fn_x_trait = fn_x.get_id(lang_items)?;
|
||||
let trait_ref = TraitRef::new(table.interner(), fn_x_trait.into(), args);
|
||||
if !table
|
||||
.try_obligation(Predicate::upcast_from(trait_ref, table.interner()))
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ pub(crate) mod path;
|
|||
use std::{cell::OnceCell, iter, mem};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use base_db::Crate;
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
|
|
@ -24,7 +23,7 @@ use hir_def::{
|
|||
GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
|
||||
},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs},
|
||||
signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
|
||||
type_ref::{
|
||||
|
|
@ -166,6 +165,7 @@ impl<'db> LifetimeElisionKind<'db> {
|
|||
pub struct TyLoweringContext<'db, 'a> {
|
||||
pub db: &'db dyn HirDatabase,
|
||||
interner: DbInterner<'db>,
|
||||
lang_items: &'db LangItems,
|
||||
resolver: &'a Resolver<'db>,
|
||||
store: &'a ExpressionStore,
|
||||
def: GenericDefId,
|
||||
|
|
@ -193,7 +193,8 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
let in_binders = DebruijnIndex::ZERO;
|
||||
Self {
|
||||
db,
|
||||
interner: DbInterner::new_with(db, Some(resolver.krate()), None),
|
||||
interner: DbInterner::new_no_crate(db),
|
||||
lang_items: hir_def::lang_item::lang_items(db, resolver.krate()),
|
||||
resolver,
|
||||
def,
|
||||
generics: Default::default(),
|
||||
|
|
@ -490,7 +491,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
// away instead of two.
|
||||
let actual_opaque_type_data = self
|
||||
.with_debruijn(DebruijnIndex::ZERO, |ctx| {
|
||||
ctx.lower_impl_trait(opaque_ty_id, bounds, self.resolver.krate())
|
||||
ctx.lower_impl_trait(opaque_ty_id, bounds)
|
||||
});
|
||||
self.impl_trait_mode.opaque_type_data[idx] = actual_opaque_type_data;
|
||||
|
||||
|
|
@ -658,6 +659,8 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
ignore_bindings: bool,
|
||||
) -> impl Iterator<Item = Clause<'db>> + use<'b, 'a, 'db> {
|
||||
let interner = self.interner;
|
||||
let meta_sized = self.lang_items.MetaSized;
|
||||
let pointee_sized = self.lang_items.PointeeSized;
|
||||
let mut assoc_bounds = None;
|
||||
let mut clause = None;
|
||||
match bound {
|
||||
|
|
@ -666,10 +669,6 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
if let Some((trait_ref, mut ctx)) = self.lower_trait_ref_from_path(path, self_ty) {
|
||||
// FIXME(sized-hierarchy): Remove this bound modifications once we have implemented
|
||||
// sized-hierarchy correctly.
|
||||
let meta_sized = LangItem::MetaSized
|
||||
.resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
|
||||
let pointee_sized = LangItem::PointeeSized
|
||||
.resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
|
||||
if meta_sized.is_some_and(|it| it == trait_ref.def_id.0) {
|
||||
// Ignore this bound
|
||||
} else if pointee_sized.is_some_and(|it| it == trait_ref.def_id.0) {
|
||||
|
|
@ -692,7 +691,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
}
|
||||
}
|
||||
&TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
||||
let sized_trait = LangItem::Sized.resolve_trait(self.db, self.resolver.krate());
|
||||
let sized_trait = self.lang_items.Sized;
|
||||
// Don't lower associated type bindings as the only possible relaxed trait bound
|
||||
// `?Sized` has no of them.
|
||||
// If we got another trait here ignore the bound completely.
|
||||
|
|
@ -873,12 +872,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_impl_trait(
|
||||
&mut self,
|
||||
def_id: SolverDefId,
|
||||
bounds: &[TypeBound],
|
||||
krate: Crate,
|
||||
) -> ImplTrait<'db> {
|
||||
fn lower_impl_trait(&mut self, def_id: SolverDefId, bounds: &[TypeBound]) -> ImplTrait<'db> {
|
||||
let interner = self.interner;
|
||||
cov_mark::hit!(lower_rpit);
|
||||
let args = GenericArgs::identity_for_item(interner, def_id);
|
||||
|
|
@ -894,7 +888,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
|
|||
}
|
||||
|
||||
if !ctx.unsized_types.contains(&self_ty) {
|
||||
let sized_trait = LangItem::Sized.resolve_trait(self.db, krate);
|
||||
let sized_trait = self.lang_items.Sized;
|
||||
let sized_clause = sized_trait.map(|trait_id| {
|
||||
let trait_ref = TraitRef::new_from_args(
|
||||
interner,
|
||||
|
|
@ -1101,7 +1095,7 @@ impl ValueTyDefId {
|
|||
/// the constructor function `(usize) -> Foo` which lives in the values
|
||||
/// namespace.
|
||||
pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBinder<'db, Ty<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
match def {
|
||||
TyDefId::BuiltinType(it) => EarlyBinder::bind(Ty::from_builtin_type(interner, it)),
|
||||
TyDefId::AdtId(it) => EarlyBinder::bind(Ty::new_adt(
|
||||
|
|
@ -1116,7 +1110,7 @@ pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBind
|
|||
/// Build the declared type of a function. This should not need to look at the
|
||||
/// function body.
|
||||
fn type_for_fn<'db>(db: &'db dyn HirDatabase, def: FunctionId) -> EarlyBinder<'db, Ty<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
EarlyBinder::bind(Ty::new_fn_def(
|
||||
interner,
|
||||
CallableDefId::FunctionId(def).into(),
|
||||
|
|
@ -1165,7 +1159,7 @@ fn type_for_struct_constructor<'db>(
|
|||
FieldsShape::Record => None,
|
||||
FieldsShape::Unit => Some(type_for_adt(db, def.into())),
|
||||
FieldsShape::Tuple => {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
Some(EarlyBinder::bind(Ty::new_fn_def(
|
||||
interner,
|
||||
CallableDefId::StructId(def).into(),
|
||||
|
|
@ -1185,7 +1179,7 @@ fn type_for_enum_variant_constructor<'db>(
|
|||
FieldsShape::Record => None,
|
||||
FieldsShape::Unit => Some(type_for_adt(db, def.loc(db).parent.into())),
|
||||
FieldsShape::Tuple => {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
Some(EarlyBinder::bind(Ty::new_fn_def(
|
||||
interner,
|
||||
CallableDefId::EnumVariantId(def).into(),
|
||||
|
|
@ -1216,7 +1210,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>(
|
|||
let type_alias_data = db.type_alias_signature(t);
|
||||
let mut diags = None;
|
||||
let resolver = t.resolver(db);
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) {
|
||||
EarlyBinder::bind(Ty::new_foreign(interner, t.into()))
|
||||
} else {
|
||||
|
|
@ -1244,7 +1238,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result<'db>(
|
|||
db: &'db dyn HirDatabase,
|
||||
_adt: TypeAliasId,
|
||||
) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) {
|
||||
(EarlyBinder::bind(Ty::new_error(DbInterner::new_with(db, None, None), ErrorGuaranteed)), None)
|
||||
(EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None)
|
||||
}
|
||||
|
||||
pub(crate) fn impl_self_ty_query<'db>(
|
||||
|
|
@ -1277,7 +1271,7 @@ pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
|
|||
db: &dyn HirDatabase,
|
||||
_impl_id: ImplId,
|
||||
) -> (EarlyBinder<'_, Ty<'_>>, Diagnostics) {
|
||||
(EarlyBinder::bind(Ty::new_error(DbInterner::new_with(db, None, None), ErrorGuaranteed)), None)
|
||||
(EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None)
|
||||
}
|
||||
|
||||
pub(crate) fn const_param_ty_query<'db>(db: &'db dyn HirDatabase, def: ConstParamId) -> Ty<'db> {
|
||||
|
|
@ -1292,7 +1286,7 @@ pub(crate) fn const_param_ty_with_diagnostics_query<'db>(
|
|||
let (parent_data, store) = db.generic_params_and_store(def.parent());
|
||||
let data = &parent_data[def.local_id()];
|
||||
let resolver = def.parent().resolver(db);
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
|
|
@ -1313,10 +1307,9 @@ pub(crate) fn const_param_ty_with_diagnostics_query<'db>(
|
|||
pub(crate) fn const_param_ty_with_diagnostics_cycle_result<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
_: crate::db::HirDatabaseData,
|
||||
def: ConstParamId,
|
||||
_def: ConstParamId,
|
||||
) -> (Ty<'db>, Diagnostics) {
|
||||
let resolver = def.parent().resolver(db);
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
(Ty::new_error(interner, ErrorGuaranteed), None)
|
||||
}
|
||||
|
||||
|
|
@ -1374,7 +1367,7 @@ pub(crate) fn generic_predicates_for_param<'db>(
|
|||
assoc_name: Option<Name>,
|
||||
) -> EarlyBinder<'db, Box<[Clause<'db>]>> {
|
||||
let generics = generics(db, def);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let resolver = def.resolver(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
|
|
@ -1401,9 +1394,7 @@ pub(crate) fn generic_predicates_for_param<'db>(
|
|||
let TypeRef::Path(path) = &ctx.store[path.type_ref()] else {
|
||||
return false;
|
||||
};
|
||||
let Some(pointee_sized) =
|
||||
LangItem::PointeeSized.resolve_trait(ctx.db, ctx.resolver.krate())
|
||||
else {
|
||||
let Some(pointee_sized) = ctx.lang_items.PointeeSized else {
|
||||
return false;
|
||||
};
|
||||
// Lower the path directly with `Resolver` instead of PathLoweringContext`
|
||||
|
|
@ -1466,9 +1457,13 @@ pub(crate) fn generic_predicates_for_param<'db>(
|
|||
let args = GenericArgs::identity_for_item(interner, def.into());
|
||||
if !args.is_empty() {
|
||||
let explicitly_unsized_tys = ctx.unsized_types;
|
||||
if let Some(implicitly_sized_predicates) =
|
||||
implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &args, &resolver)
|
||||
{
|
||||
if let Some(implicitly_sized_predicates) = implicitly_sized_clauses(
|
||||
db,
|
||||
ctx.lang_items,
|
||||
param_id.parent,
|
||||
&explicitly_unsized_tys,
|
||||
&args,
|
||||
) {
|
||||
predicates.extend(implicitly_sized_predicates);
|
||||
};
|
||||
}
|
||||
|
|
@ -1520,8 +1515,7 @@ pub fn type_alias_bounds_with_diagnostics<'db>(
|
|||
}
|
||||
|
||||
if !ctx.unsized_types.contains(&interner_ty) {
|
||||
let sized_trait = LangItem::Sized
|
||||
.resolve_trait(ctx.db, interner.krate.expect("Must have interner.krate"));
|
||||
let sized_trait = ctx.lang_items.Sized;
|
||||
if let Some(sized_trait) = sized_trait {
|
||||
let trait_ref = TraitRef::new_from_args(
|
||||
interner,
|
||||
|
|
@ -1625,7 +1619,7 @@ pub(crate) fn trait_environment_query<'db>(
|
|||
def: GenericDefId,
|
||||
) -> Arc<TraitEnvironment<'db>> {
|
||||
let module = def.module(db);
|
||||
let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
|
||||
let interner = DbInterner::new_with(db, module.krate(), module.containing_block());
|
||||
let predicates = GenericPredicates::query_all(db, def);
|
||||
let traits_in_scope = predicates
|
||||
.iter_identity_copied()
|
||||
|
|
@ -1663,7 +1657,7 @@ where
|
|||
{
|
||||
let generics = generics(db, def);
|
||||
let resolver = def.resolver(db);
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
|
|
@ -1671,7 +1665,7 @@ where
|
|||
def,
|
||||
LifetimeElisionKind::AnonymousReportError,
|
||||
);
|
||||
let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
|
||||
let sized_trait = ctx.lang_items.Sized;
|
||||
|
||||
let mut predicates = Vec::new();
|
||||
let all_generics =
|
||||
|
|
@ -1811,7 +1805,7 @@ fn push_const_arg_has_type_predicates<'db>(
|
|||
predicates: &mut Vec<Clause<'db>>,
|
||||
generics: &Generics,
|
||||
) {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let const_params_offset = generics.len_parent() + generics.len_lifetimes_self();
|
||||
for (param_index, (param_idx, param_data)) in generics.iter_self_type_or_consts().enumerate() {
|
||||
if !matches!(param_data, TypeOrConstParamData::ConstParamData(_)) {
|
||||
|
|
@ -1839,13 +1833,13 @@ fn push_const_arg_has_type_predicates<'db>(
|
|||
/// Exception is Self of a trait def.
|
||||
fn implicitly_sized_clauses<'a, 'subst, 'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
lang_items: &LangItems,
|
||||
def: GenericDefId,
|
||||
explicitly_unsized_tys: &'a FxHashSet<Ty<'db>>,
|
||||
args: &'subst GenericArgs<'db>,
|
||||
resolver: &Resolver<'db>,
|
||||
) -> Option<impl Iterator<Item = Clause<'db>> + Captures<'a> + Captures<'subst>> {
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate())?;
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let sized_trait = lang_items.Sized?;
|
||||
|
||||
let trait_self_idx = trait_self_param_idx(db, def);
|
||||
|
||||
|
|
@ -1992,7 +1986,7 @@ fn fn_sig_for_fn<'db>(
|
|||
) -> EarlyBinder<'db, PolyFnSig<'db>> {
|
||||
let data = db.function_signature(def);
|
||||
let resolver = def.resolver(db);
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx_params = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
|
|
@ -2028,7 +2022,7 @@ fn fn_sig_for_fn<'db>(
|
|||
}
|
||||
|
||||
fn type_for_adt<'db>(db: &'db dyn HirDatabase, adt: AdtId) -> EarlyBinder<'db, Ty<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = GenericArgs::identity_for_item(interner, adt.into());
|
||||
let ty = Ty::new_adt(interner, adt, args);
|
||||
EarlyBinder::bind(ty)
|
||||
|
|
@ -2043,7 +2037,7 @@ fn fn_sig_for_struct_constructor<'db>(
|
|||
let ret = type_for_adt(db, def.into()).skip_binder();
|
||||
|
||||
let inputs_and_output =
|
||||
Tys::new_from_iter(DbInterner::new_with(db, None, None), params.chain(Some(ret)));
|
||||
Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret)));
|
||||
EarlyBinder::bind(Binder::dummy(FnSig {
|
||||
abi: FnAbi::RustCall,
|
||||
c_variadic: false,
|
||||
|
|
@ -2062,7 +2056,7 @@ fn fn_sig_for_enum_variant_constructor<'db>(
|
|||
let ret = type_for_adt(db, parent.into()).skip_binder();
|
||||
|
||||
let inputs_and_output =
|
||||
Tys::new_from_iter(DbInterner::new_with(db, None, None), params.chain(Some(ret)));
|
||||
Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret)));
|
||||
EarlyBinder::bind(Binder::dummy(FnSig {
|
||||
abi: FnAbi::RustCall,
|
||||
c_variadic: false,
|
||||
|
|
@ -2078,7 +2072,7 @@ pub(crate) fn associated_ty_item_bounds<'db>(
|
|||
) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> {
|
||||
let type_alias_data = db.type_alias_signature(type_alias);
|
||||
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
|
||||
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
|
|
@ -2139,7 +2133,7 @@ pub(crate) fn associated_ty_item_bounds<'db>(
|
|||
}
|
||||
|
||||
if !ctx.unsized_types.contains(&self_ty)
|
||||
&& let Some(sized_trait) = LangItem::Sized.resolve_trait(db, resolver.krate())
|
||||
&& let Some(sized_trait) = ctx.lang_items.Sized
|
||||
{
|
||||
let sized_clause = Binder::dummy(ExistentialPredicate::Trait(ExistentialTraitRef::new(
|
||||
interner,
|
||||
|
|
@ -2157,7 +2151,8 @@ pub(crate) fn associated_type_by_name_including_super_traits<'db>(
|
|||
trait_ref: TraitRef<'db>,
|
||||
name: &Name,
|
||||
) -> Option<(TraitRef<'db>, TypeAliasId)> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let module = trait_ref.def_id.0.module(db);
|
||||
let interner = DbInterner::new_with(db, module.krate(), module.containing_block());
|
||||
rustc_type_ir::elaborate::supertraits(interner, Binder::dummy(trait_ref)).find_map(|t| {
|
||||
let trait_id = t.as_ref().skip_binder().def_id.0;
|
||||
let assoc_type = trait_id.trait_items(db).associated_type_by_name(name)?;
|
||||
|
|
@ -2171,7 +2166,7 @@ pub fn associated_type_shorthand_candidates(
|
|||
res: TypeNs,
|
||||
mut cb: impl FnMut(&Name, TypeAliasId) -> bool,
|
||||
) -> Option<TypeAliasId> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
named_associated_type_shorthand_candidates(interner, def, res, None, |name, _, id| {
|
||||
cb(name, id).then_some(id)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1100,7 +1100,7 @@ pub(crate) fn substs_from_args_and_bindings<'db>(
|
|||
explicit_self_ty: Option<Ty<'db>>,
|
||||
ctx: &mut impl GenericArgsLowerer<'db>,
|
||||
) -> GenericArgs<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
tracing::debug!(?args_and_bindings);
|
||||
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ pub(crate) fn lookup_impl_method_query<'db>(
|
|||
func: FunctionId,
|
||||
fn_subst: GenericArgs<'db>,
|
||||
) -> (FunctionId, GenericArgs<'db>) {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
|
||||
let ItemContainerId::TraitId(trait_id) = func.loc(db).container else {
|
||||
|
|
@ -597,7 +597,7 @@ impl InherentImpls {
|
|||
continue;
|
||||
}
|
||||
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let self_ty = db.impl_self_ty(impl_id);
|
||||
let self_ty = self_ty.instantiate_identity();
|
||||
if let Some(self_ty) =
|
||||
|
|
@ -723,7 +723,7 @@ impl TraitImpls {
|
|||
None => continue,
|
||||
};
|
||||
let self_ty = trait_ref.self_ty();
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let entry = map.entry(trait_ref.def_id.0).or_default();
|
||||
match simplify_type(interner, self_ty, TreatParams::InstantiateWithInfer) {
|
||||
Some(self_ty) => {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use hir_def::{
|
|||
FunctionId, GenericDefId, GenericParamId, ItemContainerId, TraitId,
|
||||
expr_store::path::{GenericArg as HirGenericArg, GenericArgs as HirGenericArgs},
|
||||
hir::{ExprId, generics::GenericParamDataRef},
|
||||
lang_item::LangItem,
|
||||
};
|
||||
use rustc_type_ir::{
|
||||
TypeFoldable,
|
||||
|
|
@ -550,9 +549,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> {
|
|||
&self,
|
||||
predicates: impl Iterator<Item = Clause<'db>>,
|
||||
) -> bool {
|
||||
let Some(sized_def_id) =
|
||||
LangItem::Sized.resolve_trait(self.db(), self.ctx.resolver.krate())
|
||||
else {
|
||||
let Some(sized_def_id) = self.ctx.lang_items.Sized else {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
@ -570,9 +567,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> {
|
|||
fn check_for_illegal_method_calls(&self) {
|
||||
// Disallow calls to the method `drop` defined in the `Drop` trait.
|
||||
if let ItemContainerId::TraitId(trait_def_id) = self.candidate.loc(self.db()).container
|
||||
&& LangItem::Drop
|
||||
.resolve_trait(self.db(), self.ctx.resolver.krate())
|
||||
.is_some_and(|drop_trait| drop_trait == trait_def_id)
|
||||
&& self.ctx.lang_items.Drop.is_some_and(|drop_trait| drop_trait == trait_def_id)
|
||||
{
|
||||
// FIXME: Report an error.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ impl<'db> Operand<'db> {
|
|||
func_id: hir_def::FunctionId,
|
||||
generic_args: GenericArgs<'db>,
|
||||
) -> Operand<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = Ty::new_fn_def(interner, CallableDefId::FunctionId(func_id).into(), generic_args);
|
||||
Operand::from_bytes(Box::default(), ty)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ pub fn borrowck_query<'db>(
|
|||
) -> Result<Arc<[BorrowckResult<'db>]>, MirLowerError<'db>> {
|
||||
let _p = tracing::info_span!("borrowck_query").entered();
|
||||
let module = def.module(db);
|
||||
let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
|
||||
let interner = DbInterner::new_with(db, module.krate(), module.containing_block());
|
||||
let env = db.trait_environment_for_body(def);
|
||||
let mut res = vec![];
|
||||
// This calculates opaques defining scope which is a bit costly therefore is put outside `all_mir_bodies()`.
|
||||
|
|
@ -124,7 +124,7 @@ fn make_fetch_closure_field<'db>(
|
|||
let infer = db.infer(def);
|
||||
let (captures, _) = infer.closure_info(c);
|
||||
let parent_subst = subst.split_closure_args_untupled().parent_args;
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
captures.get(f).expect("broken closure field").ty.instantiate(interner, parent_subst)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use hir_def::{
|
|||
Lookup, StaticId, VariantId,
|
||||
expr_store::HygieneId,
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
layout::{TagEncoding, Variants},
|
||||
resolver::{HasResolver, TypeNs, ValueNs},
|
||||
signatures::{StaticFlags, StructFlags},
|
||||
|
|
@ -641,8 +641,9 @@ impl<'db> Evaluator<'db> {
|
|||
Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)),
|
||||
};
|
||||
let cached_ptr_size = target_data_layout.pointer_size().bytes_usize();
|
||||
let interner = DbInterner::new_with(db, Some(crate_id), module.containing_block());
|
||||
let interner = DbInterner::new_with(db, crate_id, module.containing_block());
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
let lang_items = interner.lang_items();
|
||||
Ok(Evaluator {
|
||||
target_data_layout,
|
||||
stack: vec![0],
|
||||
|
|
@ -667,13 +668,13 @@ impl<'db> Evaluator<'db> {
|
|||
mir_or_dyn_index_cache: RefCell::new(Default::default()),
|
||||
unused_locals_store: RefCell::new(Default::default()),
|
||||
cached_ptr_size,
|
||||
cached_fn_trait_func: LangItem::Fn
|
||||
.resolve_trait(db, crate_id)
|
||||
cached_fn_trait_func: lang_items
|
||||
.Fn
|
||||
.and_then(|x| x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call))),
|
||||
cached_fn_mut_trait_func: LangItem::FnMut.resolve_trait(db, crate_id).and_then(|x| {
|
||||
cached_fn_mut_trait_func: lang_items.FnMut.and_then(|x| {
|
||||
x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_mut))
|
||||
}),
|
||||
cached_fn_once_trait_func: LangItem::FnOnce.resolve_trait(db, crate_id).and_then(|x| {
|
||||
cached_fn_once_trait_func: lang_items.FnOnce.and_then(|x| {
|
||||
x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_once))
|
||||
}),
|
||||
infcx,
|
||||
|
|
@ -685,6 +686,11 @@ impl<'db> Evaluator<'db> {
|
|||
self.infcx.interner
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lang_items(&self) -> &'db LangItems {
|
||||
self.infcx.interner.lang_items()
|
||||
}
|
||||
|
||||
fn place_addr(&self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Address> {
|
||||
Ok(self.place_addr_and_ty_and_metadata(p, locals)?.0)
|
||||
}
|
||||
|
|
@ -2864,7 +2870,7 @@ impl<'db> Evaluator<'db> {
|
|||
span: MirSpan,
|
||||
) -> Result<'db, ()> {
|
||||
let Some(drop_fn) = (|| {
|
||||
let drop_trait = LangItem::Drop.resolve_trait(self.db, self.crate_id)?;
|
||||
let drop_trait = self.lang_items().Drop?;
|
||||
drop_trait.trait_items(self.db).method_by_name(&Name::new_symbol_root(sym::drop))
|
||||
})() else {
|
||||
// in some tests we don't have drop trait in minicore, and
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
//!
|
||||
use std::cmp::{self, Ordering};
|
||||
|
||||
use hir_def::{CrateRootModuleId, resolver::HasResolver, signatures::FunctionSignature};
|
||||
use hir_def::signatures::FunctionSignature;
|
||||
use hir_expand::name::Name;
|
||||
use intern::{Symbol, sym};
|
||||
use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike, Ty as _};
|
||||
|
|
@ -14,8 +14,8 @@ use crate::{
|
|||
drop::{DropGlue, has_drop_glue},
|
||||
mir::eval::{
|
||||
Address, AdtId, Arc, Evaluator, FunctionId, GenericArgs, HasModule, HirDisplay,
|
||||
InternedClosure, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, LangItem,
|
||||
Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, pad16,
|
||||
InternedClosure, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, Layout, Locals,
|
||||
Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, pad16,
|
||||
},
|
||||
next_solver::Region,
|
||||
};
|
||||
|
|
@ -38,6 +38,13 @@ macro_rules! not_supported {
|
|||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum EvalLangItem {
|
||||
BeginPanic,
|
||||
SliceLen,
|
||||
DropInPlace,
|
||||
}
|
||||
|
||||
impl<'db> Evaluator<'db> {
|
||||
pub(super) fn detect_and_exec_special_function(
|
||||
&mut self,
|
||||
|
|
@ -105,7 +112,7 @@ impl<'db> Evaluator<'db> {
|
|||
return Ok(true);
|
||||
}
|
||||
if let ItemContainerId::TraitId(t) = def.lookup(self.db).container
|
||||
&& self.db.lang_attr(t.into()) == Some(LangItem::Clone)
|
||||
&& Some(t) == self.lang_items().Clone
|
||||
{
|
||||
let [self_ty] = generic_args.as_slice() else {
|
||||
not_supported!("wrong generic arg count for clone");
|
||||
|
|
@ -131,12 +138,8 @@ impl<'db> Evaluator<'db> {
|
|||
def: FunctionId,
|
||||
) -> Result<'db, Option<FunctionId>> {
|
||||
// `PanicFmt` is redirected to `ConstPanicFmt`
|
||||
if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) {
|
||||
let resolver = CrateRootModuleId::from(self.crate_id).resolver(self.db);
|
||||
|
||||
let Some(const_panic_fmt) =
|
||||
LangItem::ConstPanicFmt.resolve_function(self.db, resolver.krate())
|
||||
else {
|
||||
if Some(def) == self.lang_items().PanicFmt {
|
||||
let Some(const_panic_fmt) = self.lang_items().ConstPanicFmt else {
|
||||
not_supported!("const_panic_fmt lang item not found or not a function");
|
||||
};
|
||||
return Ok(Some(const_panic_fmt));
|
||||
|
|
@ -286,19 +289,26 @@ impl<'db> Evaluator<'db> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn detect_lang_function(&self, def: FunctionId) -> Option<LangItem> {
|
||||
use LangItem::*;
|
||||
fn detect_lang_function(&self, def: FunctionId) -> Option<EvalLangItem> {
|
||||
use EvalLangItem::*;
|
||||
let lang_items = self.lang_items();
|
||||
let attrs = self.db.attrs(def.into());
|
||||
|
||||
if attrs.by_key(sym::rustc_const_panic_str).exists() {
|
||||
// `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE.
|
||||
return Some(LangItem::BeginPanic);
|
||||
return Some(BeginPanic);
|
||||
}
|
||||
|
||||
let candidate = attrs.lang_item()?;
|
||||
// We want to execute these functions with special logic
|
||||
// `PanicFmt` is not detected here as it's redirected later.
|
||||
if [BeginPanic, SliceLen, DropInPlace].contains(&candidate) {
|
||||
if let Some((_, candidate)) = [
|
||||
(lang_items.BeginPanic, BeginPanic),
|
||||
(lang_items.SliceLen, SliceLen),
|
||||
(lang_items.DropInPlace, DropInPlace),
|
||||
]
|
||||
.iter()
|
||||
.find(|&(candidate, _)| candidate == Some(def))
|
||||
{
|
||||
return Some(candidate);
|
||||
}
|
||||
|
||||
|
|
@ -307,13 +317,13 @@ impl<'db> Evaluator<'db> {
|
|||
|
||||
fn exec_lang_item(
|
||||
&mut self,
|
||||
it: LangItem,
|
||||
it: EvalLangItem,
|
||||
generic_args: GenericArgs<'db>,
|
||||
args: &[IntervalAndTy<'db>],
|
||||
locals: &Locals<'db>,
|
||||
span: MirSpan,
|
||||
) -> Result<'db, Vec<u8>> {
|
||||
use LangItem::*;
|
||||
use EvalLangItem::*;
|
||||
let mut args = args.iter();
|
||||
match it {
|
||||
BeginPanic => {
|
||||
|
|
@ -374,7 +384,6 @@ impl<'db> Evaluator<'db> {
|
|||
)?;
|
||||
Ok(vec![])
|
||||
}
|
||||
it => not_supported!("Executing lang item {it:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1219,7 +1228,7 @@ impl<'db> Evaluator<'db> {
|
|||
let addr = tuple.interval.addr.offset(offset);
|
||||
args.push(IntervalAndTy::new(addr, field, self, locals)?);
|
||||
}
|
||||
if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id)
|
||||
if let Some(target) = self.lang_items().FnOnce
|
||||
&& let Some(def) = target
|
||||
.trait_items(self.db)
|
||||
.method_by_name(&Name::new_symbol_root(sym::call_once))
|
||||
|
|
@ -1329,7 +1338,7 @@ impl<'db> Evaluator<'db> {
|
|||
{
|
||||
result = (l as i8).cmp(&(r as i8));
|
||||
}
|
||||
if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) {
|
||||
if let Some(e) = self.lang_items().Ordering {
|
||||
let ty = self.db.ty(e.into()).skip_binder();
|
||||
let r = self.compute_discriminant(ty, &[result as i8 as u8])?;
|
||||
destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use super::{MirEvalError, interpret_mir};
|
|||
|
||||
fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError<'_>> {
|
||||
crate::attach_db(db, || {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let module_id = db.module_for_file(file_id.file_id(db));
|
||||
let def_map = module_id.def_map(db);
|
||||
let scope = &def_map[module_id.local_id].scope;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use hir_def::{
|
|||
Pat, PatId, RecordFieldPat, RecordLitField,
|
||||
},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::{LangItem, LangItemTarget, lang_item},
|
||||
lang_item::LangItems,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
|
|
@ -110,7 +110,7 @@ pub enum MirLowerError<'db> {
|
|||
Loop,
|
||||
/// Something that should never happen and is definitely a bug, but we don't want to panic if it happened
|
||||
ImplementationError(String),
|
||||
LangItemNotFound(LangItem),
|
||||
LangItemNotFound,
|
||||
MutatingRvalue,
|
||||
UnresolvedLabel,
|
||||
UnresolvedUpvar(Place<'db>),
|
||||
|
|
@ -232,7 +232,7 @@ impl MirLowerError<'_> {
|
|||
| MirLowerError::BreakWithoutLoop
|
||||
| MirLowerError::Loop
|
||||
| MirLowerError::ImplementationError(_)
|
||||
| MirLowerError::LangItemNotFound(_)
|
||||
| MirLowerError::LangItemNotFound
|
||||
| MirLowerError::MutatingRvalue
|
||||
| MirLowerError::UnresolvedLabel
|
||||
| MirLowerError::UnresolvedUpvar(_) => writeln!(f, "{self:?}")?,
|
||||
|
|
@ -302,7 +302,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
|
|||
};
|
||||
let resolver = owner.resolver(db);
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
// FIXME(next-solver): Is `non_body_analysis()` correct here? Don't we want to reveal opaque types defined by this body?
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
|
||||
|
|
@ -327,6 +327,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
|
|||
self.infcx.interner
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lang_items(&self) -> &'db LangItems {
|
||||
self.infcx.interner.lang_items()
|
||||
}
|
||||
|
||||
fn temp(
|
||||
&mut self,
|
||||
ty: Ty<'db>,
|
||||
|
|
@ -1816,11 +1821,6 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_lang_item(&self, item: LangItem) -> Result<'db, LangItemTarget> {
|
||||
let crate_id = self.owner.module(self.db).krate();
|
||||
lang_item(self.db, crate_id, item).ok_or(MirLowerError::LangItemNotFound(item))
|
||||
}
|
||||
|
||||
fn lower_block_to_place(
|
||||
&mut self,
|
||||
statements: &[hir_def::hir::Statement],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use hir_def::FunctionId;
|
||||
use intern::sym;
|
||||
use rustc_type_ir::inherent::{AdtDef, Region as _, Ty as _};
|
||||
use rustc_type_ir::inherent::{Region as _, Ty as _};
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
|
|
@ -177,13 +177,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
|
|||
Expr::UnaryOp { expr, op: hir_def::hir::UnaryOp::Deref } => {
|
||||
let is_builtin = match self.expr_ty_without_adjust(*expr).kind() {
|
||||
TyKind::Ref(..) | TyKind::RawPtr(..) => true,
|
||||
TyKind::Adt(id, _) => {
|
||||
if let Some(lang_item) = self.db.lang_attr(id.def_id().0.into()) {
|
||||
lang_item == LangItem::OwnedBox
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
TyKind::Adt(id, _) => id.is_box(),
|
||||
_ => false,
|
||||
};
|
||||
if !is_builtin {
|
||||
|
|
@ -198,8 +192,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
|
|||
expr_id.into(),
|
||||
'b: {
|
||||
if let Some((f, _)) = self.infer.method_resolution(expr_id)
|
||||
&& let Some(deref_trait) =
|
||||
self.resolve_lang_item(LangItem::DerefMut)?.as_trait()
|
||||
&& let Some(deref_trait) = self.lang_items().DerefMut
|
||||
&& let Some(deref_fn) = deref_trait
|
||||
.trait_items(self.db)
|
||||
.method_by_name(&Name::new_symbol_root(sym::deref_mut))
|
||||
|
|
@ -330,17 +323,18 @@ impl<'db> MirLowerCtx<'_, 'db> {
|
|||
span: MirSpan,
|
||||
mutability: bool,
|
||||
) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
|
||||
let lang_items = self.lang_items();
|
||||
let (mutability, trait_lang_item, trait_method_name, borrow_kind) = if !mutability {
|
||||
(
|
||||
Mutability::Not,
|
||||
LangItem::Deref,
|
||||
lang_items.Deref,
|
||||
Name::new_symbol_root(sym::deref),
|
||||
BorrowKind::Shared,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
Mutability::Mut,
|
||||
LangItem::DerefMut,
|
||||
lang_items.DerefMut,
|
||||
Name::new_symbol_root(sym::deref_mut),
|
||||
BorrowKind::Mut { kind: MutBorrowKind::Default },
|
||||
)
|
||||
|
|
@ -350,14 +344,11 @@ impl<'db> MirLowerCtx<'_, 'db> {
|
|||
let target_ty_ref = Ty::new_ref(self.interner(), error_region, target_ty, mutability);
|
||||
let ref_place: Place<'db> = self.temp(ty_ref, current, span)?.into();
|
||||
self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span);
|
||||
let deref_trait = self
|
||||
.resolve_lang_item(trait_lang_item)?
|
||||
.as_trait()
|
||||
.ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?;
|
||||
let deref_trait = trait_lang_item.ok_or(MirLowerError::LangItemNotFound)?;
|
||||
let deref_fn = deref_trait
|
||||
.trait_items(self.db)
|
||||
.method_by_name(&trait_method_name)
|
||||
.ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?;
|
||||
.ok_or(MirLowerError::LangItemNotFound)?;
|
||||
let deref_fn_op = Operand::const_zst(Ty::new_fn_def(
|
||||
self.interner(),
|
||||
CallableDefId::FunctionId(deref_fn).into(),
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ impl<'db> Filler<'db> {
|
|||
env: Arc<TraitEnvironment<'db>>,
|
||||
subst: GenericArgs<'db>,
|
||||
) -> Self {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
Self { infcx, trait_env: env, subst }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use std::sync::Arc;
|
|||
pub use BoundRegionConversionTime::*;
|
||||
use ena::unify as ut;
|
||||
use hir_def::GenericParamId;
|
||||
use hir_def::lang_item::LangItem;
|
||||
use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage};
|
||||
use region_constraints::{RegionConstraintCollector, RegionConstraintStorage};
|
||||
use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
|
||||
|
|
@ -542,9 +541,7 @@ impl<'db> InferCtxt<'db> {
|
|||
pub fn type_is_copy_modulo_regions(&self, param_env: ParamEnv<'db>, ty: Ty<'db>) -> bool {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
|
||||
let Some(copy_def_id) =
|
||||
LangItem::Copy.resolve_trait(self.interner.db, self.interner.krate.unwrap())
|
||||
else {
|
||||
let Some(copy_def_id) = self.interner.lang_items().Copy else {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db};
|
|||
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
AdtId, AttrDefId, BlockId, CallableDefId, DefWithBodyId, EnumVariantId, HasModule,
|
||||
ItemContainerId, StructId, UnionId, VariantId,
|
||||
lang_item::LangItem,
|
||||
AdtId, BlockId, CallableDefId, DefWithBodyId, EnumVariantId, HasModule, ItemContainerId,
|
||||
StructId, UnionId, VariantId,
|
||||
lang_item::LangItems,
|
||||
signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags},
|
||||
};
|
||||
use la_arena::Idx;
|
||||
|
|
@ -272,6 +272,7 @@ pub struct DbInterner<'db> {
|
|||
pub(crate) db: &'db dyn HirDatabase,
|
||||
pub(crate) krate: Option<Crate>,
|
||||
pub(crate) block: Option<BlockId>,
|
||||
lang_items: Option<&'db LangItems>,
|
||||
}
|
||||
|
||||
// FIXME: very wrong, see https://github.com/rust-lang/rust/pull/144808
|
||||
|
|
@ -285,21 +286,48 @@ impl<'db> DbInterner<'db> {
|
|||
db: unsafe { std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(db) },
|
||||
krate: None,
|
||||
block: None,
|
||||
lang_items: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a new interner without an active crate. Good only for interning things, not for trait solving etc..
|
||||
/// As a rule of thumb, when you create an `InferCtxt`, you need to provide the crate (and the block).
|
||||
///
|
||||
/// Elaboration is a special kind: it needs lang items (for `Sized`), therefore it needs `new_with()`, but you
|
||||
/// can not specify the block.
|
||||
pub fn new_no_crate(db: &'db dyn HirDatabase) -> Self {
|
||||
DbInterner { db, krate: None, block: None, lang_items: None }
|
||||
}
|
||||
|
||||
pub fn new_with(
|
||||
db: &'db dyn HirDatabase,
|
||||
krate: Option<Crate>,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
) -> DbInterner<'db> {
|
||||
DbInterner { db, krate, block }
|
||||
DbInterner {
|
||||
db,
|
||||
krate: Some(krate),
|
||||
block,
|
||||
// As an approximation, when we call `new_with` we're trait solving, therefore we need the lang items.
|
||||
// This is also convenient since here we have a starting crate but not in `new_no_crate`.
|
||||
lang_items: Some(hir_def::lang_item::lang_items(db, krate)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn db(&self) -> &'db dyn HirDatabase {
|
||||
self.db
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub fn lang_items(&self) -> &'db LangItems {
|
||||
self.lang_items.expect(
|
||||
"Must have `DbInterner::lang_items`.\n\n\
|
||||
Note: you might have called `DbInterner::new_no_crate()` \
|
||||
where you should've called `DbInterner::new_with()`",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// This is intentionally left as `()`
|
||||
|
|
@ -849,7 +877,7 @@ interned_vec_db!(PatList, Pattern);
|
|||
|
||||
macro_rules! as_lang_item {
|
||||
(
|
||||
$solver_enum:ident, $var:ident;
|
||||
$solver_enum:ident, $self:ident, $def_id:expr;
|
||||
|
||||
ignore = {
|
||||
$( $ignore:ident ),* $(,)?
|
||||
|
|
@ -857,6 +885,7 @@ macro_rules! as_lang_item {
|
|||
|
||||
$( $variant:ident ),* $(,)?
|
||||
) => {{
|
||||
let lang_items = $self.lang_items();
|
||||
// Ensure exhaustiveness.
|
||||
if let Some(it) = None::<$solver_enum> {
|
||||
match it {
|
||||
|
|
@ -864,13 +893,32 @@ macro_rules! as_lang_item {
|
|||
$( $solver_enum::$ignore => {} )*
|
||||
}
|
||||
}
|
||||
match $var {
|
||||
$( LangItem::$variant => Some($solver_enum::$variant), )*
|
||||
match $def_id {
|
||||
$( def_id if lang_items.$variant.is_some_and(|it| it == def_id) => Some($solver_enum::$variant), )*
|
||||
_ => None
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! is_lang_item {
|
||||
(
|
||||
$solver_enum:ident, $self:ident, $def_id:expr, $expected_variant:ident;
|
||||
|
||||
ignore = {
|
||||
$( $ignore:ident ),* $(,)?
|
||||
}
|
||||
|
||||
$( $variant:ident ),* $(,)?
|
||||
) => {{
|
||||
let lang_items = $self.lang_items();
|
||||
let def_id = $def_id;
|
||||
match $expected_variant {
|
||||
$( $solver_enum::$variant => lang_items.$variant.is_some_and(|it| it == def_id), )*
|
||||
$( $solver_enum::$ignore => false, )*
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
impl<'db> Interner for DbInterner<'db> {
|
||||
type DefId = SolverDefId;
|
||||
type LocalDefId = SolverDefId;
|
||||
|
|
@ -1253,8 +1301,7 @@ impl<'db> Interner for DbInterner<'db> {
|
|||
}
|
||||
|
||||
fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
|
||||
let sized_trait =
|
||||
LangItem::Sized.resolve_trait(self.db(), self.krate.expect("Must have self.krate"));
|
||||
let sized_trait = self.lang_items().Sized;
|
||||
let Some(sized_id) = sized_trait else {
|
||||
return false; /* No Sized trait, can't require it! */
|
||||
};
|
||||
|
|
@ -1428,84 +1475,69 @@ impl<'db> Interner for DbInterner<'db> {
|
|||
}
|
||||
|
||||
fn require_lang_item(self, lang_item: SolverLangItem) -> Self::DefId {
|
||||
let lang_items = self.lang_items();
|
||||
let lang_item = match lang_item {
|
||||
SolverLangItem::AsyncFnKindUpvars => unimplemented!(),
|
||||
SolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
|
||||
SolverLangItem::CallOnceFuture => LangItem::CallOnceFuture,
|
||||
SolverLangItem::CallRefFuture => LangItem::CallRefFuture,
|
||||
SolverLangItem::CoroutineReturn => LangItem::CoroutineReturn,
|
||||
SolverLangItem::CoroutineYield => LangItem::CoroutineYield,
|
||||
SolverLangItem::DynMetadata => LangItem::DynMetadata,
|
||||
SolverLangItem::FutureOutput => LangItem::FutureOutput,
|
||||
SolverLangItem::Metadata => LangItem::Metadata,
|
||||
SolverLangItem::AsyncFnOnceOutput => lang_items.AsyncFnOnceOutput,
|
||||
SolverLangItem::CallOnceFuture => lang_items.CallOnceFuture,
|
||||
SolverLangItem::CallRefFuture => lang_items.CallRefFuture,
|
||||
SolverLangItem::CoroutineReturn => lang_items.CoroutineReturn,
|
||||
SolverLangItem::CoroutineYield => lang_items.CoroutineYield,
|
||||
SolverLangItem::FutureOutput => lang_items.FutureOutput,
|
||||
SolverLangItem::Metadata => lang_items.Metadata,
|
||||
SolverLangItem::DynMetadata => {
|
||||
return lang_items.DynMetadata.expect("Lang item required but not found.").into();
|
||||
}
|
||||
};
|
||||
let target = hir_def::lang_item::lang_item(
|
||||
self.db(),
|
||||
self.krate.expect("Must have self.krate"),
|
||||
lang_item,
|
||||
)
|
||||
.unwrap_or_else(|| panic!("Lang item {lang_item:?} required but not found."));
|
||||
match target {
|
||||
hir_def::lang_item::LangItemTarget::EnumId(enum_id) => enum_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::Function(function_id) => function_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::ImplDef(impl_id) => impl_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::Static(static_id) => static_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::Struct(struct_id) => struct_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::Union(union_id) => union_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::TypeAlias(type_alias_id) => type_alias_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::Trait(trait_id) => trait_id.into(),
|
||||
hir_def::lang_item::LangItemTarget::EnumVariant(_) => unimplemented!(),
|
||||
}
|
||||
lang_item.expect("Lang item required but not found.").into()
|
||||
}
|
||||
|
||||
fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> TraitIdWrapper {
|
||||
let lang_items = self.lang_items();
|
||||
let lang_item = match lang_item {
|
||||
SolverTraitLangItem::AsyncFn => LangItem::AsyncFn,
|
||||
SolverTraitLangItem::AsyncFn => lang_items.AsyncFn,
|
||||
SolverTraitLangItem::AsyncFnKindHelper => unimplemented!(),
|
||||
SolverTraitLangItem::AsyncFnMut => LangItem::AsyncFnMut,
|
||||
SolverTraitLangItem::AsyncFnOnce => LangItem::AsyncFnOnce,
|
||||
SolverTraitLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
|
||||
SolverTraitLangItem::AsyncFnMut => lang_items.AsyncFnMut,
|
||||
SolverTraitLangItem::AsyncFnOnce => lang_items.AsyncFnOnce,
|
||||
SolverTraitLangItem::AsyncFnOnceOutput => unimplemented!(
|
||||
"This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver."
|
||||
),
|
||||
SolverTraitLangItem::AsyncIterator => unimplemented!(),
|
||||
SolverTraitLangItem::Clone => LangItem::Clone,
|
||||
SolverTraitLangItem::Copy => LangItem::Copy,
|
||||
SolverTraitLangItem::Coroutine => LangItem::Coroutine,
|
||||
SolverTraitLangItem::Destruct => LangItem::Destruct,
|
||||
SolverTraitLangItem::DiscriminantKind => LangItem::DiscriminantKind,
|
||||
SolverTraitLangItem::Drop => LangItem::Drop,
|
||||
SolverTraitLangItem::Fn => LangItem::Fn,
|
||||
SolverTraitLangItem::FnMut => LangItem::FnMut,
|
||||
SolverTraitLangItem::FnOnce => LangItem::FnOnce,
|
||||
SolverTraitLangItem::FnPtrTrait => LangItem::FnPtrTrait,
|
||||
SolverTraitLangItem::Clone => lang_items.Clone,
|
||||
SolverTraitLangItem::Copy => lang_items.Copy,
|
||||
SolverTraitLangItem::Coroutine => lang_items.Coroutine,
|
||||
SolverTraitLangItem::Destruct => lang_items.Destruct,
|
||||
SolverTraitLangItem::DiscriminantKind => lang_items.DiscriminantKind,
|
||||
SolverTraitLangItem::Drop => lang_items.Drop,
|
||||
SolverTraitLangItem::Fn => lang_items.Fn,
|
||||
SolverTraitLangItem::FnMut => lang_items.FnMut,
|
||||
SolverTraitLangItem::FnOnce => lang_items.FnOnce,
|
||||
SolverTraitLangItem::FnPtrTrait => lang_items.FnPtrTrait,
|
||||
SolverTraitLangItem::FusedIterator => unimplemented!(),
|
||||
SolverTraitLangItem::Future => LangItem::Future,
|
||||
SolverTraitLangItem::Iterator => LangItem::Iterator,
|
||||
SolverTraitLangItem::PointeeTrait => LangItem::PointeeTrait,
|
||||
SolverTraitLangItem::Sized => LangItem::Sized,
|
||||
SolverTraitLangItem::MetaSized => LangItem::MetaSized,
|
||||
SolverTraitLangItem::PointeeSized => LangItem::PointeeSized,
|
||||
SolverTraitLangItem::TransmuteTrait => LangItem::TransmuteTrait,
|
||||
SolverTraitLangItem::Tuple => LangItem::Tuple,
|
||||
SolverTraitLangItem::Unpin => LangItem::Unpin,
|
||||
SolverTraitLangItem::Unsize => LangItem::Unsize,
|
||||
SolverTraitLangItem::Future => lang_items.Future,
|
||||
SolverTraitLangItem::Iterator => lang_items.Iterator,
|
||||
SolverTraitLangItem::PointeeTrait => lang_items.PointeeTrait,
|
||||
SolverTraitLangItem::Sized => lang_items.Sized,
|
||||
SolverTraitLangItem::MetaSized => lang_items.MetaSized,
|
||||
SolverTraitLangItem::PointeeSized => lang_items.PointeeSized,
|
||||
SolverTraitLangItem::TransmuteTrait => lang_items.TransmuteTrait,
|
||||
SolverTraitLangItem::Tuple => lang_items.Tuple,
|
||||
SolverTraitLangItem::Unpin => lang_items.Unpin,
|
||||
SolverTraitLangItem::Unsize => lang_items.Unsize,
|
||||
SolverTraitLangItem::BikeshedGuaranteedNoDrop => {
|
||||
unimplemented!()
|
||||
}
|
||||
};
|
||||
lang_item
|
||||
.resolve_trait(self.db(), self.krate.expect("Must have self.krate"))
|
||||
.unwrap_or_else(|| panic!("Lang item {lang_item:?} required but not found."))
|
||||
.into()
|
||||
lang_item.expect("Lang item required but not found.").into()
|
||||
}
|
||||
|
||||
fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> AdtIdWrapper {
|
||||
let lang_items = self.lang_items();
|
||||
let lang_item = match lang_item {
|
||||
SolverAdtLangItem::Option => LangItem::Option,
|
||||
SolverAdtLangItem::Poll => LangItem::Poll,
|
||||
SolverAdtLangItem::Option => lang_items.Option,
|
||||
SolverAdtLangItem::Poll => lang_items.Poll,
|
||||
};
|
||||
lang_item
|
||||
.resolve_adt(self.db(), self.krate.expect("Must have self.krate"))
|
||||
.unwrap_or_else(|| panic!("Lang item {lang_item:?} required but not found."))
|
||||
.into()
|
||||
AdtIdWrapper(lang_item.expect("Lang item required but not found.").into())
|
||||
}
|
||||
|
||||
fn is_lang_item(self, def_id: Self::DefId, lang_item: SolverLangItem) -> bool {
|
||||
|
|
@ -1514,53 +1546,101 @@ impl<'db> Interner for DbInterner<'db> {
|
|||
}
|
||||
|
||||
fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool {
|
||||
self.as_trait_lang_item(def_id)
|
||||
.map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
|
||||
}
|
||||
|
||||
fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool {
|
||||
// FIXME: derive PartialEq on SolverTraitLangItem
|
||||
self.as_adt_lang_item(def_id)
|
||||
.map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
|
||||
}
|
||||
|
||||
fn as_lang_item(self, def_id: Self::DefId) -> Option<SolverLangItem> {
|
||||
let def_id: AttrDefId = match def_id {
|
||||
SolverDefId::TraitId(id) => id.into(),
|
||||
SolverDefId::TypeAliasId(id) => id.into(),
|
||||
SolverDefId::AdtId(id) => id.into(),
|
||||
_ => panic!("Unexpected SolverDefId in as_lang_item"),
|
||||
};
|
||||
let lang_item = self.db().lang_attr(def_id)?;
|
||||
as_lang_item!(
|
||||
SolverLangItem, lang_item;
|
||||
|
||||
ignore = {
|
||||
AsyncFnKindUpvars,
|
||||
}
|
||||
|
||||
Metadata,
|
||||
DynMetadata,
|
||||
CoroutineReturn,
|
||||
CoroutineYield,
|
||||
FutureOutput,
|
||||
CallRefFuture,
|
||||
CallOnceFuture,
|
||||
AsyncFnOnceOutput,
|
||||
)
|
||||
}
|
||||
|
||||
fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem> {
|
||||
let def_id: AttrDefId = def_id.0.into();
|
||||
let lang_item = self.db().lang_attr(def_id)?;
|
||||
as_lang_item!(
|
||||
SolverTraitLangItem, lang_item;
|
||||
is_lang_item!(
|
||||
SolverTraitLangItem, self, def_id.0, lang_item;
|
||||
|
||||
ignore = {
|
||||
AsyncFnKindHelper,
|
||||
AsyncIterator,
|
||||
BikeshedGuaranteedNoDrop,
|
||||
FusedIterator,
|
||||
AsyncFnOnceOutput, // This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver.
|
||||
}
|
||||
|
||||
Sized,
|
||||
MetaSized,
|
||||
PointeeSized,
|
||||
Unsize,
|
||||
Copy,
|
||||
Clone,
|
||||
DiscriminantKind,
|
||||
PointeeTrait,
|
||||
FnPtrTrait,
|
||||
Drop,
|
||||
Destruct,
|
||||
TransmuteTrait,
|
||||
Fn,
|
||||
FnMut,
|
||||
FnOnce,
|
||||
Future,
|
||||
Coroutine,
|
||||
Unpin,
|
||||
Tuple,
|
||||
Iterator,
|
||||
AsyncFn,
|
||||
AsyncFnMut,
|
||||
AsyncFnOnce,
|
||||
)
|
||||
}
|
||||
|
||||
fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool {
|
||||
// FIXME: derive PartialEq on SolverTraitLangItem
|
||||
self.as_adt_lang_item(def_id)
|
||||
.map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
|
||||
}
|
||||
|
||||
fn as_lang_item(self, def_id: Self::DefId) -> Option<SolverLangItem> {
|
||||
match def_id {
|
||||
SolverDefId::TypeAliasId(id) => {
|
||||
as_lang_item!(
|
||||
SolverLangItem, self, id;
|
||||
|
||||
ignore = {
|
||||
AsyncFnKindUpvars,
|
||||
DynMetadata,
|
||||
}
|
||||
|
||||
Metadata,
|
||||
CoroutineReturn,
|
||||
CoroutineYield,
|
||||
FutureOutput,
|
||||
CallRefFuture,
|
||||
CallOnceFuture,
|
||||
AsyncFnOnceOutput,
|
||||
)
|
||||
}
|
||||
SolverDefId::AdtId(AdtId::StructId(id)) => {
|
||||
as_lang_item!(
|
||||
SolverLangItem, self, id;
|
||||
|
||||
ignore = {
|
||||
AsyncFnKindUpvars,
|
||||
Metadata,
|
||||
CoroutineReturn,
|
||||
CoroutineYield,
|
||||
FutureOutput,
|
||||
CallRefFuture,
|
||||
CallOnceFuture,
|
||||
AsyncFnOnceOutput,
|
||||
}
|
||||
|
||||
DynMetadata,
|
||||
)
|
||||
}
|
||||
_ => panic!("Unexpected SolverDefId in as_lang_item"),
|
||||
}
|
||||
}
|
||||
|
||||
fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem> {
|
||||
as_lang_item!(
|
||||
SolverTraitLangItem, self, def_id.0;
|
||||
|
||||
ignore = {
|
||||
AsyncFnKindHelper,
|
||||
AsyncIterator,
|
||||
BikeshedGuaranteedNoDrop,
|
||||
FusedIterator,
|
||||
AsyncFnOnceOutput, // This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver.
|
||||
}
|
||||
|
||||
Sized,
|
||||
|
|
@ -1586,15 +1666,15 @@ impl<'db> Interner for DbInterner<'db> {
|
|||
AsyncFn,
|
||||
AsyncFnMut,
|
||||
AsyncFnOnce,
|
||||
AsyncFnOnceOutput,
|
||||
)
|
||||
}
|
||||
|
||||
fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem> {
|
||||
let def_id: AttrDefId = def_id.0.into();
|
||||
let lang_item = self.db().lang_attr(def_id)?;
|
||||
let AdtId::EnumId(def_id) = def_id.0 else {
|
||||
panic!("Unexpected SolverDefId in as_adt_lang_item");
|
||||
};
|
||||
as_lang_item!(
|
||||
SolverAdtLangItem, lang_item;
|
||||
SolverAdtLangItem, self, def_id;
|
||||
|
||||
ignore = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use std::ops::ControlFlow;
|
|||
use hir_def::{
|
||||
AdtId, HasModule, TypeParamId,
|
||||
hir::generics::{TypeOrConstParamData, TypeParamProvenance},
|
||||
lang_item::LangItem,
|
||||
};
|
||||
use hir_def::{TraitId, type_ref::Rawness};
|
||||
use rustc_abi::{Float, Integer, Size};
|
||||
|
|
@ -620,7 +619,7 @@ impl<'db> Ty<'db> {
|
|||
|
||||
// FIXME: Should this be here?
|
||||
pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'db>>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
match self.kind() {
|
||||
TyKind::Alias(AliasTyKind::Opaque, opaque_ty) => Some(
|
||||
|
|
@ -658,7 +657,7 @@ impl<'db> Ty<'db> {
|
|||
TyKind::Coroutine(coroutine_id, _args) => {
|
||||
let InternedCoroutine(owner, _) = coroutine_id.0.loc(db);
|
||||
let krate = owner.module(db).krate();
|
||||
if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
|
||||
if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future {
|
||||
// This is only used by type walking.
|
||||
// Parameters will be walked outside, and projection predicate is not used.
|
||||
// So just provide the Future trait.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ pub(crate) fn tait_hidden_types<'db>(
|
|||
|
||||
let loc = type_alias.loc(db);
|
||||
let module = loc.module(db);
|
||||
let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
|
||||
let interner = DbInterner::new_with(db, module.krate(), module.containing_block());
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let mut ocx = ObligationCtxt::new(&infcx);
|
||||
let cause = ObligationCause::dummy();
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ fn specializes_query(
|
|||
parent_impl_def_id: ImplId,
|
||||
) -> bool {
|
||||
let trait_env = db.trait_environment(specializing_impl_def_id.into());
|
||||
let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
|
||||
let interner = DbInterner::new_with(db, trait_env.krate, trait_env.block);
|
||||
|
||||
let specializing_impl_signature = db.impl_signature(specializing_impl_def_id);
|
||||
let parent_impl_signature = db.impl_signature(parent_impl_def_id);
|
||||
|
|
|
|||
|
|
@ -44,12 +44,11 @@ fn foo() -> i32 {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"lang_item",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"ImplTraits < 'db >::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"lang_item",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
|
|
@ -133,14 +132,13 @@ fn baz() -> i32 {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"lang_item",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"ImplTraits < 'db >::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"lang_item",
|
||||
"infer_shim",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
|
|
@ -513,10 +511,16 @@ impl SomeStruct {
|
|||
"impl_trait_with_diagnostics_shim",
|
||||
"impl_signature_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"ImplItems::of_",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"impl_self_ty_with_diagnostics_shim",
|
||||
"struct_signature_shim",
|
||||
"struct_signature_with_source_map_shim",
|
||||
"attrs_shim",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
|
|
@ -587,12 +591,12 @@ fn main() {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"lang_item",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"ImplTraits < 'db >::return_type_impl_traits_",
|
||||
"infer_shim",
|
||||
"function_signature_shim",
|
||||
|
|
@ -607,7 +611,6 @@ fn main() {
|
|||
"value_ty_shim",
|
||||
"VariantFields::firewall_",
|
||||
"VariantFields::query_",
|
||||
"lang_item",
|
||||
"InherentImpls::for_crate_",
|
||||
"impl_signature_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
|
|
@ -617,7 +620,6 @@ fn main() {
|
|||
"impl_trait_with_diagnostics_shim",
|
||||
"impl_self_ty_with_diagnostics_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"lang_item",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
|
|
@ -684,12 +686,12 @@ fn main() {
|
|||
"function_signature_shim",
|
||||
"body_with_source_map_shim",
|
||||
"body_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"crate_lang_items",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"GenericPredicates < 'db >::query_with_diagnostics_",
|
||||
"ImplTraits < 'db >::return_type_impl_traits_",
|
||||
"infer_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
//! Trait solving using next trait solver.
|
||||
|
||||
use core::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, BlockId, HasModule, ImplId, Lookup, TraitId,
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
nameres::DefMap,
|
||||
signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags},
|
||||
};
|
||||
|
|
@ -165,54 +164,7 @@ pub enum FnTrait {
|
|||
AsyncFn,
|
||||
}
|
||||
|
||||
impl fmt::Display for FnTrait {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
FnTrait::FnOnce => write!(f, "FnOnce"),
|
||||
FnTrait::FnMut => write!(f, "FnMut"),
|
||||
FnTrait::Fn => write!(f, "Fn"),
|
||||
FnTrait::AsyncFnOnce => write!(f, "AsyncFnOnce"),
|
||||
FnTrait::AsyncFnMut => write!(f, "AsyncFnMut"),
|
||||
FnTrait::AsyncFn => write!(f, "AsyncFn"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FnTrait {
|
||||
pub const fn function_name(&self) -> &'static str {
|
||||
match self {
|
||||
FnTrait::FnOnce => "call_once",
|
||||
FnTrait::FnMut => "call_mut",
|
||||
FnTrait::Fn => "call",
|
||||
FnTrait::AsyncFnOnce => "async_call_once",
|
||||
FnTrait::AsyncFnMut => "async_call_mut",
|
||||
FnTrait::AsyncFn => "async_call",
|
||||
}
|
||||
}
|
||||
|
||||
const fn lang_item(self) -> LangItem {
|
||||
match self {
|
||||
FnTrait::FnOnce => LangItem::FnOnce,
|
||||
FnTrait::FnMut => LangItem::FnMut,
|
||||
FnTrait::Fn => LangItem::Fn,
|
||||
FnTrait::AsyncFnOnce => LangItem::AsyncFnOnce,
|
||||
FnTrait::AsyncFnMut => LangItem::AsyncFnMut,
|
||||
FnTrait::AsyncFn => LangItem::AsyncFn,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn from_lang_item(lang_item: LangItem) -> Option<Self> {
|
||||
match lang_item {
|
||||
LangItem::FnOnce => Some(FnTrait::FnOnce),
|
||||
LangItem::FnMut => Some(FnTrait::FnMut),
|
||||
LangItem::Fn => Some(FnTrait::Fn),
|
||||
LangItem::AsyncFnOnce => Some(FnTrait::AsyncFnOnce),
|
||||
LangItem::AsyncFnMut => Some(FnTrait::AsyncFnMut),
|
||||
LangItem::AsyncFn => Some(FnTrait::AsyncFn),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method_name(self) -> Name {
|
||||
match self {
|
||||
FnTrait::FnOnce => Name::new_symbol_root(sym::call_once),
|
||||
|
|
@ -224,8 +176,15 @@ impl FnTrait {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<TraitId> {
|
||||
self.lang_item().resolve_trait(db, krate)
|
||||
pub fn get_id(self, lang_items: &LangItems) -> Option<TraitId> {
|
||||
match self {
|
||||
FnTrait::FnOnce => lang_items.FnOnce,
|
||||
FnTrait::FnMut => lang_items.FnMut,
|
||||
FnTrait::Fn => lang_items.Fn,
|
||||
FnTrait::AsyncFnOnce => lang_items.AsyncFnOnce,
|
||||
FnTrait::AsyncFnMut => lang_items.AsyncFnMut,
|
||||
FnTrait::AsyncFn => lang_items.AsyncFn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +216,7 @@ fn implements_trait_unique_impl<'db>(
|
|||
trait_: TraitId,
|
||||
create_args: &mut dyn FnMut(&InferCtxt<'db>) -> GenericArgs<'db>,
|
||||
) -> bool {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
// FIXME(next-solver): I believe this should be `PostAnalysis`.
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,12 @@
|
|||
|
||||
use std::cell::LazyCell;
|
||||
|
||||
use base_db::{
|
||||
Crate,
|
||||
target::{self, TargetData},
|
||||
};
|
||||
use base_db::target::{self, TargetData};
|
||||
use hir_def::{
|
||||
EnumId, EnumVariantId, FunctionId, Lookup, TraitId,
|
||||
db::DefDatabase,
|
||||
hir::generics::WherePredicate,
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
resolver::{HasResolver, TypeNs},
|
||||
type_ref::{TraitBoundModifier, TypeRef},
|
||||
};
|
||||
|
|
@ -27,10 +24,8 @@ use crate::{
|
|||
mir::pad16,
|
||||
};
|
||||
|
||||
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
|
||||
[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]
|
||||
.into_iter()
|
||||
.filter_map(move |lang| lang.resolve_trait(db, krate))
|
||||
pub(crate) fn fn_traits(lang_items: &LangItems) -> impl Iterator<Item = TraitId> + '_ {
|
||||
[lang_items.Fn, lang_items.FnMut, lang_items.FnOnce].into_iter().flatten()
|
||||
}
|
||||
|
||||
/// Returns an iterator over the direct super traits (including the trait itself).
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ use crate::{
|
|||
|
||||
pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> VariancesOf<'_> {
|
||||
tracing::debug!("variances_of(def={:?})", def);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
match def {
|
||||
GenericDefId::FunctionId(_) => (),
|
||||
GenericDefId::AdtId(adt) => {
|
||||
|
|
@ -107,7 +107,7 @@ pub(crate) fn variances_of_cycle_initial(
|
|||
db: &dyn HirDatabase,
|
||||
def: GenericDefId,
|
||||
) -> VariancesOf<'_> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let generics = generics(db, def);
|
||||
let count = generics.len();
|
||||
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ fn resolve_impl_trait_item<'db>(
|
|||
// attributes here. Use path resolution directly instead.
|
||||
//
|
||||
// FIXME: resolve type aliases (which are not yielded by iterate_path_candidates)
|
||||
let interner = DbInterner::new_with(db, Some(environment.krate), environment.block);
|
||||
let interner = DbInterner::new_with(db, environment.krate, environment.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
let unstable_features =
|
||||
MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map());
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use hir_def::{
|
|||
expr_store::ExpressionStore,
|
||||
hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItem,
|
||||
signatures::{StaticFlags, TraitFlags},
|
||||
type_ref::{TypeBound, TypeRef, TypeRefId},
|
||||
};
|
||||
|
|
@ -520,7 +519,7 @@ impl<'db> HirDisplay<'db> for TypeParam {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let sized_trait = LangItem::Sized.resolve_trait(f.db, krate);
|
||||
let sized_trait = f.lang_items().Sized;
|
||||
let has_only_sized_bound =
|
||||
predicates.iter().all(move |pred| match pred.kind().skip_binder() {
|
||||
ClauseKind::Trait(it) => Some(it.def_id().0) == sized_trait,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ use hir_def::{
|
|||
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
||||
},
|
||||
item_tree::ImportAlias,
|
||||
lang_item::LangItemTarget,
|
||||
layout::{self, ReprOptions, TargetDataLayout},
|
||||
nameres::{
|
||||
assoc::TraitItems,
|
||||
|
|
@ -91,7 +92,7 @@ use hir_ty::{
|
|||
PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode,
|
||||
infer::{DbInternerInferExt, InferCtxt},
|
||||
},
|
||||
traits::{self, FnTrait, is_inherent_impl_coherent, structurally_normalize_ty},
|
||||
traits::{self, is_inherent_impl_coherent, structurally_normalize_ty},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
|
@ -138,7 +139,7 @@ pub use {
|
|||
attr::{AttrSourceMap, Attrs, AttrsWithOwner},
|
||||
find_path::PrefixKind,
|
||||
import_map,
|
||||
lang_item::{LangItem, crate_lang_items},
|
||||
lang_item::{LangItemEnum as LangItem, crate_lang_items},
|
||||
nameres::{DefMap, ModuleSource, crate_def_map},
|
||||
per_ns::Namespace,
|
||||
type_ref::{Mutability, TypeRef},
|
||||
|
|
@ -765,7 +766,7 @@ impl Module {
|
|||
}
|
||||
self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));
|
||||
|
||||
let interner = DbInterner::new_with(db, Some(self.id.krate()), self.id.containing_block());
|
||||
let interner = DbInterner::new_with(db, self.id.krate(), self.id.containing_block());
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
|
||||
let mut impl_assoc_items_scratch = vec![];
|
||||
|
|
@ -818,7 +819,7 @@ impl Module {
|
|||
let drop_maybe_dangle = (|| {
|
||||
// FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper
|
||||
let trait_ = trait_?;
|
||||
let drop_trait = LangItem::Drop.resolve_trait(db, self.krate().into())?;
|
||||
let drop_trait = interner.lang_items().Drop?;
|
||||
if drop_trait != trait_.into() {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -1282,8 +1283,7 @@ pub struct InstantiatedField<'db> {
|
|||
impl<'db> InstantiatedField<'db> {
|
||||
/// Returns the type as in the signature of the struct.
|
||||
pub fn ty(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
|
||||
let krate = self.inner.krate(db);
|
||||
let interner = DbInterner::new_with(db, Some(krate.base()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
let var_id = self.inner.parent.into();
|
||||
let field = db.field_types(var_id)[self.inner.id];
|
||||
|
|
@ -1305,7 +1305,7 @@ impl TupleField {
|
|||
}
|
||||
|
||||
pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = db
|
||||
.infer(self.owner)
|
||||
.tuple_field_access_type(self.tuple)
|
||||
|
|
@ -1381,7 +1381,7 @@ impl Field {
|
|||
VariantDef::Union(it) => it.id.into(),
|
||||
VariantDef::Variant(it) => it.parent_enum(db).id.into(),
|
||||
};
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty));
|
||||
let ty = db.field_types(var_id)[self.id].instantiate(interner, args);
|
||||
Type::new(db, var_id, ty)
|
||||
|
|
@ -1506,8 +1506,7 @@ impl<'db> InstantiatedStruct<'db> {
|
|||
}
|
||||
|
||||
pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
|
||||
let krate = self.inner.krate(db);
|
||||
let interner = DbInterner::new_with(db, Some(krate.base()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
let ty = db.ty(self.inner.id.into());
|
||||
TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args))
|
||||
|
|
@ -1605,7 +1604,7 @@ impl Enum {
|
|||
|
||||
/// The type of the enum variant bodies.
|
||||
pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
Type::new_for_crate(
|
||||
self.id.lookup(db).container.krate(),
|
||||
match db.enum_signature(self.id).variant_body_type() {
|
||||
|
|
@ -1669,8 +1668,7 @@ pub struct InstantiatedEnum<'db> {
|
|||
|
||||
impl<'db> InstantiatedEnum<'db> {
|
||||
pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
|
||||
let krate = self.inner.krate(db);
|
||||
let interner = DbInterner::new_with(db, Some(krate.base()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
let ty = db.ty(self.inner.id.into());
|
||||
TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args))
|
||||
|
|
@ -1816,7 +1814,7 @@ impl Adt {
|
|||
|
||||
pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
|
||||
let env = db.trait_environment(self.into());
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let adt_id = AdtId::from(self);
|
||||
let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| {
|
||||
GenericArg::error_from_id(interner, id)
|
||||
|
|
@ -1841,7 +1839,7 @@ impl Adt {
|
|||
args: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Type<'db> {
|
||||
let id = AdtId::from(self);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = Ty::new_adt(
|
||||
interner,
|
||||
id,
|
||||
|
|
@ -2277,7 +2275,7 @@ impl Function {
|
|||
|
||||
pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type<'_> {
|
||||
let resolver = self.id.resolver(db);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
// FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
|
||||
let callable_sig = db.callable_item_signature(self.id.into()).instantiate_identity();
|
||||
let ty = Ty::new_fn_ptr(interner, callable_sig);
|
||||
|
|
@ -2305,10 +2303,10 @@ impl Function {
|
|||
generics: impl Iterator<Item = Type<'db>>,
|
||||
) -> Type<'db> {
|
||||
let resolver = self.id.resolver(db);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty));
|
||||
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = db
|
||||
.callable_item_signature(self.id.into())
|
||||
.instantiate(interner, args)
|
||||
|
|
@ -2396,7 +2394,7 @@ impl Function {
|
|||
generics: impl Iterator<Item = Type<'db>>,
|
||||
) -> Vec<Param<'db>> {
|
||||
let environment = db.trait_environment(self.id.into());
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty));
|
||||
let callable_sig =
|
||||
db.callable_item_signature(self.id.into()).instantiate(interner, args).skip_binder();
|
||||
|
|
@ -2439,11 +2437,11 @@ impl Function {
|
|||
|
||||
let ret_type = self.ret_type(db);
|
||||
let Some(impl_traits) = ret_type.as_impl_traits(db) else { return false };
|
||||
let Some(future_trait_id) = LangItem::Future.resolve_trait(db, self.ty(db).env.krate)
|
||||
else {
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.krate(db).id);
|
||||
let Some(future_trait_id) = lang_items.Future else {
|
||||
return false;
|
||||
};
|
||||
let Some(sized_trait_id) = LangItem::Sized.resolve_trait(db, self.ty(db).env.krate) else {
|
||||
let Some(sized_trait_id) = lang_items.Sized else {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
@ -2547,7 +2545,7 @@ impl Function {
|
|||
db: &dyn HirDatabase,
|
||||
span_formatter: impl Fn(FileId, TextRange) -> String,
|
||||
) -> Result<String, ConstEvalError<'_>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let body = db.monomorphized_mir_body(
|
||||
self.id.into(),
|
||||
GenericArgs::new_from_iter(interner, []),
|
||||
|
|
@ -2704,7 +2702,7 @@ impl SelfParam {
|
|||
db: &'db dyn HirDatabase,
|
||||
generics: impl Iterator<Item = Type<'db>>,
|
||||
) -> Type<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = generic_args_from_tys(interner, self.func.into(), generics.map(|ty| ty.ty));
|
||||
let callable_sig =
|
||||
db.callable_item_signature(self.func.into()).instantiate(interner, args).skip_binder();
|
||||
|
|
@ -2804,7 +2802,7 @@ impl Const {
|
|||
|
||||
/// Evaluate the constant.
|
||||
pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst<'_>, ConstEvalError<'_>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity();
|
||||
db.const_eval(self.id, GenericArgs::new_from_iter(interner, []), None)
|
||||
.map(|it| EvaluatedConst { const_: it, def: self.id.into(), ty })
|
||||
|
|
@ -2908,8 +2906,12 @@ pub struct Trait {
|
|||
}
|
||||
|
||||
impl Trait {
|
||||
pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> {
|
||||
LangItem::from_name(name)?.resolve_trait(db, krate.into()).map(Into::into)
|
||||
pub fn lang(db: &dyn HirDatabase, krate: Crate, lang_item: LangItem) -> Option<Trait> {
|
||||
let lang_items = hir_def::lang_item::lang_items(db, krate.id);
|
||||
match lang_item.from_lang_items(lang_items)? {
|
||||
LangItemTarget::TraitId(it) => Some(it.into()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||
|
|
@ -3076,7 +3078,7 @@ impl BuiltinType {
|
|||
|
||||
pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
|
||||
let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
Type::new_for_crate(core, Ty::from_builtin_type(interner, self.inner))
|
||||
}
|
||||
|
||||
|
|
@ -4208,7 +4210,7 @@ impl TypeParam {
|
|||
|
||||
pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
|
||||
let resolver = self.id.parent().resolver(db);
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let index = hir_ty::param_idx(db, self.id.into()).unwrap();
|
||||
let ty = Ty::new_param(interner, self.id, index as u32);
|
||||
Type::new_with_resolver_inner(db, &resolver, ty)
|
||||
|
|
@ -4412,9 +4414,12 @@ impl Impl {
|
|||
/// blanket impls, and only does a shallow type constructor check. In fact, this should've probably been on `Adt`
|
||||
/// etc., and not on `Type`. If you would want to create a precise list of all impls applying to a type,
|
||||
/// you would need to include blanket impls, and try to prove to predicates for each candidate.
|
||||
pub fn all_for_type<'db>(db: &'db dyn HirDatabase, Type { ty, env }: Type<'db>) -> Vec<Impl> {
|
||||
pub fn all_for_type<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
Type { ty, env: _ }: Type<'db>,
|
||||
) -> Vec<Impl> {
|
||||
let mut result = Vec::new();
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let Some(simplified_ty) =
|
||||
fast_reject::simplify_type(interner, ty, fast_reject::TreatParams::AsRigid)
|
||||
else {
|
||||
|
|
@ -4591,7 +4596,7 @@ pub struct Closure<'db> {
|
|||
|
||||
impl<'db> Closure<'db> {
|
||||
fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
match self.id {
|
||||
AnyClosureId::ClosureId(id) => Ty::new_closure(interner, id.into(), self.subst),
|
||||
AnyClosureId::CoroutineClosureId(id) => {
|
||||
|
|
@ -4650,7 +4655,7 @@ impl<'db> Closure<'db> {
|
|||
let owner = db.lookup_intern_closure(id).0;
|
||||
let infer = db.infer(owner);
|
||||
let info = infer.closure_info(id);
|
||||
info.1
|
||||
info.1.into()
|
||||
}
|
||||
AnyClosureId::CoroutineClosureId(_id) => {
|
||||
// FIXME: Infer kind for coroutine closures.
|
||||
|
|
@ -4664,6 +4669,71 @@ impl<'db> Closure<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum FnTrait {
|
||||
FnOnce,
|
||||
FnMut,
|
||||
Fn,
|
||||
|
||||
AsyncFnOnce,
|
||||
AsyncFnMut,
|
||||
AsyncFn,
|
||||
}
|
||||
|
||||
impl From<traits::FnTrait> for FnTrait {
|
||||
fn from(value: traits::FnTrait) -> Self {
|
||||
match value {
|
||||
traits::FnTrait::FnOnce => FnTrait::FnOnce,
|
||||
traits::FnTrait::FnMut => FnTrait::FnMut,
|
||||
traits::FnTrait::Fn => FnTrait::Fn,
|
||||
traits::FnTrait::AsyncFnOnce => FnTrait::AsyncFnOnce,
|
||||
traits::FnTrait::AsyncFnMut => FnTrait::AsyncFnMut,
|
||||
traits::FnTrait::AsyncFn => FnTrait::AsyncFn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FnTrait {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
FnTrait::FnOnce => write!(f, "FnOnce"),
|
||||
FnTrait::FnMut => write!(f, "FnMut"),
|
||||
FnTrait::Fn => write!(f, "Fn"),
|
||||
FnTrait::AsyncFnOnce => write!(f, "AsyncFnOnce"),
|
||||
FnTrait::AsyncFnMut => write!(f, "AsyncFnMut"),
|
||||
FnTrait::AsyncFn => write!(f, "AsyncFn"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FnTrait {
|
||||
pub const fn function_name(&self) -> &'static str {
|
||||
match self {
|
||||
FnTrait::FnOnce => "call_once",
|
||||
FnTrait::FnMut => "call_mut",
|
||||
FnTrait::Fn => "call",
|
||||
FnTrait::AsyncFnOnce => "async_call_once",
|
||||
FnTrait::AsyncFnMut => "async_call_mut",
|
||||
FnTrait::AsyncFn => "async_call",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lang_item(self) -> LangItem {
|
||||
match self {
|
||||
FnTrait::FnOnce => LangItem::FnOnce,
|
||||
FnTrait::FnMut => LangItem::FnMut,
|
||||
FnTrait::Fn => LangItem::Fn,
|
||||
FnTrait::AsyncFnOnce => LangItem::AsyncFnOnce,
|
||||
FnTrait::AsyncFnMut => LangItem::AsyncFnMut,
|
||||
FnTrait::AsyncFn => LangItem::AsyncFn,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<Trait> {
|
||||
Trait::lang(db, krate, self.lang_item())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ClosureCapture<'db> {
|
||||
owner: DefWithBodyId,
|
||||
|
|
@ -4821,7 +4891,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
fn from_def(db: &'db dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Self {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = db.ty(def.into());
|
||||
let def = match def.into() {
|
||||
TyDefId::AdtId(it) => GenericDefId::AdtId(it),
|
||||
|
|
@ -4844,7 +4914,7 @@ impl<'db> Type<'db> {
|
|||
db: &'db dyn HirDatabase,
|
||||
def: impl Into<ValueTyDefId> + HasResolver,
|
||||
) -> Self {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let Some(ty) = db.value_ty(def.into()) else {
|
||||
return Type::new(db, def, Ty::new_error(interner, ErrorGuaranteed));
|
||||
};
|
||||
|
|
@ -4900,7 +4970,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
return self.ty.visit_with(&mut Visitor { interner }).is_break();
|
||||
|
||||
fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool {
|
||||
|
|
@ -5052,14 +5122,15 @@ impl<'db> Type<'db> {
|
|||
/// `std::future::Future` and returns the `Output` associated type.
|
||||
/// This function is used in `.await` syntax completion.
|
||||
pub fn into_future_output(&self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
|
||||
let trait_ = LangItem::IntoFutureIntoFuture
|
||||
.resolve_function(db, self.env.krate)
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let trait_ = lang_items
|
||||
.IntoFutureIntoFuture
|
||||
.and_then(|into_future_fn| {
|
||||
let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
|
||||
let into_future_trait = assoc_item.container_or_implemented_trait(db)?;
|
||||
Some(into_future_trait.id)
|
||||
})
|
||||
.or_else(|| LangItem::Future.resolve_trait(db, self.env.krate))?;
|
||||
.or(lang_items.Future)?;
|
||||
|
||||
if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) {
|
||||
return None;
|
||||
|
|
@ -5072,13 +5143,15 @@ impl<'db> Type<'db> {
|
|||
|
||||
/// This does **not** resolve `IntoFuture`, only `Future`.
|
||||
pub fn future_output(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
|
||||
let future_output = LangItem::FutureOutput.resolve_type_alias(db, self.env.krate)?;
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let future_output = lang_items.FutureOutput?;
|
||||
self.normalize_trait_assoc_type(db, &[], future_output.into())
|
||||
}
|
||||
|
||||
/// This does **not** resolve `IntoIterator`, only `Iterator`.
|
||||
pub fn iterator_item(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
|
||||
let iterator_trait = LangItem::Iterator.resolve_trait(db, self.env.krate)?;
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let iterator_trait = lang_items.Iterator?;
|
||||
let iterator_item = iterator_trait
|
||||
.trait_items(db)
|
||||
.associated_type_by_name(&Name::new_symbol_root(sym::Item))?;
|
||||
|
|
@ -5086,7 +5159,8 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub fn impls_iterator(self, db: &'db dyn HirDatabase) -> bool {
|
||||
let Some(iterator_trait) = LangItem::Iterator.resolve_trait(db, self.env.krate) else {
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let Some(iterator_trait) = lang_items.Iterator else {
|
||||
return false;
|
||||
};
|
||||
traits::implements_trait_unique(self.ty, db, self.env.clone(), iterator_trait)
|
||||
|
|
@ -5094,13 +5168,12 @@ impl<'db> Type<'db> {
|
|||
|
||||
/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
|
||||
pub fn into_iterator_iter(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
|
||||
let trait_ = LangItem::IntoIterIntoIter.resolve_function(db, self.env.krate).and_then(
|
||||
|into_iter_fn| {
|
||||
let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?;
|
||||
let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
|
||||
Some(into_iter_trait.id)
|
||||
},
|
||||
)?;
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let trait_ = lang_items.IntoIterIntoIter.and_then(|into_iter_fn| {
|
||||
let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?;
|
||||
let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
|
||||
Some(into_iter_trait.id)
|
||||
})?;
|
||||
|
||||
if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) {
|
||||
return None;
|
||||
|
|
@ -5117,7 +5190,8 @@ impl<'db> Type<'db> {
|
|||
/// This function can be used to check if a particular type is callable, since FnOnce is a
|
||||
/// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
|
||||
pub fn impls_fnonce(&self, db: &'db dyn HirDatabase) -> bool {
|
||||
let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.env.krate) {
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let fnonce_trait = match lang_items.FnOnce {
|
||||
Some(it) => it,
|
||||
None => return false,
|
||||
};
|
||||
|
|
@ -5127,7 +5201,7 @@ impl<'db> Type<'db> {
|
|||
|
||||
// FIXME: Find better API that also handles const generics
|
||||
pub fn impls_trait(&self, db: &'db dyn HirDatabase, trait_: Trait, args: &[Type<'db>]) -> bool {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = generic_args_from_tys(
|
||||
interner,
|
||||
trait_.id.into(),
|
||||
|
|
@ -5142,7 +5216,7 @@ impl<'db> Type<'db> {
|
|||
args: &[Type<'db>],
|
||||
alias: TypeAlias,
|
||||
) -> Option<Type<'db>> {
|
||||
let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
|
||||
let interner = DbInterner::new_with(db, self.env.krate, self.env.block);
|
||||
let args = generic_args_from_tys(
|
||||
interner,
|
||||
alias.id.into(),
|
||||
|
|
@ -5161,14 +5235,15 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub fn is_copy(&self, db: &'db dyn HirDatabase) -> bool {
|
||||
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, self.env.krate) else {
|
||||
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
|
||||
let Some(copy_trait) = lang_items.Copy else {
|
||||
return false;
|
||||
};
|
||||
self.impls_trait(db, copy_trait.into(), &[])
|
||||
}
|
||||
|
||||
pub fn as_callable(&self, db: &'db dyn HirDatabase) -> Option<Callable<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let callee = match self.ty.kind() {
|
||||
TyKind::Closure(id, subst) => Callee::Closure(id.0, subst),
|
||||
TyKind::CoroutineClosure(id, subst) => Callee::CoroutineClosure(id.0, subst),
|
||||
|
|
@ -5242,7 +5317,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub fn fields(&self, db: &'db dyn HirDatabase) -> Vec<(Field, Self)> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let (variant_id, substs) = match self.ty.kind() {
|
||||
TyKind::Adt(adt_def, substs) => {
|
||||
let id = match adt_def.def_id().0 {
|
||||
|
|
@ -5299,7 +5374,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Ty<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
// There should be no inference vars in types passed here
|
||||
let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty);
|
||||
autoderef(db, self.env.clone(), canonical)
|
||||
|
|
@ -5335,7 +5410,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
};
|
||||
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let Some(simplified_type) =
|
||||
fast_reject::simplify_type(interner, self.ty, fast_reject::TreatParams::AsRigid)
|
||||
else {
|
||||
|
|
@ -5484,7 +5559,7 @@ impl<'db> Type<'db> {
|
|||
f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R,
|
||||
) -> R {
|
||||
let module = resolver.module();
|
||||
let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
|
||||
let interner = DbInterner::new_with(db, module.krate(), module.containing_block());
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
let unstable_features =
|
||||
MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map());
|
||||
|
|
@ -5781,7 +5856,7 @@ impl<'db> Type<'db> {
|
|||
/// Note that we consider placeholder types to unify with everything.
|
||||
/// For example `Option<T>` and `Option<U>` unify although there is unresolved goal `T = U`.
|
||||
pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty));
|
||||
hir_ty::could_unify(db, self.env.clone(), &tys)
|
||||
}
|
||||
|
|
@ -5791,13 +5866,13 @@ impl<'db> Type<'db> {
|
|||
/// This means that placeholder types are not considered to unify if there are any bounds set on
|
||||
/// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
|
||||
pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty));
|
||||
hir_ty::could_unify_deeply(db, self.env.clone(), &tys)
|
||||
}
|
||||
|
||||
pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, to.ty));
|
||||
hir_ty::could_coerce(db, self.env.clone(), &tys)
|
||||
}
|
||||
|
|
@ -5823,7 +5898,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue {
|
||||
let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
|
||||
let interner = DbInterner::new_with(db, self.env.krate, self.env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
hir_ty::drop::has_drop_glue(&infcx, self.ty, self.env.clone())
|
||||
}
|
||||
|
|
@ -5913,7 +5988,7 @@ enum Callee<'db> {
|
|||
Closure(InternedClosureId, GenericArgs<'db>),
|
||||
CoroutineClosure(InternedCoroutineId, GenericArgs<'db>),
|
||||
FnPtr,
|
||||
FnImpl(FnTrait),
|
||||
FnImpl(traits::FnTrait),
|
||||
}
|
||||
|
||||
pub enum CallableKind<'db> {
|
||||
|
|
@ -5940,7 +6015,7 @@ impl<'db> Callable<'db> {
|
|||
CallableKind::Closure(Closure { id: AnyClosureId::CoroutineClosureId(id), subst })
|
||||
}
|
||||
Callee::FnPtr => CallableKind::FnPtr,
|
||||
Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_),
|
||||
Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_.into()),
|
||||
}
|
||||
}
|
||||
pub fn receiver_param(&self, db: &'db dyn HirDatabase) -> Option<(SelfParam, Type<'db>)> {
|
||||
|
|
|
|||
|
|
@ -1655,7 +1655,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
func: Function,
|
||||
subst: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Option<Function> {
|
||||
let interner = DbInterner::new_with(self.db, None, None);
|
||||
let interner = DbInterner::new_no_crate(self.db);
|
||||
let mut subst = subst.into_iter();
|
||||
let substs =
|
||||
hir_ty::next_solver::GenericArgs::for_item(interner, trait_.id.into(), |_, id, _| {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use hir_def::{
|
|||
scope::{ExprScopes, ScopeId},
|
||||
},
|
||||
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat},
|
||||
lang_item::LangItem,
|
||||
lang_item::LangItems,
|
||||
nameres::MacroSubNs,
|
||||
resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope},
|
||||
type_ref::{Mutability, TypeRef, TypeRefId},
|
||||
|
|
@ -267,7 +267,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
db: &'db dyn HirDatabase,
|
||||
ty: &ast::Type,
|
||||
) -> Option<Type<'db>> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
let type_ref = self.type_id(ty)?;
|
||||
|
||||
|
|
@ -410,7 +410,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
) -> Option<Callable<'db>> {
|
||||
let expr_id = self.expr_id(call.clone().into())?.as_expr()?;
|
||||
let (func, args) = self.infer()?.method_resolution(expr_id)?;
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let ty = db.value_ty(func.into())?.instantiate(interner, args);
|
||||
let ty = Type::new_with_resolver(db, &self.resolver, ty);
|
||||
let mut res = ty.as_callable(db)?;
|
||||
|
|
@ -589,10 +589,10 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?;
|
||||
let poll_fn = self.lang_items(db).FuturePoll?;
|
||||
// HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
|
||||
// doesn't have any generic parameters, so we skip building another subst for `poll()`.
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let substs = GenericArgs::new_from_iter(interner, [ty.into()]);
|
||||
Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs))
|
||||
}
|
||||
|
|
@ -607,15 +607,18 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
// This can be either `Deref::deref` or `DerefMut::deref_mut`.
|
||||
// Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
|
||||
// use that result to find out which one it is.
|
||||
let (deref_trait, deref) =
|
||||
self.lang_trait_fn(db, LangItem::Deref, &Name::new_symbol_root(sym::deref))?;
|
||||
let (deref_trait, deref) = self.lang_trait_fn(
|
||||
db,
|
||||
self.lang_items(db).Deref,
|
||||
&Name::new_symbol_root(sym::deref),
|
||||
)?;
|
||||
self.infer()
|
||||
.and_then(|infer| {
|
||||
let expr = self.expr_id(prefix_expr.clone().into())?.as_expr()?;
|
||||
let (func, _) = infer.method_resolution(expr)?;
|
||||
let (deref_mut_trait, deref_mut) = self.lang_trait_fn(
|
||||
db,
|
||||
LangItem::DerefMut,
|
||||
self.lang_items(db).DerefMut,
|
||||
&Name::new_symbol_root(sym::deref_mut),
|
||||
)?;
|
||||
if func == deref_mut { Some((deref_mut_trait, deref_mut)) } else { None }
|
||||
|
|
@ -623,16 +626,16 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
.unwrap_or((deref_trait, deref))
|
||||
}
|
||||
ast::UnaryOp::Not => {
|
||||
self.lang_trait_fn(db, LangItem::Not, &Name::new_symbol_root(sym::not))?
|
||||
self.lang_trait_fn(db, self.lang_items(db).Not, &Name::new_symbol_root(sym::not))?
|
||||
}
|
||||
ast::UnaryOp::Neg => {
|
||||
self.lang_trait_fn(db, LangItem::Neg, &Name::new_symbol_root(sym::neg))?
|
||||
self.lang_trait_fn(db, self.lang_items(db).Neg, &Name::new_symbol_root(sym::neg))?
|
||||
}
|
||||
};
|
||||
|
||||
let ty = self.ty_of_expr(prefix_expr.expr()?)?;
|
||||
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
// HACK: subst for all methods coincides with that for their trait because the methods
|
||||
// don't have any generic parameters, so we skip building another subst for the methods.
|
||||
let substs = GenericArgs::new_from_iter(interner, [ty.into()]);
|
||||
|
|
@ -649,7 +652,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
let index_ty = self.ty_of_expr(index_expr.index()?)?;
|
||||
|
||||
let (_index_trait, index_fn) =
|
||||
self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?;
|
||||
self.lang_trait_fn(db, self.lang_items(db).Index, &Name::new_symbol_root(sym::index))?;
|
||||
let op_fn = self
|
||||
.infer()
|
||||
.and_then(|infer| {
|
||||
|
|
@ -657,7 +660,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
let (func, _) = infer.method_resolution(expr)?;
|
||||
let (_index_mut_trait, index_mut_fn) = self.lang_trait_fn(
|
||||
db,
|
||||
LangItem::IndexMut,
|
||||
self.lang_items(db).IndexMut,
|
||||
&Name::new_symbol_root(sym::index_mut),
|
||||
)?;
|
||||
if func == index_mut_fn { Some(index_mut_fn) } else { None }
|
||||
|
|
@ -665,7 +668,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
.unwrap_or(index_fn);
|
||||
// HACK: subst for all methods coincides with that for their trait because the methods
|
||||
// don't have any generic parameters, so we skip building another subst for the methods.
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let substs = GenericArgs::new_from_iter(interner, [base_ty.into(), index_ty.into()]);
|
||||
Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
|
||||
}
|
||||
|
|
@ -679,12 +682,13 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
let lhs = self.ty_of_expr(binop_expr.lhs()?)?;
|
||||
let rhs = self.ty_of_expr(binop_expr.rhs()?)?;
|
||||
|
||||
let (_op_trait, op_fn) = lang_items_for_bin_op(op).and_then(|(name, lang_item)| {
|
||||
self.lang_trait_fn(db, lang_item, &Name::new_symbol_root(name))
|
||||
})?;
|
||||
let (_op_trait, op_fn) =
|
||||
lang_items_for_bin_op(self.lang_items(db), op).and_then(|(name, lang_item)| {
|
||||
self.lang_trait_fn(db, lang_item, &Name::new_symbol_root(name))
|
||||
})?;
|
||||
// HACK: subst for `index()` coincides with that for `Index` because `index()` itself
|
||||
// doesn't have any generic parameters, so we skip building another subst for `index()`.
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let substs = GenericArgs::new_from_iter(interner, [lhs.into(), rhs.into()]);
|
||||
|
||||
Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
|
||||
|
|
@ -697,10 +701,10 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
) -> Option<FunctionId> {
|
||||
let ty = self.ty_of_expr(try_expr.expr()?)?;
|
||||
|
||||
let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?;
|
||||
let op_fn = self.lang_items(db).TryTraitBranch?;
|
||||
// HACK: subst for `branch()` coincides with that for `Try` because `branch()` itself
|
||||
// doesn't have any generic parameters, so we skip building another subst for `branch()`.
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let substs = GenericArgs::new_from_iter(interner, [ty.into()]);
|
||||
|
||||
Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
|
||||
|
|
@ -714,7 +718,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
|
||||
let expr = ast::Expr::from(record_expr);
|
||||
let expr_id = self.store_sm()?.node_expr(InFile::new(self.file_id, &expr))?;
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
|
||||
let ast_name = field.field_name()?;
|
||||
let local_name = ast_name.as_name();
|
||||
|
|
@ -755,7 +759,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
db: &'db dyn HirDatabase,
|
||||
field: &ast::RecordPatField,
|
||||
) -> Option<(Field, Type<'db>, GenericSubstitution<'db>)> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let field_name = field.field_name()?.as_name();
|
||||
let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
|
||||
let pat_id = self.pat_id(&record_pat.into())?;
|
||||
|
|
@ -817,7 +821,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
|
||||
let trait_env = container.env;
|
||||
|
||||
let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
|
||||
let interner = DbInterner::new_with(db, trait_env.krate, trait_env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
|
||||
let mut container = Either::Right(container.ty);
|
||||
|
|
@ -1273,7 +1277,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
variant: VariantId,
|
||||
missing_fields: Vec<LocalFieldId>,
|
||||
) -> Vec<(Field, Type<'db>)> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let field_types = db.field_types(variant);
|
||||
|
||||
missing_fields
|
||||
|
|
@ -1423,18 +1427,22 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
None => return (const_id, subs),
|
||||
};
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
let interner = DbInterner::new_with(db, env.krate, env.block);
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
|
||||
method_resolution::lookup_impl_const(&infcx, env, const_id, subs)
|
||||
}
|
||||
|
||||
fn lang_items<'a>(&self, db: &'a dyn HirDatabase) -> &'a LangItems {
|
||||
hir_def::lang_item::lang_items(db, self.resolver.krate())
|
||||
}
|
||||
|
||||
fn lang_trait_fn(
|
||||
&self,
|
||||
db: &'db dyn HirDatabase,
|
||||
lang_trait: LangItem,
|
||||
lang_trait: Option<TraitId>,
|
||||
method_name: &Name,
|
||||
) -> Option<(TraitId, FunctionId)> {
|
||||
let trait_id = lang_trait.resolve_trait(db, self.resolver.krate())?;
|
||||
let trait_id = lang_trait?;
|
||||
let fn_id = trait_id.trait_items(db).method_by_name(method_name)?;
|
||||
Some((trait_id, fn_id))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ pub(super) fn famous_types<'a, 'lt, 'db, DB: HirDatabase>(
|
|||
) -> impl Iterator<Item = Expr<'db>> + use<'a, 'db, 'lt, DB> {
|
||||
let db = ctx.sema.db;
|
||||
let module = ctx.scope.module();
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let bool_ty = Ty::new_bool(interner);
|
||||
let unit_ty = Ty::new_unit(interner);
|
||||
[
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ fn existing_from_impl(
|
|||
let variant = sema.to_def(variant)?;
|
||||
let krate = variant.module(db).krate();
|
||||
let from_trait = FamousDefs(sema, krate).core_convert_From()?;
|
||||
let interner = DbInterner::new_with(db, Some(krate.base()), None);
|
||||
let interner = DbInterner::new_with(db, krate.base(), None);
|
||||
use hir::next_solver::infer::DbInternerInferExt;
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ fn from_impl_exists(
|
|||
let strukt = sema.to_def(strukt)?;
|
||||
let krate = strukt.krate(db);
|
||||
let from_trait = FamousDefs(sema, krate).core_convert_From()?;
|
||||
let interner = DbInterner::new_with(db, Some(krate.base()), None);
|
||||
let interner = DbInterner::new_with(db, krate.base(), None);
|
||||
use hir::next_solver::infer::DbInternerInferExt;
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
|
||||
|
|
|
|||
|
|
@ -780,9 +780,9 @@ fn main() {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
|
||||
ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED
|
||||
fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
|
||||
me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ mod tests;
|
|||
use std::{iter, ops::Not};
|
||||
|
||||
use either::Either;
|
||||
use hir::{
|
||||
DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics,
|
||||
};
|
||||
use hir::{DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, Semantics};
|
||||
use ide_db::{
|
||||
FileRange, FxIndexSet, MiniCore, Ranker, RootDatabase,
|
||||
defs::{Definition, IdentClass, NameRefClass, OperatorClass},
|
||||
|
|
@ -675,10 +673,10 @@ fn walk_and_push_ty(
|
|||
} else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
|
||||
push_new_def(trait_.into());
|
||||
} else if let Some(tp) = t.as_type_param(db) {
|
||||
let sized_trait = LangItem::Sized.resolve_trait(db, t.krate(db).into());
|
||||
let sized_trait = hir::Trait::lang(db, t.krate(db), hir::LangItem::Sized);
|
||||
tp.trait_bounds(db)
|
||||
.into_iter()
|
||||
.filter(|&it| Some(it.into()) != sized_trait)
|
||||
.filter(|&it| Some(it) != sized_trait)
|
||||
.for_each(|it| push_new_def(it.into()));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1083,8 +1083,8 @@ fn closure_ty(
|
|||
};
|
||||
let mut markup = format!("```rust\n{}\n```", c.display_with_impl(sema.db, display_target));
|
||||
|
||||
if let Some(trait_) = c.fn_trait(sema.db).get_id(sema.db, original.krate(sema.db).into()) {
|
||||
push_new_def(hir::Trait::from(trait_).into())
|
||||
if let Some(trait_) = c.fn_trait(sema.db).get_id(sema.db, original.krate(sema.db)) {
|
||||
push_new_def(trait_.into())
|
||||
}
|
||||
if let Some(layout) = render_memory_layout(
|
||||
config.memory_layout,
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use std::{
|
|||
|
||||
use cfg::{CfgAtom, CfgDiff};
|
||||
use hir::{
|
||||
Adt, AssocItem, Crate, DefWithBody, FindPathConfig, HasCrate, HasSource, HirDisplay, ModuleDef,
|
||||
Name, crate_lang_items,
|
||||
Adt, AssocItem, Crate, DefWithBody, FindPathConfig, HasSource, HirDisplay, ModuleDef, Name,
|
||||
crate_lang_items,
|
||||
db::{DefDatabase, ExpandDatabase, HirDatabase},
|
||||
next_solver::{DbInterner, GenericArgs},
|
||||
};
|
||||
|
|
@ -374,7 +374,7 @@ impl flags::AnalysisStats {
|
|||
let mut all = 0;
|
||||
let mut fail = 0;
|
||||
for &a in adts {
|
||||
let interner = DbInterner::new_with(db, Some(a.krate(db).base()), None);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let generic_params = db.generic_params(a.into());
|
||||
if generic_params.iter_type_or_consts().next().is_some()
|
||||
|| generic_params.iter_lt().next().is_some()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue