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
``