Auto merge of #121752 - mu001999:dead_code/improve, r=pnkfelix · rust-lang/rust@c69fda7 (original) (raw)

`@@ -15,7 +15,7 @@ use rustc_hir::{Node, PatKind, TyKind};

`

15

15

`use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;

`

16

16

`use rustc_middle::middle:🔏:Level;

`

17

17

`use rustc_middle::query::Providers;

`

18

``

`-

use rustc_middle::ty::{self, TyCtxt, Visibility};

`

``

18

`+

use rustc_middle::ty::{self, TyCtxt};

`

19

19

`use rustc_session::lint;

`

20

20

`use rustc_session::lint::builtin::DEAD_CODE;

`

21

21

`use rustc_span::symbol::{sym, Symbol};

`

`@@ -45,6 +45,18 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {

`

45

45

`)

`

46

46

`}

`

47

47

``

``

48

`+

fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> bool {

`

``

49

`+

if let TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind

`

``

50

`+

&& let Res::Def(def_kind, def_id) = path.res

`

``

51

`+

&& def_id.is_local()

`

``

52

`+

&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)

`

``

53

`+

{

`

``

54

`+

tcx.visibility(def_id).is_public()

`

``

55

`+

} else {

`

``

56

`+

true

`

``

57

`+

}

`

``

58

`+

}

`

``

59

+

48

60

`` /// Determine if a work from the worklist is coming from the a #[allow]

``

49

61

`` /// or a #[expect] of dead_code

``

50

62

`#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]

`

`@@ -415,6 +427,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {

`

415

427

` && let ItemKind::Impl(impl_ref) =

`

416

428

`self.tcx.hir().expect_item(local_impl_id).kind

`

417

429

`{

`

``

430

`+

if self.tcx.visibility(trait_id).is_public()

`

``

431

`+

&& matches!(trait_item.kind, hir::TraitItemKind::Fn(..))

`

``

432

`+

&& !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)

`

``

433

`+

{

`

``

434

`+

continue;

`

``

435

`+

}

`

``

436

+

418

437

`// mark self_ty live

`

419

438

` intravisit::walk_ty(self, impl_ref.self_ty);

`

420

439

`if let Some(&impl_item_id) =

`

`@@ -465,6 +484,36 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {

`

465

484

`}

`

466

485

`}

`

467

486

`}

`

``

487

+

``

488

`+

fn solve_rest_impl_items(&mut self, mut unsolved_impl_items: Vec<(hir::ItemId, LocalDefId)>) {

`

``

489

`+

let mut ready;

`

``

490

`+

(ready, unsolved_impl_items) = unsolved_impl_items

`

``

491

`+

.into_iter()

`

``

492

`+

.partition(|&(impl_id, _)| self.impl_item_with_used_self(impl_id));

`

``

493

+

``

494

`+

while !ready.is_empty() {

`

``

495

`+

self.worklist =

`

``

496

`+

ready.into_iter().map(|(_, id)| (id, ComesFromAllowExpect::No)).collect();

`

``

497

`+

self.mark_live_symbols();

`

``

498

+

``

499

`+

(ready, unsolved_impl_items) = unsolved_impl_items

`

``

500

`+

.into_iter()

`

``

501

`+

.partition(|&(impl_id, _)| self.impl_item_with_used_self(impl_id));

`

``

502

`+

}

`

``

503

`+

}

`

``

504

+

``

505

`+

fn impl_item_with_used_self(&mut self, impl_id: hir::ItemId) -> bool {

`

``

506

`+

if let TyKind::Path(hir::QPath::Resolved(_, path)) =

`

``

507

`+

self.tcx.hir().item(impl_id).expect_impl().self_ty.kind

`

``

508

`+

&& let Res::Def(def_kind, def_id) = path.res

`

``

509

`+

&& let Some(local_def_id) = def_id.as_local()

`

``

510

`+

&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)

`

``

511

`+

{

`

``

512

`+

self.live_symbols.contains(&local_def_id)

`

``

513

`+

} else {

`

``

514

`+

false

`

``

515

`+

}

`

``

516

`+

}

`

468

517

`}

`

469

518

``

470

519

`impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {

`

`@@ -652,6 +701,7 @@ fn check_item<'tcx>(

`

652

701

`tcx: TyCtxt<'tcx>,

`

653

702

`worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,

`

654

703

`struct_constructors: &mut LocalDefIdMap,

`

``

704

`+

unsolved_impl_items: &mut Vec<(hir::ItemId, LocalDefId)>,

`

655

705

`id: hir::ItemId,

`

656

706

`) {

`

657

707

`let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id);

`

`@@ -683,16 +733,33 @@ fn check_item<'tcx>(

`

683

733

`.iter()

`

684

734

`.filter_map(|def_id| def_id.as_local());

`

685

735

``

``

736

`+

let ty_is_pub = ty_ref_to_pub_struct(tcx, tcx.hir().item(id).expect_impl().self_ty);

`

``

737

