@@ -1035,6 +1035,12 @@ fn check_impl_items_against_trait<'tcx>(
10351035
10361036 let trait_def = tcx. trait_def ( trait_ref. def_id ) ;
10371037
1038+ let self_is_guaranteed_unsized =
1039+ match tcx. struct_tail_raw ( trait_ref. self_ty ( ) , |ty| ty, || { } ) . kind ( ) {
1040+ ty:: Dynamic ( _, _, ty:: DynKind :: Dyn ) | ty:: Slice ( _) | ty:: Str => true ,
1041+ _ => false ,
1042+ } ;
1043+
10381044 for & impl_item in impl_item_refs {
10391045 let ty_impl_item = tcx. associated_item ( impl_item) ;
10401046 let ty_trait_item = if let Some ( trait_item_id) = ty_impl_item. trait_item_def_id {
@@ -1064,6 +1070,15 @@ fn check_impl_items_against_trait<'tcx>(
10641070 }
10651071 }
10661072
1073+ if self_is_guaranteed_unsized && tcx. generics_require_sized_self ( ty_trait_item. def_id ) {
1074+ tcx. emit_node_span_lint (
1075+ rustc_lint_defs:: builtin:: DEAD_CODE ,
1076+ tcx. local_def_id_to_hir_id ( ty_impl_item. def_id . expect_local ( ) ) ,
1077+ tcx. def_span ( ty_impl_item. def_id ) ,
1078+ errors:: UselessImplItem ,
1079+ )
1080+ }
1081+
10671082 check_specialization_validity (
10681083 tcx,
10691084 trait_def,
@@ -1087,7 +1102,11 @@ fn check_impl_items_against_trait<'tcx>(
10871102 . as_ref ( )
10881103 . is_some_and ( |node_item| node_item. item . defaultness ( tcx) . has_value ( ) ) ;
10891104
1090- if !is_implemented && tcx. defaultness ( impl_id) . is_final ( ) {
1105+ if !is_implemented
1106+ && tcx. defaultness ( impl_id) . is_final ( )
1107+ // unsized types don't need to implement methods that have `Self: Sized` bounds.
1108+ && !( self_is_guaranteed_unsized && tcx. generics_require_sized_self ( trait_item_id) )
1109+ {
10911110 missing_items. push ( tcx. associated_item ( trait_item_id) ) ;
10921111 }
10931112
0 commit comments