@@ -1035,6 +1035,37 @@ fn check_impl_items_against_trait<'tcx>(
10351035
10361036 let trait_def = tcx. trait_def ( trait_ref. def_id ) ;
10371037
1038+ let infcx = tcx
1039+ . infer_ctxt ( )
1040+ // typeck writeback gives us predicates with their regions erased.
1041+ // As borrowck already has checked lifetimes, we do not need to do it again.
1042+ . ignoring_regions ( )
1043+ . build ( TypingMode :: non_body_analysis ( ) ) ;
1044+
1045+ let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
1046+ let cause = ObligationCause :: misc ( tcx. def_span ( impl_id) , impl_id) ;
1047+ let param_env = tcx. param_env ( impl_id) ;
1048+
1049+ let self_is_guaranteed_unsized = match tcx
1050+ . struct_tail_raw (
1051+ trait_ref. self_ty ( ) ,
1052+ |ty| {
1053+ ocx. structurally_normalize ( & cause, param_env, ty) . unwrap_or_else ( |_| {
1054+ Ty :: new_error_with_message (
1055+ tcx,
1056+ tcx. def_span ( impl_id) ,
1057+ "struct tail should be computable" ,
1058+ )
1059+ } )
1060+ } ,
1061+ || ( ) ,
1062+ )
1063+ . kind ( )
1064+ {
1065+ ty:: Dynamic ( _, _, ty:: DynKind :: Dyn ) | ty:: Slice ( _) | ty:: Str => true ,
1066+ _ => false ,
1067+ } ;
1068+
10381069 for & impl_item in impl_item_refs {
10391070 let ty_impl_item = tcx. associated_item ( impl_item) ;
10401071 let ty_trait_item = if let Some ( trait_item_id) = ty_impl_item. trait_item_def_id {
@@ -1064,6 +1095,15 @@ fn check_impl_items_against_trait<'tcx>(
10641095 }
10651096 }
10661097
1098+ if self_is_guaranteed_unsized && tcx. generics_require_sized_self ( ty_trait_item. def_id ) {
1099+ tcx. emit_node_span_lint (
1100+ rustc_lint_defs:: builtin:: DEAD_CODE ,
1101+ tcx. local_def_id_to_hir_id ( ty_impl_item. def_id . expect_local ( ) ) ,
1102+ tcx. def_span ( ty_impl_item. def_id ) ,
1103+ errors:: UselessImplItem ,
1104+ )
1105+ }
1106+
10671107 check_specialization_validity (
10681108 tcx,
10691109 trait_def,
@@ -1087,7 +1127,11 @@ fn check_impl_items_against_trait<'tcx>(
10871127 . as_ref ( )
10881128 . is_some_and ( |node_item| node_item. item . defaultness ( tcx) . has_value ( ) ) ;
10891129
1090- if !is_implemented && tcx. defaultness ( impl_id) . is_final ( ) {
1130+ if !is_implemented
1131+ && tcx. defaultness ( impl_id) . is_final ( )
1132+ // unsized types don't need to implement methods that have `Self: Sized` bounds.
1133+ && !( self_is_guaranteed_unsized && tcx. generics_require_sized_self ( trait_item_id) )
1134+ {
10911135 missing_items. push ( tcx. associated_item ( trait_item_id) ) ;
10921136 }
10931137
0 commit comments