+

686

738

`// And we access the Map here to get HirId from LocalDefId

`

687

``

`-

for id in local_def_ids {

`

``

739

`+

for local_def_id in local_def_ids {

`

``

740

`+

// check the function may construct Self

`

``

741

`+

let mut may_construct_self = true;

`

``

742

`+

if let Some(hir_id) = tcx.opt_local_def_id_to_hir_id(local_def_id)

`

``

743

`+

&& let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id)

`

``

744

`+

{

`

``

745

`+

may_construct_self =

`

``

746

`+

matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None);

`

``

747

`+

}

`

``

748

+

688

749

`// for impl trait blocks, mark associate functions live if the trait is public

`

689

750

`if of_trait

`

690

``

`-

&& (!matches!(tcx.def_kind(id), DefKind::AssocFn)

`

691

``

`-

|| tcx.local_visibility(id) == Visibility::Public)

`

``

751

`+

&& (!matches!(tcx.def_kind(local_def_id), DefKind::AssocFn)

`

``

752

`+

|| tcx.visibility(local_def_id).is_public()

`

``

753

`+

&& (ty_is_pub || may_construct_self))

`

692

754

`{

`

693

``

`-

worklist.push((id, ComesFromAllowExpect::No));

`

694

``

`-

} else if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id) {

`

695

``

`-

worklist.push((id, comes_from_allow));

`

``

755

`+

worklist.push((local_def_id, ComesFromAllowExpect::No));

`

``

756

`+

} else if of_trait && tcx.visibility(local_def_id).is_public() {

`

``

757

`+

// pub method && private ty & methods not construct self

`

``

758

`+

unsolved_impl_items.push((id, local_def_id));

`

``

759

`+

} else if let Some(comes_from_allow) =

`

``

760

`+

has_allow_dead_code_or_lang_attr(tcx, local_def_id)

`

``

761

`+

{

`

``

762

`+

worklist.push((local_def_id, comes_from_allow));

`

696

763

`}

`

697

764

`}

`

698

765

`}

`

`@@ -743,9 +810,14 @@ fn check_foreign_item(

`

743

810

``

744

811

`fn create_and_seed_worklist(

`

745

812

`tcx: TyCtxt<'_>,

`

746

``

`-

) -> (Vec<(LocalDefId, ComesFromAllowExpect)>, LocalDefIdMap) {

`

``

813

`+

) -> (

`

``

814

`+

Vec<(LocalDefId, ComesFromAllowExpect)>,

`

``

815

`+

LocalDefIdMap,

`

``

816

`+

Vec<(hir::ItemId, LocalDefId)>,

`

``

817

`+

) {

`

747

818

`let effective_visibilities = &tcx.effective_visibilities(());

`

748

819

`` // see MarkSymbolVisitor::struct_constructors

``

``

820

`+

let mut unsolved_impl_item = Vec::new();

`

749

821

`let mut struct_constructors = Default::default();

`

750

822

`let mut worklist = effective_visibilities

`

751

823

`.iter()

`

`@@ -764,7 +836,7 @@ fn create_and_seed_worklist(

`

764

836

``

765

837

`let crate_items = tcx.hir_crate_items(());

`

766

838

`for id in crate_items.items() {

`

767

``

`-

check_item(tcx, &mut worklist, &mut struct_constructors, id);

`

``

839

`+

check_item(tcx, &mut worklist, &mut struct_constructors, &mut unsolved_impl_item, id);

`

768

840

`}

`

769

841

``

770

842

`for id in crate_items.trait_items() {

`

`@@ -775,14 +847,14 @@ fn create_and_seed_worklist(

`

775

847

`check_foreign_item(tcx, &mut worklist, id);

`

776

848

`}

`

777

849

``

778

``

`-

(worklist, struct_constructors)

`

``

850

`+

(worklist, struct_constructors, unsolved_impl_item)

`

779

851

`}

`

780

852

``

781

853

`fn live_symbols_and_ignored_derived_traits(

`

782

854

`tcx: TyCtxt<'_>,

`

783

855

`(): (),

`

784

856

`) -> (LocalDefIdSet, LocalDefIdMap<Vec<(DefId, DefId)>>) {

`

785

``

`-

let (worklist, struct_constructors) = create_and_seed_worklist(tcx);

`

``

857

`+

let (worklist, struct_constructors, unsolved_impl_items) = create_and_seed_worklist(tcx);

`

786

858

`let mut symbol_visitor = MarkSymbolVisitor {

`

787

859

` worklist,

`

788

860

` tcx,

`

`@@ -796,6 +868,8 @@ fn live_symbols_and_ignored_derived_traits(

`

796

868

`ignored_derived_traits: Default::default(),

`

797

869

`};

`

798

870

` symbol_visitor.mark_live_symbols();

`

``

871

`+

symbol_visitor.solve_rest_impl_items(unsolved_impl_items);

`

``

872

+

799

873

`(symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits)

`

800

874

`}

`

801

875

``