@@ -1035,6 +1035,37 @@ 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 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
+
1038
1069
for & impl_item in impl_item_refs {
1039
1070
let ty_impl_item = tcx. associated_item ( impl_item) ;
1040
1071
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>(
1064
1095
}
1065
1096
}
1066
1097
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
+
1067
1107
check_specialization_validity (
1068
1108
tcx,
1069
1109
trait_def,
@@ -1087,7 +1127,11 @@ fn check_impl_items_against_trait<'tcx>(
1087
1127
. as_ref ( )
1088
1128
. is_some_and ( |node_item| node_item. item . defaultness ( tcx) . has_value ( ) ) ;
1089
1129
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
+ {
1091
1135
missing_items. push ( tcx. associated_item ( trait_item_id) ) ;
1092
1136
}
1093
1137
0 commit comments