@@ -1035,6 +1035,12 @@ fn check_impl_items_against_trait<'tcx>(
1035
1035
1036
1036
let trait_def = tcx. trait_def ( trait_ref. def_id ) ;
1037
1037
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
+
1038
1044
for & impl_item in impl_item_refs {
1039
1045
let ty_impl_item = tcx. associated_item ( impl_item) ;
1040
1046
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>(
1064
1070
}
1065
1071
}
1066
1072
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
+
1067
1082
check_specialization_validity (
1068
1083
tcx,
1069
1084
trait_def,
@@ -1087,7 +1102,11 @@ fn check_impl_items_against_trait<'tcx>(
1087
1102
. as_ref ( )
1088
1103
. is_some_and ( |node_item| node_item. item . defaultness ( tcx) . has_value ( ) ) ;
1089
1104
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
+ {
1091
1110
missing_items. push ( tcx. associated_item ( trait_item_id) ) ;
1092
1111
}
1093
1112
0 commit comments