Skip to content

Commit 65aaece

Browse files
Rollup merge of #119297 - cjgillot:issue-119267, r=petrochenkov
Pass DeadItem and lint as consistent group in dead-code. Fixes #119267
2 parents e7bd402 + 8bb74c0 commit 65aaece

File tree

3 files changed

+50
-62
lines changed

3 files changed

+50
-62
lines changed

compiler/rustc_passes/src/dead.rs

+45-62
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// is dead.
55

66
use hir::def_id::{LocalDefIdMap, LocalDefIdSet};
7-
use itertools::Itertools;
87
use rustc_data_structures::unord::UnordSet;
98
use rustc_errors::MultiSpan;
109
use rustc_hir as hir;
@@ -16,7 +15,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1615
use rustc_middle::middle::privacy::Level;
1716
use rustc_middle::query::Providers;
1817
use rustc_middle::ty::{self, TyCtxt};
19-
use rustc_session::lint;
18+
use rustc_session::lint::builtin::{DEAD_CODE, UNUSED_TUPLE_STRUCT_FIELDS};
19+
use rustc_session::lint::{self, Lint, LintId};
2020
use rustc_span::symbol::{sym, Symbol};
2121
use rustc_target::abi::FieldIdx;
2222
use std::mem;
@@ -762,7 +762,7 @@ struct DeadVisitor<'tcx> {
762762
}
763763

764764
enum ShouldWarnAboutField {
765-
Yes(bool), // positional?
765+
Yes,
766766
No,
767767
}
768768

@@ -784,7 +784,12 @@ impl<'tcx> DeadVisitor<'tcx> {
784784
{
785785
return ShouldWarnAboutField::No;
786786
}
787-
ShouldWarnAboutField::Yes(is_positional)
787+
ShouldWarnAboutField::Yes
788+
}
789+
790+
fn def_lint_level(&self, lint: &'static Lint, id: LocalDefId) -> lint::Level {
791+
let hir_id = self.tcx.local_def_id_to_hir_id(id);
792+
self.tcx.lint_level_at_node(lint, hir_id).0
788793
}
789794

