Auto merge of #114417 - chinedufn:fix-expect-unused-in-impl-block-rus… · rust-lang/rust@2bbb619 (original) (raw)

1

``

`-

// This implements the dead-code warning pass. It follows middle::reachable

`

2

``

`-

// closely. The idea is that all reachable symbols are live, codes called

`

3

``

`-

// from live codes are live, and everything else is dead.

`

``

1

`+

// This implements the dead-code warning pass.

`

``

2

`+

// All reachable symbols are live, code called from live code is live, code with certain lint

`

``

3

`` +

// expectations such as #[expect(unused)] and #[expect(dead_code)] is live, and everything else

``

``

4

`+

// is dead.

`

4

5

``

5

6

`use hir::def_id::{LocalDefIdMap, LocalDefIdSet};

`

6

7

`use itertools::Itertools;

`

`@@ -747,7 +748,7 @@ fn live_symbols_and_ignored_derived_traits(

`

747

748

`(symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits)

`

748

749

`}

`

749

750

``

750

``

`-

struct DeadVariant {

`

``

751

`+

struct DeadItem {

`

751

752

`def_id: LocalDefId,

`

752

753

`name: Symbol,

`

753

754

`level: lint::Level,

`

`@@ -785,7 +786,13 @@ impl<'tcx> DeadVisitor<'tcx> {

`

785

786

`ShouldWarnAboutField::Yes(is_positional)

`

786

787

`}

`

787

788

``

788

``

`-

fn warn_multiple_dead_codes(

`

``

789

`+

// # Panics

`

``

790

`` +

// All dead_codes must have the same lint level, otherwise we will intentionally ICE.

``

``

791

`` +

// This is because we emit a multi-spanned lint using the lint level of the dead_codes's

``

``

792

`+

// first local def id.

`

``

793

`` +

// Prefer calling Self.warn_dead_code or Self.warn_dead_code_grouped_by_lint_level

``

``

794

`+

// since those methods group by lint level before calling this method.

`

``

795

`+

fn lint_at_single_level(

`

789

796

`&self,

`

790

797

`dead_codes: &[LocalDefId],

`

791

798

`participle: &str,

`

`@@ -796,6 +803,15 @@ impl<'tcx> DeadVisitor<'tcx> {

`

796

803

`return;

`

797

804

`};

`

798

805

`let tcx = self.tcx;

`

``

806

+

``

807

`+

let first_hir_id = tcx.hir().local_def_id_to_hir_id(first_id);

`

``

808

`+

let first_lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, first_hir_id).0;

`

``

809

`+

assert!(dead_codes.iter().skip(1).all(|id| {

`

``

810

`+

let hir_id = tcx.hir().local_def_id_to_hir_id(*id);

`

``

811

`+

let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;

`

``

812

`+

level == first_lint_level

`

``

813

`+

}));

`

``

814

+

799

815

`let names: Vec<_> =

`

800

816

` dead_codes.iter().map(|&def_id| tcx.item_name(def_id.to_def_id())).collect();

`

801

817

`let spans: Vec<_> = dead_codes

`

`@@ -876,31 +892,26 @@ impl<'tcx> DeadVisitor<'tcx> {

`

876

892

`}

`

877

893

`};

`

878

894

``

879

``

`-

self.tcx.emit_spanned_lint(

`

880

``

`-

lint,

`

881

``

`-

tcx.hir().local_def_id_to_hir_id(first_id),

`

882

``

`-

MultiSpan::from_spans(spans),

`

883

``

`-

diag,

`

884

``

`-

);

`

``

895

`+

self.tcx.emit_spanned_lint(lint, first_hir_id, MultiSpan::from_spans(spans), diag);

`

885

896

`}

`

886

897

``

887

``

`-

fn warn_dead_fields_and_variants(

`

``

898

`+

fn warn_multiple(

`

888

899

`&self,

`

889

900

`def_id: LocalDefId,

`

890

901

`participle: &str,

`

891

``

`-

dead_codes: Vec,

`

``

902

`+

dead_codes: Vec,

`

892

903

`is_positional: bool,

`

893

904

`) {

`

894

905

`let mut dead_codes = dead_codes

`

