Skip to content

Commit 6a1246b

Browse files
Merge pull request #21403 from ShoyuVanilla/missing-assoc-specialize
fix: Suppress false positive missing assoc item diag on specialization
2 parents 3493b4c + ee12c40 commit 6a1246b

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

‎crates/hir/src/lib.rs‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,48 @@ impl Module {
920920
}
921921
}
922922

923+
// HACK: When specialization is enabled in the current crate, and there exists
924+
// *any* blanket impl that provides a default implementation for the missing item,
925+
// suppress the missing associated item diagnostic.
926+
// This can lead to false negatives when the impl in question does not actually
927+
// specialize that blanket impl, but determining the exact specialization
928+
// relationship here would be significantly more expensive.
929+
if !missing.is_empty() {
930+
let krate = self.krate(db).id;
931+
let def_map = crate_def_map(db, krate);
932+
if def_map.is_unstable_feature_enabled(&sym::specialization)
933+
|| def_map.is_unstable_feature_enabled(&sym::min_specialization)
934+
{
935+
missing.retain(|(assoc_name, assoc_item)| {
936+
let AssocItem::Function(_) = assoc_item else {
937+
return true;
938+
};
939+
940+
for &impl_ in TraitImpls::for_crate(db, krate).blanket_impls(trait_.id)
941+
{
942+
if impl_ == impl_id {
943+
continue;
944+
}
945+
946+
for (name, item) in &impl_.impl_items(db).items {
947+
let AssocItemId::FunctionId(fn_) = item else {
948+
continue;
949+
};
950+
if name != assoc_name {
951+
continue;
952+
}
953+
954+
if db.function_signature(*fn_).is_default() {
955+
return false;
956+
}
957+
}
958+
}
959+
960+
true
961+
});
962+
}
963+
}
964+
923965
if !missing.is_empty() {
924966
acc.push(
925967
TraitImplMissingAssocItems {

‎crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,22 @@ impl Trait for dyn OtherTrait {}
156156
"#,
157157
)
158158
}
159+
160+
#[test]
161+
fn no_false_positive_on_specialization() {
162+
check_diagnostics(
163+
r#"
164+
#![feature(specialization)]
165+
166+
pub trait Foo {
167+
fn foo();
168+
}
169+
170+
impl<T> Foo for T {
171+
default fn foo() {}
172+
}
173+
impl Foo for bool {}
174+
"#,
175+
);
176+
}
159177
}

0 commit comments

Comments
 (0)