Reduce impl_signature query dependencies in method resolution

This commit is contained in:
Lukas Wirth
2026-01-02 13:16:21 +01:00
parent e19dfc83c3
commit 439c095212
10 changed files with 36 additions and 36 deletions

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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 {{ ... }}");
}

View File

@@ -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 {

View File

@@ -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];

View File

@@ -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,

View File

@@ -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_",
]
"#]],

View File

@@ -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.

View File

@@ -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
"#]],
);
}