diff options
| author | Oli Scherer <github333195615777966@oli-obk.de> | 2025-01-14 11:02:29 +0000 |
|---|---|---|
| committer | Oli Scherer <github333195615777966@oli-obk.de> | 2025-02-25 08:06:30 +0000 |
| commit | ffc955bcfb79063b51947d4846591bf162e7ddfe (patch) | |
| tree | e7c8f443e1ac7cd9f7238a11f47d71a591efdd44 /compiler/rustc_hir_analysis/src | |
| parent | f5729cfed3c45e061e8a443677fc1d5ef9277df7 (diff) | |
| download | rust-ffc955bcfb79063b51947d4846591bf162e7ddfe.tar.gz rust-ffc955bcfb79063b51947d4846591bf162e7ddfe.zip | |
Don't require method impls for methods with `Self:Sized` bounds for impls for unsized types
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 41 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 4 |
2 files changed, 44 insertions, 1 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 09320b86878..f2331f3fd8e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -992,6 +992,32 @@ fn check_impl_items_against_trait<'tcx>( let trait_def = tcx.trait_def(trait_ref.def_id); + let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis()); + + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); + let cause = ObligationCause::misc(tcx.def_span(impl_id), impl_id); + let param_env = tcx.param_env(impl_id); + + let self_is_guaranteed_unsized = match tcx + .struct_tail_raw( + trait_ref.self_ty(), + |ty| { + ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| { + Ty::new_error_with_message( + tcx, + tcx.def_span(impl_id), + "struct tail should be computable", + ) + }) + }, + || (), + ) + .kind() + { + ty::Dynamic(_, _, ty::DynKind::Dyn) | ty::Slice(_) | ty::Str => true, + _ => false, + }; + for &impl_item in impl_item_refs { let ty_impl_item = tcx.associated_item(impl_item); let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id { @@ -1021,6 +1047,15 @@ fn check_impl_items_against_trait<'tcx>( } } + if self_is_guaranteed_unsized && tcx.generics_require_sized_self(ty_trait_item.def_id) { + tcx.emit_node_span_lint( + rustc_lint_defs::builtin::DEAD_CODE, + tcx.local_def_id_to_hir_id(ty_impl_item.def_id.expect_local()), + tcx.def_span(ty_impl_item.def_id), + errors::UselessImplItem, + ) + } + check_specialization_validity( tcx, trait_def, @@ -1044,7 +1079,11 @@ fn check_impl_items_against_trait<'tcx>( .as_ref() .is_some_and(|node_item| node_item.item.defaultness(tcx).has_value()); - if !is_implemented && tcx.defaultness(impl_id).is_final() { + if !is_implemented + && tcx.defaultness(impl_id).is_final() + // unsized types don't need to implement methods that have `Self: Sized` bounds. + && !(self_is_guaranteed_unsized && tcx.generics_require_sized_self(trait_item_id)) + { missing_items.push(tcx.associated_item(trait_item_id)); } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 99262f9871e..852533ff5c9 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -908,6 +908,10 @@ pub(crate) enum ImplNotMarkedDefault { }, } +#[derive(LintDiagnostic)] +#[diag(hir_analysis_useless_impl_item)] +pub(crate) struct UselessImplItem; + #[derive(Diagnostic)] #[diag(hir_analysis_missing_trait_item, code = E0046)] pub(crate) struct MissingTraitItem { |
