File tree Expand file tree Collapse file tree 2 files changed +60
-0
lines changed
ide-diagnostics/src/handlers Expand file tree Collapse file tree 2 files changed +60
-0
lines changed Original file line number Diff line number Diff 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 {
Original file line number Diff line number Diff 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}
You can’t perform that action at this time.
0 commit comments