790795
// # Panics
@@ -795,38 +800,33 @@ impl<'tcx> DeadVisitor<'tcx> {
795800
// since those methods group by lint level before calling this method.
796801
fn lint_at_single_level(
797802
&self,
798-
dead_codes: &[LocalDefId],
803+
dead_codes: &[&DeadItem],
799804
participle: &str,
800805
parent_item: Option<LocalDefId>,
801-
is_positional: bool,
806+
lint: &'static Lint,
802807
) {
803-
let Some(&first_id) = dead_codes.first() else {
808+
let Some(&first_item) = dead_codes.first() else {
804809
return;
805810
};
806811
let tcx = self.tcx;
807812

808-
let first_hir_id = tcx.local_def_id_to_hir_id(first_id);
809-
let first_lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, first_hir_id).0;
810-
assert!(dead_codes.iter().skip(1).all(|id| {
811-
let hir_id = tcx.local_def_id_to_hir_id(*id);
812-
let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
813-
level == first_lint_level
814-
}));
813+
let first_lint_level = first_item.level;
814+
assert!(dead_codes.iter().skip(1).all(|item| item.level == first_lint_level));
815815

816-
let names: Vec<_> =
817-
dead_codes.iter().map(|&def_id| tcx.item_name(def_id.to_def_id())).collect();
816+
let names: Vec<_> = dead_codes.iter().map(|item| item.name).collect();
818817
let spans: Vec<_> = dead_codes
819818
.iter()
820-
.map(|&def_id| match tcx.def_ident_span(def_id) {
821-
Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()),
822-
None => tcx.def_span(def_id),
819+
.map(|item| match tcx.def_ident_span(item.def_id) {
820+
Some(s) => s.with_ctxt(tcx.def_span(item.def_id).ctxt()),
821+
None => tcx.def_span(item.def_id),
823822
})
824823
.collect();
825824

826-
let descr = tcx.def_descr(first_id.to_def_id());
825+
let descr = tcx.def_descr(first_item.def_id.to_def_id());
827826
// `impl` blocks are "batched" and (unlike other batching) might
828827
// contain different kinds of associated items.
829-
let descr = if dead_codes.iter().any(|did| tcx.def_descr(did.to_def_id()) != descr) {
828+
let descr = if dead_codes.iter().any(|item| tcx.def_descr(item.def_id.to_def_id()) != descr)
829+
{
830830
"associated item"
831831
} else {
832832
descr
@@ -835,12 +835,6 @@ impl<'tcx> DeadVisitor<'tcx> {
835835
let multiple = num > 6;
836836
let name_list = names.into();
837837

838-
let lint = if is_positional {
839-
lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
840-
} else {
841-
lint::builtin::DEAD_CODE
842-
};
843-
844838
let parent_info = if let Some(parent_item) = parent_item {
845839
let parent_descr = tcx.def_descr(parent_item.to_def_id());
846840
let span = if let DefKind::Impl { .. } = tcx.def_kind(parent_item) {
@@ -853,7 +847,7 @@ impl<'tcx> DeadVisitor<'tcx> {
853847
None
854848
};
855849

856-
let encl_def_id = parent_item.unwrap_or(first_id);
850+
let encl_def_id = parent_item.unwrap_or(first_item.def_id);
857851
let ignored_derived_impls =
858852
if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
859853
let trait_list = ign_traits
@@ -870,7 +864,7 @@ impl<'tcx> DeadVisitor<'tcx> {
870864
None
871865
};
872866

873-
let diag = if is_positional {
867+
let diag = if LintId::of(lint) == LintId::of(UNUSED_TUPLE_STRUCT_FIELDS) {
874868
MultipleDeadCodes::UnusedTupleStructFields {
875869
multiple,
876870
num,
@@ -893,15 +887,16 @@ impl<'tcx> DeadVisitor<'tcx> {
893887
}
894888
};
895889

896-
self.tcx.emit_spanned_lint(lint, first_hir_id, MultiSpan::from_spans(spans), diag);
890+
let hir_id = tcx.local_def_id_to_hir_id(first_item.def_id);
891+
self.tcx.emit_spanned_lint(lint, hir_id, MultiSpan::from_spans(spans), diag);
897892
}
898893

899894
fn warn_multiple(
900895
&self,
901896
def_id: LocalDefId,
902897
participle: &str,
903898
dead_codes: Vec<DeadItem>,
904-
is_positional: bool,
899+
lint: &'static Lint,
905900
) {
906901
let mut dead_codes = dead_codes
907902
.iter()
@@ -911,18 +906,18 @@ impl<'tcx> DeadVisitor<'tcx> {
911906
return;
912907
}
913908
dead_codes.sort_by_key(|v| v.level);
914-
for (_, group) in &dead_codes.into_iter().group_by(|v| v.level) {
915-
self.lint_at_single_level(
916-
&group.map(|v| v.def_id).collect::<Vec<_>>(),
917-
participle,
918-
Some(def_id),
919-
is_positional,
920-
);
909+
for group in dead_codes[..].group_by(|a, b| a.level == b.level) {
910+
self.lint_at_single_level(&group, participle, Some(def_id), lint);
921911
}
922912
}
923913

924914
fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) {
925-
self.lint_at_single_level(&[id], participle, None, false);
915+
let item = DeadItem {
916+
def_id: id,
917+
name: self.tcx.item_name(id.to_def_id()),
918+
level: self.def_lint_level(DEAD_CODE, id),
919+
};
920+
self.lint_at_single_level(&[&item], participle, None, DEAD_CODE);
926921
}
927922

928923
fn check_definition(&mut self, def_id: LocalDefId) {
@@ -969,13 +964,12 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
969964
let def_id = item.id.owner_id.def_id;
970965
if !visitor.is_live_code(def_id) {
971966
let name = tcx.item_name(def_id.to_def_id());
972-
let hir_id = tcx.local_def_id_to_hir_id(def_id);
973-
let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
967+
let level = visitor.def_lint_level(DEAD_CODE, def_id);
974968

975969
dead_items.push(DeadItem { def_id, name, level })
976970
}
977971
}
978-
visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, false);
972+
visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, DEAD_CODE);
979973
}
980974

981975
if !live_symbols.contains(&item.owner_id.def_id) {
@@ -997,43 +991,32 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
997991
let def_id = variant.def_id.expect_local();
998992
if !live_symbols.contains(&def_id) {
999993
// Record to group diagnostics.
1000-
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1001-
let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
994+
let level = visitor.def_lint_level(DEAD_CODE, def_id);
1002995
dead_variants.push(DeadItem { def_id, name: variant.name, level });
1003996
continue;
1004997
}
1005998

1006-
let mut is_positional = false;
999+
let is_positional = variant.fields.raw.first().map_or(false, |field| {
1000+
field.name.as_str().starts_with(|c: char| c.is_ascii_digit())
1001+
});
1002+
let lint = if is_positional { UNUSED_TUPLE_STRUCT_FIELDS } else { DEAD_CODE };
10071003
let dead_fields = variant
10081004
.fields
10091005
.iter()
10101006
.filter_map(|field| {
10111007
let def_id = field.did.expect_local();
1012-
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1013-
if let ShouldWarnAboutField::Yes(is_pos) =
1014-
visitor.should_warn_about_field(field)
1015-
{
1016-
let level = tcx
1017-
.lint_level_at_node(
1018-
if is_pos {
1019-
is_positional = true;
1020-
lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
1021-
} else {
1022-
lint::builtin::DEAD_CODE
1023-
},
1024-
hir_id,
1025-
)
1026-
.0;
1008+
if let ShouldWarnAboutField::Yes = visitor.should_warn_about_field(field) {
1009+
let level = visitor.def_lint_level(lint, def_id);
10271010
Some(DeadItem { def_id, name: field.name, level })
10281011
} else {
10291012
None
10301013
}
10311014
})
10321015
.collect();
1033-
visitor.warn_multiple(def_id, "read", dead_fields, is_positional);
1016+
visitor.warn_multiple(def_id, "read", dead_fields, lint);
10341017
}
10351018

1036-
visitor.warn_multiple(item.owner_id.def_id, "constructed", dead_variants, false);
1019+
visitor.warn_multiple(item.owner_id.def_id, "constructed", dead_variants, DEAD_CODE);
10371020
}
10381021
}
10391022

compiler/rustc_passes/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![feature(let_chains)]
1313
#![feature(map_try_insert)]
1414
#![feature(min_specialization)]
15+
#![feature(slice_group_by)]
1516
#![feature(try_blocks)]
1617
#![recursion_limit = "256"]
1718
#![deny(rustc::untranslatable_diagnostic)]

tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ struct Bar {
1515
_h: usize,
1616
}
1717

18+
// Issue 119267: this should not ICE.
19+
#[derive(Debug)]
20+
struct Foo(usize, #[allow(unused)] usize);
21+
1822
fn main() {
1923
Bar {
2024
a: 1,

0 commit comments

Comments
 (0)