mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 10:39:45 +00:00
refactor: De-arc lang item queries
This commit is contained in:
parent
5adee2ad2c
commit
6355df9c57
23 changed files with 194 additions and 261 deletions
|
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
hir::generics::GenericParams,
|
hir::generics::GenericParams,
|
||||||
import_map::ImportMap,
|
import_map::ImportMap,
|
||||||
item_tree::{AttrOwner, ItemTree},
|
item_tree::{AttrOwner, ItemTree},
|
||||||
lang_item::{self, LangItem, LangItemTarget, LangItems},
|
lang_item::{self, LangItem},
|
||||||
nameres::{
|
nameres::{
|
||||||
DefMap, LocalDefMap,
|
DefMap, LocalDefMap,
|
||||||
assoc::{ImplItems, TraitItems},
|
assoc::{ImplItems, TraitItems},
|
||||||
|
|
@ -325,9 +325,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
|
||||||
|
|
||||||
// endregion:attrs
|
// endregion:attrs
|
||||||
|
|
||||||
#[salsa::invoke(LangItems::lang_item_query)]
|
|
||||||
fn lang_item(&self, start_crate: Crate, item: LangItem) -> Option<LangItemTarget>;
|
|
||||||
|
|
||||||
#[salsa::invoke(ImportMap::import_map_query)]
|
#[salsa::invoke(ImportMap::import_map_query)]
|
||||||
fn import_map(&self, krate: Crate) -> Arc<ImportMap>;
|
fn import_map(&self, krate: Crate) -> Arc<ImportMap>;
|
||||||
|
|
||||||
|
|
@ -349,9 +346,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
|
||||||
|
|
||||||
// endregion:visibilities
|
// endregion:visibilities
|
||||||
|
|
||||||
#[salsa::invoke(LangItems::crate_lang_items_query)]
|
|
||||||
fn crate_lang_items(&self, krate: Crate) -> Option<Arc<LangItems>>;
|
|
||||||
|
|
||||||
#[salsa::invoke(crate::lang_item::notable_traits_in_deps)]
|
#[salsa::invoke(crate::lang_item::notable_traits_in_deps)]
|
||||||
fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>;
|
fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>;
|
||||||
#[salsa::invoke(crate::lang_item::crate_notable_traits)]
|
#[salsa::invoke(crate::lang_item::crate_notable_traits)]
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,91 @@ impl LangItemTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Salsa query. This will look for lang items in a specific crate.
|
||||||
|
#[salsa::tracked(return_ref)]
|
||||||
|
pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangItems>> {
|
||||||
|
let _p = tracing::info_span!("crate_lang_items_query").entered();
|
||||||
|
|
||||||
|
let mut lang_items = LangItems::default();
|
||||||
|
|
||||||
|
let crate_def_map = db.crate_def_map(krate);
|
||||||
|
|
||||||
|
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);
|
||||||
|
for &(_, assoc) in db.impl_items(impl_def).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::ConstId(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for def in module_data.scope.declarations() {
|
||||||
|
match def {
|
||||||
|
ModuleDefId::TraitId(trait_) => {
|
||||||
|
lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait);
|
||||||
|
db.trait_items(trait_).items.iter().for_each(|&(_, assoc_id)| match assoc_id {
|
||||||
|
AssocItemId::FunctionId(f) => {
|
||||||
|
lang_items.collect_lang_item(db, f, LangItemTarget::Function);
|
||||||
|
}
|
||||||
|
AssocItemId::TypeAliasId(alias) => {
|
||||||
|
lang_items.collect_lang_item(db, alias, LangItemTarget::TypeAlias)
|
||||||
|
}
|
||||||
|
AssocItemId::ConstId(_) => {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ModuleDefId::AdtId(AdtId::EnumId(e)) => {
|
||||||
|
lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
|
||||||
|
db.enum_variants(e).variants.iter().for_each(|&(id, _)| {
|
||||||
|
lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ModuleDefId::AdtId(AdtId::StructId(s)) => {
|
||||||
|
lang_items.collect_lang_item(db, s, LangItemTarget::Struct);
|
||||||
|
}
|
||||||
|
ModuleDefId::AdtId(AdtId::UnionId(u)) => {
|
||||||
|
lang_items.collect_lang_item(db, u, LangItemTarget::Union);
|
||||||
|
}
|
||||||
|
ModuleDefId::FunctionId(f) => {
|
||||||
|
lang_items.collect_lang_item(db, f, LangItemTarget::Function);
|
||||||
|
}
|
||||||
|
ModuleDefId::StaticId(s) => {
|
||||||
|
lang_items.collect_lang_item(db, s, LangItemTarget::Static);
|
||||||
|
}
|
||||||
|
ModuleDefId::TypeAliasId(t) => {
|
||||||
|
lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if lang_items.items.is_empty() { None } else { Some(Box::new(lang_items)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Salsa query. Look for a lang item, starting from the specified crate and recursively
|
||||||
|
/// traversing its dependencies.
|
||||||
|
#[salsa::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);
|
||||||
|
}
|
||||||
|
start_crate.data(db).dependencies.iter().find_map(|dep| lang_item(db, dep.crate_id, item))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct LangItems {
|
pub struct LangItems {
|
||||||
items: FxHashMap<LangItem, LangItemTarget>,
|
items: FxHashMap<LangItem, LangItemTarget>,
|
||||||
|
|
@ -93,96 +178,6 @@ impl LangItems {
|
||||||
self.items.get(&item).copied()
|
self.items.get(&item).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Salsa query. This will look for lang items in a specific crate.
|
|
||||||
pub(crate) fn crate_lang_items_query(
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
krate: Crate,
|
|
||||||
) -> Option<Arc<LangItems>> {
|
|
||||||
let _p = tracing::info_span!("crate_lang_items_query").entered();
|
|
||||||
|
|
||||||
let mut lang_items = LangItems::default();
|
|
||||||
|
|
||||||
let crate_def_map = db.crate_def_map(krate);
|
|
||||||
|
|
||||||
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);
|
|
||||||
for &(_, assoc) in db.impl_items(impl_def).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::ConstId(_) => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for def in module_data.scope.declarations() {
|
|
||||||
match def {
|
|
||||||
ModuleDefId::TraitId(trait_) => {
|
|
||||||
lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait);
|
|
||||||
db.trait_items(trait_).items.iter().for_each(
|
|
||||||
|&(_, assoc_id)| match assoc_id {
|
|
||||||
AssocItemId::FunctionId(f) => {
|
|
||||||
lang_items.collect_lang_item(db, f, LangItemTarget::Function);
|
|
||||||
}
|
|
||||||
AssocItemId::TypeAliasId(alias) => lang_items.collect_lang_item(
|
|
||||||
db,
|
|
||||||
alias,
|
|
||||||
LangItemTarget::TypeAlias,
|
|
||||||
),
|
|
||||||
AssocItemId::ConstId(_) => {}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ModuleDefId::AdtId(AdtId::EnumId(e)) => {
|
|
||||||
lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
|
|
||||||
db.enum_variants(e).variants.iter().for_each(|&(id, _)| {
|
|
||||||
lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ModuleDefId::AdtId(AdtId::StructId(s)) => {
|
|
||||||
lang_items.collect_lang_item(db, s, LangItemTarget::Struct);
|
|
||||||
}
|
|
||||||
ModuleDefId::AdtId(AdtId::UnionId(u)) => {
|
|
||||||
lang_items.collect_lang_item(db, u, LangItemTarget::Union);
|
|
||||||
}
|
|
||||||
ModuleDefId::FunctionId(f) => {
|
|
||||||
lang_items.collect_lang_item(db, f, LangItemTarget::Function);
|
|
||||||
}
|
|
||||||
ModuleDefId::StaticId(s) => {
|
|
||||||
lang_items.collect_lang_item(db, s, LangItemTarget::Static);
|
|
||||||
}
|
|
||||||
ModuleDefId::TypeAliasId(t) => {
|
|
||||||
lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if lang_items.items.is_empty() { None } else { Some(Arc::new(lang_items)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Salsa query. Look for a lang item, starting from the specified crate and recursively
|
|
||||||
/// traversing its dependencies.
|
|
||||||
pub(crate) fn lang_item_query(
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
start_crate: Crate,
|
|
||||||
item: LangItem,
|
|
||||||
) -> Option<LangItemTarget> {
|
|
||||||
let _p = tracing::info_span!("lang_item_query").entered();
|
|
||||||
if let Some(target) =
|
|
||||||
db.crate_lang_items(start_crate).and_then(|it| it.items.get(&item).copied())
|
|
||||||
{
|
|
||||||
return Some(target);
|
|
||||||
}
|
|
||||||
start_crate.data(db).dependencies.iter().find_map(|dep| db.lang_item(dep.crate_id, item))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect_lang_item<T>(
|
fn collect_lang_item<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
|
|
@ -269,18 +264,38 @@ macro_rules! language_item_table {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LangItem {
|
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())
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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`]
|
/// Opposite of [`LangItem::name`]
|
||||||
pub fn from_name(name: &hir_expand::name::Name) -> Option<Self> {
|
pub fn from_name(name: &hir_expand::name::Name) -> Option<Self> {
|
||||||
Self::from_symbol(name.symbol())
|
Self::from_symbol(name.symbol())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option<Path> {
|
pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option<Path> {
|
||||||
let t = db.lang_item(start_crate, *self)?;
|
let t = lang_item(db, start_crate, *self)?;
|
||||||
Some(Path::LangItem(t, None))
|
Some(Path::LangItem(t, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option<Path> {
|
pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option<Path> {
|
||||||
let t = db.lang_item(start_crate, *self)?;
|
let t = lang_item(db, start_crate, *self)?;
|
||||||
Some(Path::LangItem(t, Some(seg)))
|
Some(Path::LangItem(t, Some(seg)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,15 +198,13 @@ pub(crate) fn deref_by_trait(
|
||||||
// blanked impl on `Deref`.
|
// blanked impl on `Deref`.
|
||||||
#[expect(clippy::overly_complex_bool_expr)]
|
#[expect(clippy::overly_complex_bool_expr)]
|
||||||
if use_receiver_trait && false {
|
if use_receiver_trait && false {
|
||||||
if let Some(receiver) =
|
if let Some(receiver) = LangItem::Receiver.resolve_trait(db, table.trait_env.krate) {
|
||||||
db.lang_item(table.trait_env.krate, LangItem::Receiver).and_then(|l| l.as_trait())
|
|
||||||
{
|
|
||||||
return Some(receiver);
|
return Some(receiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Old rustc versions might not have `Receiver` trait.
|
// Old rustc versions might not have `Receiver` trait.
|
||||||
// Fallback to `Deref` if they don't
|
// Fallback to `Deref` if they don't
|
||||||
db.lang_item(table.trait_env.krate, LangItem::Deref).and_then(|l| l.as_trait())
|
LangItem::Deref.resolve_trait(db, table.trait_env.krate)
|
||||||
};
|
};
|
||||||
let trait_id = trait_id()?;
|
let trait_id = trait_id()?;
|
||||||
let target =
|
let target =
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use hir_def::{
|
||||||
AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
|
AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
|
||||||
TypeAliasId, VariantId,
|
TypeAliasId, VariantId,
|
||||||
hir::Movability,
|
hir::Movability,
|
||||||
lang_item::{LangItem, LangItemTarget},
|
lang_item::LangItem,
|
||||||
signatures::{ImplFlags, StructFlags, TraitFlags},
|
signatures::{ImplFlags, StructFlags, TraitFlags},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -262,10 +262,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
||||||
well_known_trait: rust_ir::WellKnownTrait,
|
well_known_trait: rust_ir::WellKnownTrait,
|
||||||
) -> Option<chalk_ir::TraitId<Interner>> {
|
) -> Option<chalk_ir::TraitId<Interner>> {
|
||||||
let lang_attr = lang_item_from_well_known_trait(well_known_trait);
|
let lang_attr = lang_item_from_well_known_trait(well_known_trait);
|
||||||
let trait_ = match self.db.lang_item(self.krate, lang_attr) {
|
let trait_ = lang_attr.resolve_trait(self.db, self.krate)?;
|
||||||
Some(LangItemTarget::Trait(trait_)) => trait_,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
Some(to_chalk_trait_id(trait_))
|
Some(to_chalk_trait_id(trait_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,11 +303,8 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
||||||
chalk_ir::Binders::new(binders, bound)
|
chalk_ir::Binders::new(binders, bound)
|
||||||
}
|
}
|
||||||
crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
|
crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
|
||||||
if let Some((future_trait, future_output)) = self
|
if let Some((future_trait, future_output)) =
|
||||||
.db
|
LangItem::Future.resolve_trait(self.db, self.krate).and_then(|trait_| {
|
||||||
.lang_item(self.krate, LangItem::Future)
|
|
||||||
.and_then(|item| item.as_trait())
|
|
||||||
.and_then(|trait_| {
|
|
||||||
let alias = self
|
let alias = self
|
||||||
.db
|
.db
|
||||||
.trait_items(trait_)
|
.trait_items(trait_)
|
||||||
|
|
@ -338,10 +332,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
||||||
});
|
});
|
||||||
let mut binder = vec![];
|
let mut binder = vec![];
|
||||||
binder.push(crate::wrap_empty_binders(impl_bound));
|
binder.push(crate::wrap_empty_binders(impl_bound));
|
||||||
let sized_trait = self
|
let sized_trait = LangItem::Sized.resolve_trait(self.db, self.krate);
|
||||||
.db
|
|
||||||
.lang_item(self.krate, LangItem::Sized)
|
|
||||||
.and_then(|item| item.as_trait());
|
|
||||||
if let Some(sized_trait_) = sized_trait {
|
if let Some(sized_trait_) = sized_trait {
|
||||||
let sized_bound = WhereClause::Implemented(TraitRef {
|
let sized_bound = WhereClause::Implemented(TraitRef {
|
||||||
trait_id: to_chalk_trait_id(sized_trait_),
|
trait_id: to_chalk_trait_id(sized_trait_),
|
||||||
|
|
@ -660,9 +651,8 @@ pub(crate) fn associated_ty_data_query(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.unsized_types.contains(&self_ty) {
|
if !ctx.unsized_types.contains(&self_ty) {
|
||||||
let sized_trait = db
|
let sized_trait =
|
||||||
.lang_item(resolver.krate(), LangItem::Sized)
|
LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id);
|
||||||
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
|
|
||||||
let sized_bound = sized_trait.into_iter().map(|sized_trait| {
|
let sized_bound = sized_trait.into_iter().map(|sized_trait| {
|
||||||
let trait_bound =
|
let trait_bound =
|
||||||
rust_ir::TraitBound { trait_id: sized_trait, args_no_self: Default::default() };
|
rust_ir::TraitBound { trait_id: sized_trait, args_no_self: Default::default() };
|
||||||
|
|
|
||||||
|
|
@ -251,9 +251,7 @@ impl TyExt for Ty {
|
||||||
match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
|
match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
|
||||||
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
|
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
|
||||||
let krate = def.module(db).krate();
|
let krate = def.module(db).krate();
|
||||||
if let Some(future_trait) =
|
if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
|
||||||
db.lang_item(krate, LangItem::Future).and_then(|item| item.as_trait())
|
|
||||||
{
|
|
||||||
// This is only used by type walking.
|
// This is only used by type walking.
|
||||||
// Parameters will be walked outside, and projection predicate is not used.
|
// Parameters will be walked outside, and projection predicate is not used.
|
||||||
// So just provide the Future trait.
|
// So just provide the Future trait.
|
||||||
|
|
@ -364,8 +362,7 @@ impl TyExt for Ty {
|
||||||
|
|
||||||
fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
|
fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
|
||||||
let crate_id = owner.module(db).krate();
|
let crate_id = owner.module(db).krate();
|
||||||
let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|it| it.as_trait())
|
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, crate_id) else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
|
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
|
||||||
|
|
|
||||||
|
|
@ -482,9 +482,8 @@ struct FilterMapNextChecker {
|
||||||
impl FilterMapNextChecker {
|
impl FilterMapNextChecker {
|
||||||
fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self {
|
fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self {
|
||||||
// Find and store the FunctionIds for Iterator::filter_map and Iterator::next
|
// Find and store the FunctionIds for Iterator::filter_map and Iterator::next
|
||||||
let (next_function_id, filter_map_function_id) = match db
|
let (next_function_id, filter_map_function_id) = match LangItem::IteratorNext
|
||||||
.lang_item(resolver.krate(), LangItem::IteratorNext)
|
.resolve_function(db, resolver.krate())
|
||||||
.and_then(|it| it.as_function())
|
|
||||||
{
|
{
|
||||||
Some(next_function_id) => (
|
Some(next_function_id) => (
|
||||||
Some(next_function_id),
|
Some(next_function_id),
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use hir_def::{
|
||||||
hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
|
hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
|
||||||
item_scope::ItemInNs,
|
item_scope::ItemInNs,
|
||||||
item_tree::FieldsShape,
|
item_tree::FieldsShape,
|
||||||
lang_item::{LangItem, LangItemTarget},
|
lang_item::LangItem,
|
||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
signatures::VariantFields,
|
signatures::VariantFields,
|
||||||
type_ref::{
|
type_ref::{
|
||||||
|
|
@ -1348,9 +1348,8 @@ impl HirDisplay for Ty {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => {
|
ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => {
|
||||||
let future_trait = db
|
let future_trait =
|
||||||
.lang_item(body.module(db).krate(), LangItem::Future)
|
LangItem::Future.resolve_trait(db, body.module(db).krate());
|
||||||
.and_then(LangItemTarget::as_trait);
|
|
||||||
let output = future_trait.and_then(|t| {
|
let output = future_trait.and_then(|t| {
|
||||||
db.trait_items(t)
|
db.trait_items(t)
|
||||||
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
|
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
|
||||||
|
|
@ -1728,9 +1727,7 @@ impl SizedByDefault {
|
||||||
match self {
|
match self {
|
||||||
Self::NotSized => false,
|
Self::NotSized => false,
|
||||||
Self::Sized { anchor } => {
|
Self::Sized { anchor } => {
|
||||||
let sized_trait = db
|
let sized_trait = LangItem::Sized.resolve_trait(db, anchor);
|
||||||
.lang_item(anchor, LangItem::Sized)
|
|
||||||
.and_then(|lang_item| lang_item.as_trait());
|
|
||||||
Some(trait_) == sized_trait
|
Some(trait_) == sized_trait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1895,8 +1892,7 @@ fn write_bounds_like_dyn_trait(
|
||||||
write!(f, ">")?;
|
write!(f, ">")?;
|
||||||
}
|
}
|
||||||
if let SizedByDefault::Sized { anchor } = default_sized {
|
if let SizedByDefault::Sized { anchor } = default_sized {
|
||||||
let sized_trait =
|
let sized_trait = LangItem::Sized.resolve_trait(f.db, anchor);
|
||||||
f.db.lang_item(anchor, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
|
|
||||||
if !is_sized {
|
if !is_sized {
|
||||||
if !first {
|
if !first {
|
||||||
write!(f, " + ")?;
|
write!(f, " + ")?;
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,7 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
||||||
AdtId::StructId(id) => db.lookup_intern_struct(id).container,
|
AdtId::StructId(id) => db.lookup_intern_struct(id).container,
|
||||||
AdtId::UnionId(id) => db.lookup_intern_union(id).container,
|
AdtId::UnionId(id) => db.lookup_intern_union(id).container,
|
||||||
};
|
};
|
||||||
let Some(drop_trait) =
|
let Some(drop_trait) = LangItem::Drop.resolve_trait(db, module.krate()) else {
|
||||||
db.lang_item(module.krate(), LangItem::Drop).and_then(|it| it.as_trait())
|
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let impls = match module.containing_block() {
|
let impls = match module.containing_block() {
|
||||||
|
|
@ -181,8 +179,7 @@ fn projection_has_drop_glue(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> bool {
|
fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> bool {
|
||||||
let Some(copy_trait) = db.lang_item(env.krate, LangItem::Copy).and_then(|it| it.as_trait())
|
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
|
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ pub fn dyn_compatibility_of_trait_query(
|
||||||
|
|
||||||
fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
|
fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
|
||||||
let krate = def.module(db).krate();
|
let krate = def.module(db).krate();
|
||||||
let Some(sized) = db.lang_item(krate, LangItem::Sized).and_then(|l| l.as_trait()) else {
|
let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -491,8 +491,8 @@ fn receiver_is_dispatchable(
|
||||||
|
|
||||||
let krate = func.module(db).krate();
|
let krate = func.module(db).krate();
|
||||||
let traits = (
|
let traits = (
|
||||||
db.lang_item(krate, LangItem::Unsize).and_then(|it| it.as_trait()),
|
LangItem::Unsize.resolve_trait(db, krate),
|
||||||
db.lang_item(krate, LangItem::DispatchFromDyn).and_then(|it| it.as_trait()),
|
LangItem::DispatchFromDyn.resolve_trait(db, krate),
|
||||||
);
|
);
|
||||||
let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
|
let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ use hir_def::{
|
||||||
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
|
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
|
||||||
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
||||||
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
|
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
|
||||||
lang_item::{LangItem, LangItemTarget},
|
lang_item::{LangItem, LangItemTarget, lang_item},
|
||||||
layout::Integer,
|
layout::Integer,
|
||||||
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||||
signatures::{ConstSignature, StaticSignature},
|
signatures::{ConstSignature, StaticSignature},
|
||||||
|
|
@ -1801,7 +1801,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
|
|
||||||
fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
|
fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
|
||||||
let krate = self.resolver.krate();
|
let krate = self.resolver.krate();
|
||||||
self.db.lang_item(krate, item)
|
lang_item(self.db, krate, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
|
fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use chalk_ir::{BoundVar, Goal, Mutability, TyKind, TyVariableKind, cast::Cast};
|
use chalk_ir::{BoundVar, Goal, Mutability, TyKind, TyVariableKind, cast::Cast};
|
||||||
use hir_def::{
|
use hir_def::{hir::ExprId, lang_item::LangItem};
|
||||||
hir::ExprId,
|
|
||||||
lang_item::{LangItem, LangItemTarget},
|
|
||||||
};
|
|
||||||
use stdx::always;
|
use stdx::always;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
|
@ -701,8 +698,8 @@ impl InferenceTable<'_> {
|
||||||
reborrow.as_ref().map_or_else(|| from_ty.clone(), |(_, adj)| adj.target.clone());
|
reborrow.as_ref().map_or_else(|| from_ty.clone(), |(_, adj)| adj.target.clone());
|
||||||
|
|
||||||
let krate = self.trait_env.krate;
|
let krate = self.trait_env.krate;
|
||||||
let coerce_unsized_trait = match self.db.lang_item(krate, LangItem::CoerceUnsized) {
|
let coerce_unsized_trait = match LangItem::CoerceUnsized.resolve_trait(self.db, krate) {
|
||||||
Some(LangItemTarget::Trait(trait_)) => trait_,
|
Some(trait_) => trait_,
|
||||||
_ => return Err(TypeError),
|
_ => return Err(TypeError),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,10 +126,8 @@ impl InferenceContext<'_> {
|
||||||
&Expr::Index { base, index } => {
|
&Expr::Index { base, index } => {
|
||||||
if mutability == Mutability::Mut {
|
if mutability == Mutability::Mut {
|
||||||
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
|
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
|
||||||
if let Some(index_trait) = self
|
if let Some(index_trait) =
|
||||||
.db
|
LangItem::IndexMut.resolve_trait(self.db, self.table.trait_env.krate)
|
||||||
.lang_item(self.table.trait_env.krate, LangItem::IndexMut)
|
|
||||||
.and_then(|l| l.as_trait())
|
|
||||||
{
|
{
|
||||||
if let Some(index_fn) = self
|
if let Some(index_fn) = self
|
||||||
.db
|
.db
|
||||||
|
|
@ -183,10 +181,8 @@ impl InferenceContext<'_> {
|
||||||
let mut mutability = mutability;
|
let mut mutability = mutability;
|
||||||
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
|
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
|
||||||
if mutability == Mutability::Mut {
|
if mutability == Mutability::Mut {
|
||||||
if let Some(deref_trait) = self
|
if let Some(deref_trait) =
|
||||||
.db
|
LangItem::DerefMut.resolve_trait(self.db, self.table.trait_env.krate)
|
||||||
.lang_item(self.table.trait_env.krate, LangItem::DerefMut)
|
|
||||||
.and_then(|l| l.as_trait())
|
|
||||||
{
|
{
|
||||||
let ty = self.result.type_of_expr.get(*expr);
|
let ty = self.result.type_of_expr.get(*expr);
|
||||||
let is_mut_ptr = ty.is_some_and(|ty| {
|
let is_mut_ptr = ty.is_some_and(|ty| {
|
||||||
|
|
|
||||||
|
|
@ -1024,11 +1024,7 @@ impl<'a> InferenceTable<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(sized) = self
|
let Some(sized) = LangItem::Sized.resolve_trait(self.db, self.trait_env.krate) else {
|
||||||
.db
|
|
||||||
.lang_item(self.trait_env.krate, LangItem::Sized)
|
|
||||||
.and_then(|sized| sized.as_trait())
|
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let sized_pred = WhereClause::Implemented(TraitRef {
|
let sized_pred = WhereClause::Implemented(TraitRef {
|
||||||
|
|
|
||||||
|
|
@ -590,10 +590,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
&TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
||||||
let sized_trait = self
|
let sized_trait = LangItem::Sized.resolve_trait(self.db, self.resolver.krate());
|
||||||
.db
|
|
||||||
.lang_item(self.resolver.krate(), LangItem::Sized)
|
|
||||||
.and_then(|lang_item| lang_item.as_trait());
|
|
||||||
// Don't lower associated type bindings as the only possible relaxed trait bound
|
// Don't lower associated type bindings as the only possible relaxed trait bound
|
||||||
// `?Sized` has no of them.
|
// `?Sized` has no of them.
|
||||||
// If we got another trait here ignore the bound completely.
|
// If we got another trait here ignore the bound completely.
|
||||||
|
|
@ -736,10 +733,8 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.unsized_types.contains(&self_ty) {
|
if !ctx.unsized_types.contains(&self_ty) {
|
||||||
let sized_trait = ctx
|
let sized_trait =
|
||||||
.db
|
LangItem::Sized.resolve_trait(ctx.db, krate).map(to_chalk_trait_id);
|
||||||
.lang_item(krate, LangItem::Sized)
|
|
||||||
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
|
|
||||||
let sized_clause = sized_trait.map(|trait_id| {
|
let sized_clause = sized_trait.map(|trait_id| {
|
||||||
let clause = WhereClause::Implemented(TraitRef {
|
let clause = WhereClause::Implemented(TraitRef {
|
||||||
trait_id,
|
trait_id,
|
||||||
|
|
@ -1188,9 +1183,7 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
|
||||||
substitution: &'subst Substitution,
|
substitution: &'subst Substitution,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
) -> Option<impl Iterator<Item = WhereClause> + Captures<'a> + Captures<'subst>> {
|
) -> Option<impl Iterator<Item = WhereClause> + Captures<'a> + Captures<'subst>> {
|
||||||
let sized_trait = db
|
let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id)?;
|
||||||
.lang_item(resolver.krate(), LangItem::Sized)
|
|
||||||
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?;
|
|
||||||
|
|
||||||
let trait_self_idx = trait_self_param_idx(db, def);
|
let trait_self_idx = trait_self_param_idx(db, def);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -655,22 +655,15 @@ impl Evaluator<'_> {
|
||||||
mir_or_dyn_index_cache: RefCell::new(Default::default()),
|
mir_or_dyn_index_cache: RefCell::new(Default::default()),
|
||||||
unused_locals_store: RefCell::new(Default::default()),
|
unused_locals_store: RefCell::new(Default::default()),
|
||||||
cached_ptr_size,
|
cached_ptr_size,
|
||||||
cached_fn_trait_func: db
|
cached_fn_trait_func: LangItem::Fn
|
||||||
.lang_item(crate_id, LangItem::Fn)
|
.resolve_trait(db, crate_id)
|
||||||
.and_then(|x| x.as_trait())
|
|
||||||
.and_then(|x| db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call))),
|
.and_then(|x| db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call))),
|
||||||
cached_fn_mut_trait_func: db
|
cached_fn_mut_trait_func: LangItem::FnMut.resolve_trait(db, crate_id).and_then(|x| {
|
||||||
.lang_item(crate_id, LangItem::FnMut)
|
db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut))
|
||||||
.and_then(|x| x.as_trait())
|
}),
|
||||||
.and_then(|x| {
|
cached_fn_once_trait_func: LangItem::FnOnce.resolve_trait(db, crate_id).and_then(|x| {
|
||||||
db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut))
|
db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once))
|
||||||
}),
|
}),
|
||||||
cached_fn_once_trait_func: db
|
|
||||||
.lang_item(crate_id, LangItem::FnOnce)
|
|
||||||
.and_then(|x| x.as_trait())
|
|
||||||
.and_then(|x| {
|
|
||||||
db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once))
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2811,7 +2804,7 @@ impl Evaluator<'_> {
|
||||||
span: MirSpan,
|
span: MirSpan,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let Some(drop_fn) = (|| {
|
let Some(drop_fn) = (|| {
|
||||||
let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?;
|
let drop_trait = LangItem::Drop.resolve_trait(self.db, self.crate_id)?;
|
||||||
self.db.trait_items(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop))
|
self.db.trait_items(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop))
|
||||||
})() else {
|
})() else {
|
||||||
// in some tests we don't have drop trait in minicore, and
|
// in some tests we don't have drop trait in minicore, and
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use std::cmp::{self, Ordering};
|
||||||
use chalk_ir::TyKind;
|
use chalk_ir::TyKind;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
builtin_type::{BuiltinInt, BuiltinUint},
|
builtin_type::{BuiltinInt, BuiltinUint},
|
||||||
lang_item::LangItemTarget,
|
|
||||||
resolver::HasResolver,
|
resolver::HasResolver,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
@ -156,8 +155,8 @@ impl Evaluator<'_> {
|
||||||
if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) {
|
if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) {
|
||||||
let resolver = self.db.crate_def_map(self.crate_id).crate_root().resolver(self.db);
|
let resolver = self.db.crate_def_map(self.crate_id).crate_root().resolver(self.db);
|
||||||
|
|
||||||
let Some(hir_def::lang_item::LangItemTarget::Function(const_panic_fmt)) =
|
let Some(const_panic_fmt) =
|
||||||
self.db.lang_item(resolver.krate(), LangItem::ConstPanicFmt)
|
LangItem::ConstPanicFmt.resolve_function(self.db, resolver.krate())
|
||||||
else {
|
else {
|
||||||
not_supported!("const_panic_fmt lang item not found or not a function");
|
not_supported!("const_panic_fmt lang item not found or not a function");
|
||||||
};
|
};
|
||||||
|
|
@ -1257,12 +1256,12 @@ impl Evaluator<'_> {
|
||||||
let addr = tuple.interval.addr.offset(offset);
|
let addr = tuple.interval.addr.offset(offset);
|
||||||
args.push(IntervalAndTy::new(addr, field, self, locals)?);
|
args.push(IntervalAndTy::new(addr, field, self, locals)?);
|
||||||
}
|
}
|
||||||
if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) {
|
if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id) {
|
||||||
if let Some(def) = target.as_trait().and_then(|it| {
|
if let Some(def) = self
|
||||||
self.db
|
.db
|
||||||
.trait_items(it)
|
.trait_items(target)
|
||||||
.method_by_name(&Name::new_symbol_root(sym::call_once))
|
.method_by_name(&Name::new_symbol_root(sym::call_once))
|
||||||
}) {
|
{
|
||||||
self.exec_fn_trait(
|
self.exec_fn_trait(
|
||||||
def,
|
def,
|
||||||
&args,
|
&args,
|
||||||
|
|
@ -1376,9 +1375,7 @@ impl Evaluator<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(LangItemTarget::EnumId(e)) =
|
if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) {
|
||||||
self.db.lang_item(self.crate_id, LangItem::Ordering)
|
|
||||||
{
|
|
||||||
let ty = self.db.ty(e.into());
|
let ty = self.db.ty(e.into());
|
||||||
let r = self
|
let r = self
|
||||||
.compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
|
.compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use hir_def::{
|
||||||
Pat, PatId, RecordFieldPat, RecordLitField,
|
Pat, PatId, RecordFieldPat, RecordLitField,
|
||||||
},
|
},
|
||||||
item_tree::FieldsShape,
|
item_tree::FieldsShape,
|
||||||
lang_item::{LangItem, LangItemTarget},
|
lang_item::{LangItem, LangItemTarget, lang_item},
|
||||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
@ -1727,7 +1727,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
|
|
||||||
fn resolve_lang_item(&self, item: LangItem) -> Result<LangItemTarget> {
|
fn resolve_lang_item(&self, item: LangItem) -> Result<LangItemTarget> {
|
||||||
let crate_id = self.owner.module(self.db).krate();
|
let crate_id = self.owner.module(self.db).krate();
|
||||||
self.db.lang_item(crate_id, item).ok_or(MirLowerError::LangItemNotFound(item))
|
lang_item(self.db, crate_id, item).ok_or(MirLowerError::LangItemNotFound(item))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_block_to_place(
|
fn lower_block_to_place(
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ use chalk_recursive::Cache;
|
||||||
use chalk_solve::{Solver, logging_db::LoggingRustIrDatabase, rust_ir};
|
use chalk_solve::{Solver, logging_db::LoggingRustIrDatabase, rust_ir};
|
||||||
|
|
||||||
use base_db::Crate;
|
use base_db::Crate;
|
||||||
use hir_def::{
|
use hir_def::{BlockId, TraitId, lang_item::LangItem};
|
||||||
BlockId, TraitId,
|
|
||||||
lang_item::{LangItem, LangItemTarget},
|
|
||||||
};
|
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use intern::sym;
|
use intern::sym;
|
||||||
use span::Edition;
|
use span::Edition;
|
||||||
|
|
@ -292,10 +289,6 @@ impl FnTrait {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<TraitId> {
|
pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<TraitId> {
|
||||||
let target = db.lang_item(krate, self.lang_item())?;
|
self.lang_item().resolve_trait(db, krate)
|
||||||
match target {
|
|
||||||
LangItemTarget::Trait(t) => Some(t),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,7 @@ use crate::{
|
||||||
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
|
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
|
||||||
[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]
|
[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |lang| db.lang_item(krate, lang))
|
.filter_map(move |lang| lang.resolve_trait(db, krate))
|
||||||
.flat_map(|it| it.as_trait())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the direct super traits (including the trait itself).
|
/// Returns an iterator over the direct super traits (including the trait itself).
|
||||||
|
|
|
||||||
|
|
@ -516,8 +516,7 @@ impl HirDisplay for TypeParam {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let sized_trait =
|
let sized_trait = LangItem::Sized.resolve_trait(f.db, krate);
|
||||||
f.db.lang_item(krate, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
|
|
||||||
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
|
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
|
||||||
WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
|
WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,6 @@ use hir_def::{
|
||||||
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
||||||
},
|
},
|
||||||
item_tree::{AttrOwner, FieldParent, ImportAlias, ItemTreeFieldId, ItemTreeNode},
|
item_tree::{AttrOwner, FieldParent, ImportAlias, ItemTreeFieldId, ItemTreeNode},
|
||||||
lang_item::LangItemTarget,
|
|
||||||
layout::{self, ReprOptions, TargetDataLayout},
|
layout::{self, ReprOptions, TargetDataLayout},
|
||||||
nameres::{self, diagnostics::DefDiagnostic},
|
nameres::{self, diagnostics::DefDiagnostic},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
|
|
@ -781,7 +780,7 @@ impl Module {
|
||||||
let drop_maybe_dangle = (|| {
|
let drop_maybe_dangle = (|| {
|
||||||
// FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper
|
// FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper
|
||||||
let trait_ = trait_?;
|
let trait_ = trait_?;
|
||||||
let drop_trait = db.lang_item(self.krate().into(), LangItem::Drop)?.as_trait()?;
|
let drop_trait = LangItem::Drop.resolve_trait(db, self.krate().into())?;
|
||||||
if drop_trait != trait_.into() {
|
if drop_trait != trait_.into() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -2388,14 +2387,11 @@ impl Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false };
|
let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false };
|
||||||
let Some(future_trait_id) =
|
let Some(future_trait_id) = LangItem::Future.resolve_trait(db, self.ty(db).env.krate)
|
||||||
db.lang_item(self.ty(db).env.krate, LangItem::Future).and_then(|t| t.as_trait())
|
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let Some(sized_trait_id) =
|
let Some(sized_trait_id) = LangItem::Sized.resolve_trait(db, self.ty(db).env.krate) else {
|
||||||
db.lang_item(self.ty(db).env.krate, LangItem::Sized).and_then(|t| t.as_trait())
|
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2861,9 +2857,7 @@ pub struct Trait {
|
||||||
|
|
||||||
impl Trait {
|
impl Trait {
|
||||||
pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> {
|
pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> {
|
||||||
db.lang_item(krate.into(), LangItem::from_name(name)?)
|
LangItem::from_name(name)?.resolve_trait(db, krate.into()).map(Into::into)
|
||||||
.and_then(LangItemTarget::as_trait)
|
|
||||||
.map(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||||
|
|
@ -4989,18 +4983,14 @@ impl Type {
|
||||||
/// `std::future::Future` and returns the `Output` associated type.
|
/// `std::future::Future` and returns the `Output` associated type.
|
||||||
/// This function is used in `.await` syntax completion.
|
/// This function is used in `.await` syntax completion.
|
||||||
pub fn into_future_output(&self, db: &dyn HirDatabase) -> Option<Type> {
|
pub fn into_future_output(&self, db: &dyn HirDatabase) -> Option<Type> {
|
||||||
let trait_ = db
|
let trait_ = LangItem::IntoFutureIntoFuture
|
||||||
.lang_item(self.env.krate, LangItem::IntoFutureIntoFuture)
|
.resolve_function(db, self.env.krate)
|
||||||
.and_then(|it| {
|
.and_then(|into_future_fn| {
|
||||||
let into_future_fn = it.as_function()?;
|
|
||||||
let assoc_item = as_assoc_item(db, AssocItem::Function, 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)?;
|
let into_future_trait = assoc_item.container_or_implemented_trait(db)?;
|
||||||
Some(into_future_trait.id)
|
Some(into_future_trait.id)
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| LangItem::Future.resolve_trait(db, self.env.krate))?;
|
||||||
let future_trait = db.lang_item(self.env.krate, LangItem::Future)?;
|
|
||||||
future_trait.as_trait()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let canonical_ty =
|
let canonical_ty =
|
||||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
|
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
|
||||||
|
|
@ -5015,14 +5005,13 @@ impl Type {
|
||||||
|
|
||||||
/// This does **not** resolve `IntoFuture`, only `Future`.
|
/// This does **not** resolve `IntoFuture`, only `Future`.
|
||||||
pub fn future_output(self, db: &dyn HirDatabase) -> Option<Type> {
|
pub fn future_output(self, db: &dyn HirDatabase) -> Option<Type> {
|
||||||
let future_output =
|
let future_output = LangItem::FutureOutput.resolve_type_alias(db, self.env.krate)?;
|
||||||
db.lang_item(self.env.krate, LangItem::FutureOutput)?.as_type_alias()?;
|
|
||||||
self.normalize_trait_assoc_type(db, &[], future_output.into())
|
self.normalize_trait_assoc_type(db, &[], future_output.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This does **not** resolve `IntoIterator`, only `Iterator`.
|
/// This does **not** resolve `IntoIterator`, only `Iterator`.
|
||||||
pub fn iterator_item(self, db: &dyn HirDatabase) -> Option<Type> {
|
pub fn iterator_item(self, db: &dyn HirDatabase) -> Option<Type> {
|
||||||
let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?;
|
let iterator_trait = LangItem::Iterator.resolve_trait(db, self.env.krate)?;
|
||||||
let iterator_item = db
|
let iterator_item = db
|
||||||
.trait_items(iterator_trait)
|
.trait_items(iterator_trait)
|
||||||
.associated_type_by_name(&Name::new_symbol_root(sym::Item))?;
|
.associated_type_by_name(&Name::new_symbol_root(sym::Item))?;
|
||||||
|
|
@ -5030,9 +5019,7 @@ impl Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool {
|
pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool {
|
||||||
let Some(iterator_trait) =
|
let Some(iterator_trait) = LangItem::Iterator.resolve_trait(db, self.env.krate) else {
|
||||||
db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait())
|
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let canonical_ty =
|
let canonical_ty =
|
||||||
|
|
@ -5042,12 +5029,13 @@ impl Type {
|
||||||
|
|
||||||
/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
|
/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
|
||||||
pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
|
pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
|
||||||
let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {
|
let trait_ = LangItem::IntoIterIntoIter.resolve_function(db, self.env.krate).and_then(
|
||||||
let into_iter_fn = it.as_function()?;
|
|into_iter_fn| {
|
||||||
let assoc_item = as_assoc_item(db, AssocItem::Function, 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)?;
|
let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
|
||||||
Some(into_iter_trait.id)
|
Some(into_iter_trait.id)
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
let canonical_ty =
|
let canonical_ty =
|
||||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
|
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
|
||||||
|
|
@ -5133,10 +5121,8 @@ impl Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
|
pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
|
||||||
let lang_item = db.lang_item(self.env.krate, LangItem::Copy);
|
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, self.env.krate) else {
|
||||||
let copy_trait = match lang_item {
|
return false;
|
||||||
Some(LangItemTarget::Trait(it)) => it,
|
|
||||||
_ => return false,
|
|
||||||
};
|
};
|
||||||
self.impls_trait(db, copy_trait.into(), &[])
|
self.impls_trait(db, copy_trait.into(), &[])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -556,8 +556,8 @@ impl SourceAnalyzer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let future_trait = db.lang_item(self.resolver.krate(), LangItem::Future)?.as_trait()?;
|
let future_trait = LangItem::Future.resolve_trait(db, self.resolver.krate())?;
|
||||||
let poll_fn = db.lang_item(self.resolver.krate(), LangItem::FuturePoll)?.as_function()?;
|
let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?;
|
||||||
// HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
|
// 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()`.
|
// doesn't have any generic parameters, so we skip building another subst for `poll()`.
|
||||||
let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
|
let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
|
||||||
|
|
@ -666,7 +666,7 @@ impl SourceAnalyzer {
|
||||||
) -> Option<FunctionId> {
|
) -> Option<FunctionId> {
|
||||||
let ty = self.ty_of_expr(try_expr.expr()?)?;
|
let ty = self.ty_of_expr(try_expr.expr()?)?;
|
||||||
|
|
||||||
let op_fn = db.lang_item(self.resolver.krate(), LangItem::TryTraitBranch)?.as_function()?;
|
let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?;
|
||||||
let op_trait = match op_fn.lookup(db).container {
|
let op_trait = match op_fn.lookup(db).container {
|
||||||
ItemContainerId::TraitId(id) => id,
|
ItemContainerId::TraitId(id) => id,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
|
@ -1425,7 +1425,7 @@ impl SourceAnalyzer {
|
||||||
lang_trait: LangItem,
|
lang_trait: LangItem,
|
||||||
method_name: &Name,
|
method_name: &Name,
|
||||||
) -> Option<(TraitId, FunctionId)> {
|
) -> Option<(TraitId, FunctionId)> {
|
||||||
let trait_id = db.lang_item(self.resolver.krate(), lang_trait)?.as_trait()?;
|
let trait_id = lang_trait.resolve_trait(db, self.resolver.krate())?;
|
||||||
let fn_id = db.trait_items(trait_id).method_by_name(method_name)?;
|
let fn_id = db.trait_items(trait_id).method_by_name(method_name)?;
|
||||||
Some((trait_id, fn_id))
|
Some((trait_id, fn_id))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -634,9 +634,7 @@ fn walk_and_push_ty(
|
||||||
} else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
|
} else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
|
||||||
push_new_def(trait_.into());
|
push_new_def(trait_.into());
|
||||||
} else if let Some(tp) = t.as_type_param(db) {
|
} else if let Some(tp) = t.as_type_param(db) {
|
||||||
let sized_trait = db
|
let sized_trait = LangItem::Sized.resolve_trait(db, t.krate(db).into());
|
||||||
.lang_item(t.krate(db).into(), LangItem::Sized)
|
|
||||||
.and_then(|lang_item| lang_item.as_trait());
|
|
||||||
tp.trait_bounds(db)
|
tp.trait_bounds(db)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|&it| Some(it.into()) != sized_trait)
|
.filter(|&it| Some(it.into()) != sized_trait)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue