Rollup merge of #127107 - mu001999-contrib:dead/enhance-2, r=pnkfelix
Improve dead code analysis Fixes #120770 1. check impl items later if self ty is private although the trait method is public, cause we must use the ty firstly if it's private 2. mark the adt live if it appears in pattern, like generic argument, this implies the use of the adt 3. based on the above, we can handle the case that private adts impl Default, so that we don't need adding rustc_trivial_field_reads on Default, and the logic in should_ignore_item r? ``@pnkfelix``
This commit is contained in:
commit
31fe9628cf
21 changed files with 173 additions and 69 deletions
|
@ -277,7 +277,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||
pats: &[hir::PatField<'_>],
|
||||
) {
|
||||
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
|
||||
ty::Adt(adt, _) => adt.variant_of_res(res),
|
||||
ty::Adt(adt, _) => {
|
||||
self.check_def_id(adt.did());
|
||||
adt.variant_of_res(res)
|
||||
}
|
||||
_ => span_bug!(lhs.span, "non-ADT in struct pattern"),
|
||||
};
|
||||
for pat in pats {
|
||||
|
@ -297,7 +300,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||
dotdot: hir::DotDotPos,
|
||||
) {
|
||||
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
|
||||
ty::Adt(adt, _) => adt.variant_of_res(res),
|
||||
ty::Adt(adt, _) => {
|
||||
self.check_def_id(adt.did());
|
||||
adt.variant_of_res(res)
|
||||
}
|
||||
_ => {
|
||||
self.tcx.dcx().span_delayed_bug(lhs.span, "non-ADT in tuple struct pattern");
|
||||
return;
|
||||
|
@ -402,31 +408,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||
return false;
|
||||
}
|
||||
|
||||
// don't ignore impls for Enums and pub Structs whose methods don't have self receiver,
|
||||
// cause external crate may call such methods to construct values of these types
|
||||
if let Some(local_impl_of) = impl_of.as_local()
|
||||
&& let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(fn_sig) =
|
||||
self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
|
||||
&& matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
|
||||
&& let TyKind::Path(hir::QPath::Resolved(_, path)) =
|
||||
self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind
|
||||
&& let Res::Def(def_kind, did) = path.res
|
||||
{
|
||||
match def_kind {
|
||||
// for example, #[derive(Default)] pub struct T(i32);
|
||||
// external crate can call T::default() to construct T,
|
||||
// so that don't ignore impl Default for pub Enum and Structs
|
||||
DefKind::Struct | DefKind::Union if self.tcx.visibility(did).is_public() => {
|
||||
return false;
|
||||
}
|
||||
// don't ignore impl Default for Enums,
|
||||
// cause we don't know which variant is constructed
|
||||
DefKind::Enum => return false,
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
|
||||
&& self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
|
||||
{
|
||||
|
@ -690,6 +671,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
|||
self.handle_field_pattern_match(pat, res, fields);
|
||||
}
|
||||
PatKind::Path(ref qpath) => {
|
||||
if let ty::Adt(adt, _) = self.typeck_results().node_type(pat.hir_id).kind() {
|
||||
self.check_def_id(adt.did());
|
||||
}
|
||||
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
|
||||
self.handle_res(res);
|
||||
}
|
||||
|
@ -845,7 +829,7 @@ fn check_item<'tcx>(
|
|||
// mark the method live if the self_ty is public,
|
||||
// or the method is public and may construct self
|
||||
if tcx.visibility(local_def_id).is_public()
|
||||
&& (ty_and_all_fields_are_public || may_construct_self)
|
||||
&& (ty_and_all_fields_are_public || (ty_is_public && may_construct_self))
|
||||
{
|
||||
// if the impl item is public,
|
||||
// and the ty may be constructed or can be constructed in foreign crates,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue