1
Fork 0

Improve dead code analysis

This commit is contained in:
mu001999 2024-07-04 22:05:00 +08:00
parent bae813a265
commit 0adb82528f
21 changed files with 173 additions and 69 deletions

View file

@ -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,