mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2026-03-24 20:40:30 +00:00
Reduce impl_signature query dependencies in method resolution
This commit is contained in:
@@ -158,7 +158,7 @@ pub struct ItemScope {
|
||||
/// declared.
|
||||
declarations: ThinVec<ModuleDefId>,
|
||||
|
||||
impls: ThinVec<ImplId>,
|
||||
impls: ThinVec<(ImplId, /* trait impl */ bool)>,
|
||||
builtin_derive_impls: ThinVec<BuiltinDeriveImplId>,
|
||||
extern_blocks: ThinVec<ExternBlockId>,
|
||||
unnamed_consts: ThinVec<ConstId>,
|
||||
@@ -327,7 +327,15 @@ impl ItemScope {
|
||||
}
|
||||
|
||||
pub fn impls(&self) -> impl ExactSizeIterator<Item = ImplId> + '_ {
|
||||
self.impls.iter().copied()
|
||||
self.impls.iter().map(|&(id, _)| id)
|
||||
}
|
||||
|
||||
pub fn trait_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
|
||||
self.impls.iter().filter(|&&(_, is_trait_impl)| is_trait_impl).map(|&(id, _)| id)
|
||||
}
|
||||
|
||||
pub fn inherent_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
|
||||
self.impls.iter().filter(|&&(_, is_trait_impl)| !is_trait_impl).map(|&(id, _)| id)
|
||||
}
|
||||
|
||||
pub fn builtin_derive_impls(&self) -> impl ExactSizeIterator<Item = BuiltinDeriveImplId> + '_ {
|
||||
@@ -472,8 +480,8 @@ impl ItemScope {
|
||||
self.legacy_macros.get(name).map(|it| &**it)
|
||||
}
|
||||
|
||||
pub(crate) fn define_impl(&mut self, imp: ImplId) {
|
||||
self.impls.push(imp);
|
||||
pub(crate) fn define_impl(&mut self, imp: ImplId, is_trait_impl: bool) {
|
||||
self.impls.push((imp, is_trait_impl));
|
||||
}
|
||||
|
||||
pub(crate) fn define_builtin_derive_impl(&mut self, imp: BuiltinDeriveImplId) {
|
||||
|
||||
@@ -614,7 +614,9 @@ pub struct Trait {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Impl {}
|
||||
pub struct Impl {
|
||||
pub is_trait_impl: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TypeAlias {
|
||||
|
||||
@@ -271,7 +271,7 @@ impl<'a> Ctx<'a> {
|
||||
let ast_id = self.source_ast_id_map.ast_id(impl_def);
|
||||
// Note that trait impls don't get implicit `Self` unlike traits, because here they are a
|
||||
// type alias rather than a type parameter, so this is handled by the resolver.
|
||||
let res = Impl {};
|
||||
let res = Impl { is_trait_impl: impl_def.trait_().is_some() };
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Impl(res));
|
||||
ast_id
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ impl Printer<'_> {
|
||||
w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition));
|
||||
}
|
||||
ModItemId::Impl(ast_id) => {
|
||||
let Impl {} = &self.tree[ast_id];
|
||||
let Impl { is_trait_impl: _ } = &self.tree[ast_id];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
w!(self, "impl {{ ... }}");
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt
|
||||
let crate_def_map = crate_def_map(db, krate);
|
||||
|
||||
for (_, module_data) in crate_def_map.modules() {
|
||||
for impl_def in module_data.scope.impls() {
|
||||
for impl_def in module_data.scope.inherent_impls() {
|
||||
lang_items.collect_lang_item(db, impl_def);
|
||||
for &(_, assoc) in impl_def.impl_items(db).items.iter() {
|
||||
match assoc {
|
||||
|
||||
@@ -2028,7 +2028,9 @@ impl ModCollector<'_, '_> {
|
||||
let impl_id =
|
||||
ImplLoc { container: module_id, id: InFile::new(self.file_id(), imp) }
|
||||
.intern(db);
|
||||
self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
|
||||
self.def_collector.def_map.modules[self.module_id]
|
||||
.scope
|
||||
.define_impl(impl_id, self.item_tree[imp].is_trait_impl)
|
||||
}
|
||||
ModItemId::Function(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
@@ -609,12 +609,7 @@ impl InherentImpls {
|
||||
map: &mut FxHashMap<SimplifiedType, Vec<ImplId>>,
|
||||
) {
|
||||
for (_module_id, module_data) in def_map.modules() {
|
||||
for impl_id in module_data.scope.impls() {
|
||||
let data = db.impl_signature(impl_id);
|
||||
if data.target_trait.is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
for impl_id in module_data.scope.inherent_impls() {
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let self_ty = db.impl_self_ty(impl_id);
|
||||
let self_ty = self_ty.instantiate_identity();
|
||||
@@ -730,7 +725,7 @@ impl TraitImpls {
|
||||
map: &mut FxHashMap<TraitId, OneTraitImplsBuilder>,
|
||||
) {
|
||||
for (_module_id, module_data) in def_map.modules() {
|
||||
for impl_id in module_data.scope.impls() {
|
||||
for impl_id in module_data.scope.trait_impls() {
|
||||
let trait_ref = match db.impl_trait(impl_id) {
|
||||
Some(tr) => tr.instantiate_identity(),
|
||||
None => continue,
|
||||
|
||||
@@ -539,12 +539,6 @@ impl SomeStruct {
|
||||
"AttrFlags::query_",
|
||||
"AttrFlags::query_",
|
||||
"AttrFlags::query_",
|
||||
"impl_trait_with_diagnostics_query",
|
||||
"impl_signature_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"impl_self_ty_with_diagnostics_query",
|
||||
"struct_signature_shim",
|
||||
"struct_signature_with_source_map_shim",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
@@ -617,7 +611,6 @@ fn main() {
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"AttrFlags::query_",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
@@ -633,13 +626,14 @@ fn main() {
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"value_ty_query",
|
||||
"InherentImpls::for_crate_",
|
||||
"impl_signature_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"callable_item_signature_query",
|
||||
"TraitImpls::for_crate_and_deps_",
|
||||
"TraitImpls::for_crate_",
|
||||
"impl_trait_with_diagnostics_query",
|
||||
"impl_signature_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"impl_self_ty_with_diagnostics_query",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
]
|
||||
"#]],
|
||||
@@ -710,7 +704,6 @@ fn main() {
|
||||
"crate_lang_items",
|
||||
"AttrFlags::query_",
|
||||
"AttrFlags::query_",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
@@ -722,12 +715,13 @@ fn main() {
|
||||
"struct_signature_with_source_map_shim",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"InherentImpls::for_crate_",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"impl_signature_shim",
|
||||
"callable_item_signature_query",
|
||||
"TraitImpls::for_crate_",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"impl_signature_shim",
|
||||
"impl_trait_with_diagnostics_query",
|
||||
"impl_self_ty_with_diagnostics_query",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
]
|
||||
"#]],
|
||||
|
||||
@@ -803,22 +803,21 @@ impl Module {
|
||||
emit_def_diagnostic(db, acc, diag, edition, loc.container.krate(db));
|
||||
}
|
||||
|
||||
if impl_signature.target_trait.is_none()
|
||||
&& !is_inherent_impl_coherent(db, def_map, impl_id)
|
||||
{
|
||||
let trait_impl = impl_signature.target_trait.is_some();
|
||||
if !trait_impl && !is_inherent_impl_coherent(db, def_map, impl_id) {
|
||||
acc.push(IncoherentImpl { impl_: ast_id_map.get(loc.id.value), file_id }.into())
|
||||
}
|
||||
|
||||
if !impl_def.check_orphan_rules(db) {
|
||||
if trait_impl && !impl_def.check_orphan_rules(db) {
|
||||
acc.push(TraitImplOrphan { impl_: ast_id_map.get(loc.id.value), file_id }.into())
|
||||
}
|
||||
|
||||
let trait_ = impl_def.trait_(db);
|
||||
let trait_ = trait_impl.then(|| impl_def.trait_(db)).flatten();
|
||||
let mut trait_is_unsafe = trait_.is_some_and(|t| t.is_unsafe(db));
|
||||
let impl_is_negative = impl_def.is_negative(db);
|
||||
let impl_is_unsafe = impl_def.is_unsafe(db);
|
||||
|
||||
let trait_is_unresolved = trait_.is_none() && impl_signature.target_trait.is_some();
|
||||
let trait_is_unresolved = trait_.is_none() && trait_impl;
|
||||
if trait_is_unresolved {
|
||||
// Ignore trait safety errors when the trait is unresolved, as otherwise we'll treat it as safe,
|
||||
// which may not be correct.
|
||||
|
||||
@@ -781,9 +781,9 @@ fn main() {
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
|
||||
ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED
|
||||
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
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user