@@ -606,37 +606,61 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
606606
607607impl < ' tcx > LateLintPass < ' tcx > for MissingDebugImplementations {
608608 fn check_item ( & mut self , cx : & LateContext < ' _ > , item : & hir:: Item < ' _ > ) {
609- if !cx. effective_visibilities . is_reachable ( item. owner_id . def_id ) {
609+ let def_id = item. owner_id . def_id ;
610+ if !cx. effective_visibilities . is_reachable ( def_id) {
610611 return ;
611612 }
612613
613- match item. kind {
614- hir:: ItemKind :: Struct ( ..) | hir:: ItemKind :: Union ( ..) | hir:: ItemKind :: Enum ( ..) => { }
614+ let is_generic = match item. kind {
615+ hir:: ItemKind :: Struct ( _, generics, _)
616+ | hir:: ItemKind :: Union ( _, generics, _)
617+ | hir:: ItemKind :: Enum ( _, generics, _) => !generics. params . is_empty ( ) ,
615618 _ => return ,
616- }
619+ } ;
620+
621+ let tcx = cx. tcx ;
617622
618623 // Avoid listing trait impls if the trait is allowed.
619- if cx . tcx . lint_level_spec_at_node ( MISSING_DEBUG_IMPLEMENTATIONS , item. hir_id ( ) ) . is_allow ( ) {
624+ if tcx. lint_level_spec_at_node ( MISSING_DEBUG_IMPLEMENTATIONS , item. hir_id ( ) ) . is_allow ( ) {
620625 return ;
621626 }
622627
623- let Some ( debug) = cx . tcx . get_diagnostic_item ( sym:: Debug ) else { return } ;
628+ let Some ( debug) = tcx. get_diagnostic_item ( sym:: Debug ) else { return } ;
624629
625- let has_impl = cx
626- . tcx
627- . non_blanket_impls_for_ty (
628- debug,
629- cx. tcx . type_of ( item. owner_id ) . instantiate_identity ( ) . skip_norm_wip ( ) ,
630- )
630+ let ty = tcx. type_of ( item. owner_id ) ;
631+ if tcx
632+ . non_blanket_impls_for_ty ( debug, ty. instantiate_identity ( ) . skip_norm_wip ( ) )
631633 . next ( )
632- . is_some ( ) ;
633- if !has_impl {
634- cx. emit_span_lint (
635- MISSING_DEBUG_IMPLEMENTATIONS ,
636- item. span ,
637- BuiltinMissingDebugImpl { tcx : cx. tcx , def_id : debug } ,
638- ) ;
634+ . is_some ( )
635+ {
636+ return ;
639637 }
638+
639+ let infcx = tcx. infer_ctxt ( ) . build ( cx. typing_mode ( ) ) ;
640+ if is_generic {
641+ let args = infcx. fresh_args_for_item ( item. span , def_id. to_def_id ( ) ) ;
642+ if infcx
643+ . type_implements_trait_shallow (
644+ debug,
645+ ty. instantiate ( tcx, args) . skip_norm_wip ( ) ,
646+ cx. param_env ,
647+ )
648+ . is_some ( )
649+ {
650+ return ;
651+ }
652+ } else if infcx
653+ . type_implements_trait ( debug, [ ty. instantiate_identity ( ) . skip_norm_wip ( ) ] , cx. param_env )
654+ . must_apply_modulo_regions ( )
655+ {
656+ return ;
657+ }
658+
659+ cx. emit_span_lint (
660+ MISSING_DEBUG_IMPLEMENTATIONS ,
661+ item. span ,
662+ BuiltinMissingDebugImpl { tcx : cx. tcx , def_id : debug } ,
663+ ) ;
640664 }
641665}
642666
0 commit comments