895

906

`.iter()

`

896

907

`.filter(|v| !v.name.as_str().starts_with('_'))

`

897

``

`-

.collect::<Vec<&DeadVariant>>();

`

``

908

`+

.collect::<Vec<&DeadItem>>();

`

898

909

`if dead_codes.is_empty() {

`

899

910

`return;

`

900

911

`}

`

901

912

` dead_codes.sort_by_key(|v| v.level);

`

902

913

`for (_, group) in &dead_codes.into_iter().group_by(|v| v.level) {

`

903

``

`-

self.warn_multiple_dead_codes(

`

``

914

`+

self.lint_at_single_level(

`

904

915

`&group.map(|v| v.def_id).collect::<Vec<_>>(),

`

905

916

` participle,

`

906

917

`Some(def_id),

`

`@@ -910,7 +921,7 @@ impl<'tcx> DeadVisitor<'tcx> {

`

910

921

`}

`

911

922

``

912

923

`fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) {

`

913

``

`-

self.warn_multiple_dead_codes(&[id], participle, None, false);

`

``

924

`+

self.lint_at_single_level(&[id], participle, None, false);

`

914

925

`}

`

915

926

``

916

927

`fn check_definition(&mut self, def_id: LocalDefId) {

`

`@@ -954,17 +965,16 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {

`

954

965

`if let hir::ItemKind::Impl(impl_item) = tcx.hir().item(item).kind {

`

955

966

`let mut dead_items = Vec::new();

`

956

967

`for item in impl_item.items {

`

957

``

`-

let did = item.id.owner_id.def_id;

`

958

``

`-

if !visitor.is_live_code(did) {

`

959

``

`-

dead_items.push(did)

`

``

968

`+

let def_id = item.id.owner_id.def_id;

`

``

969

`+

if !visitor.is_live_code(def_id) {

`

``

970

`+

let name = tcx.item_name(def_id.to_def_id());

`

``

971

`+

let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

`

``

972

`+

let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;

`

``

973

+

``

974

`+

dead_items.push(DeadItem { def_id, name, level })

`

960

975

`}

`

961

976

`}

`

962

``

`-

visitor.warn_multiple_dead_codes(

`

963

``

`-

&dead_items,

`

964

``

`-

"used",

`

965

``

`-

Some(item.owner_id.def_id),

`

966

``

`-

false,

`

967

``

`-

);

`

``

977

`+

visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, false);

`

968

978

`}

`

969

979

``

970

980

`if !live_symbols.contains(&item.owner_id.def_id) {

`

`@@ -988,7 +998,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {

`

988

998

`// Record to group diagnostics.

`

989

999

`let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

`

990

1000

`let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;

`

991

``

`-

dead_variants.push(DeadVariant { def_id, name: variant.name, level });

`

``

1001

`+

dead_variants.push(DeadItem { def_id, name: variant.name, level });

`

992

1002

`continue;

`

993

1003

`}

`

994

1004

``

`@@ -1013,21 +1023,16 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {

`

1013

1023

` hir_id,

`

1014

1024

`)

`

1015

1025

`.0;

`

1016

``

`-

Some(DeadVariant { def_id, name: field.name, level })

`

``

1026

`+

Some(DeadItem { def_id, name: field.name, level })

`

1017

1027

`} else {

`

1018

1028

`None

`

1019

1029

`}

`

1020

1030

`})

`

1021

1031

`.collect();

`

1022

``

`-

visitor.warn_dead_fields_and_variants(def_id, "read", dead_fields, is_positional)

`

``

1032

`+

visitor.warn_multiple(def_id, "read", dead_fields, is_positional);

`

1023

1033

`}

`

1024

1034

``

1025

``

`-

visitor.warn_dead_fields_and_variants(

`

1026

``

`-

item.owner_id.def_id,

`

1027

``

`-

"constructed",

`

1028

``

`-

dead_variants,

`

1029

``

`-

false,

`

1030

``

`-

);

`

``

1035

`+

visitor.warn_multiple(item.owner_id.def_id, "constructed", dead_variants, false);

`

1031

1036

`}

`

1032

1037

`}

`

1033

1038

``