diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 93904fb5c56..76c630fc456 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -328,6 +328,7 @@ macro_rules! add_lint_group { store.register_renamed("disjoint_capture_migration", "rust_2021_incompatible_closure_captures"); store.register_renamed("or_patterns_back_compat", "rust_2021_incompatible_or_patterns"); store.register_renamed("non_fmt_panic", "non_fmt_panics"); + store.register_renamed("unused_tuple_struct_fields", "dead_code"); // These were moved to tool lints, but rustc still sees them when compiling normally, before // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 399e6968fae..9158579bea3 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -125,7 +125,6 @@ UNUSED_MACROS, UNUSED_MUT, UNUSED_QUALIFICATIONS, - UNUSED_TUPLE_STRUCT_FIELDS, UNUSED_UNSAFE, UNUSED_VARIABLES, USELESS_DEPRECATED, @@ -697,8 +696,13 @@ /// Dead code may signal a mistake or unfinished code. To silence the /// warning for individual items, prefix the name with an underscore such /// as `_foo`. If it was intended to expose the item outside of the crate, - /// consider adding a visibility modifier like `pub`. Otherwise consider - /// removing the unused code. + /// consider adding a visibility modifier like `pub`. + /// + /// To preserve the numbering of tuple structs with unused fields, + /// change the unused fields to have unit type or use + /// `PhantomData`. + /// + /// Otherwise consider removing the unused code. pub DEAD_CODE, Warn, "detect unused, unexported items" @@ -732,32 +736,6 @@ "detects attributes that were not used by the compiler" } -declare_lint! { - /// The `unused_tuple_struct_fields` lint detects fields of tuple structs - /// that are never read. - /// - /// ### Example - /// - /// ```rust - /// #[warn(unused_tuple_struct_fields)] - /// struct S(i32, i32, i32); - /// let s = S(1, 2, 3); - /// let _ = (s.0, s.2); - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Tuple struct fields that are never read anywhere may indicate a - /// mistake or unfinished code. To silence this warning, consider - /// removing the unused field(s) or, to preserve the numbering of the - /// remaining fields, change the unused field(s) to have unit type. - pub UNUSED_TUPLE_STRUCT_FIELDS, - Allow, - "detects tuple struct fields that are never read" -} - declare_lint! { /// The `unreachable_code` lint detects unreachable code paths. /// diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 22aac1e775e..ac2ca23ad41 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -15,8 +15,8 @@ use rustc_middle::middle::privacy::Level; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::lint::builtin::{DEAD_CODE, UNUSED_TUPLE_STRUCT_FIELDS}; -use rustc_session::lint::{self, Lint, LintId}; +use rustc_session::lint; +use rustc_session::lint::builtin::DEAD_CODE; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::FieldIdx; use std::mem; @@ -766,6 +766,12 @@ enum ShouldWarnAboutField { No, } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum ReportOn { + TupleField, + NamedField, +} + impl<'tcx> DeadVisitor<'tcx> { fn should_warn_about_field(&mut self, field: &ty::FieldDef) -> ShouldWarnAboutField { if self.live_symbols.contains(&field.did.expect_local()) { @@ -787,9 +793,9 @@ fn should_warn_about_field(&mut self, field: &ty::FieldDef) -> ShouldWarnAboutFi ShouldWarnAboutField::Yes } - fn def_lint_level(&self, lint: &'static Lint, id: LocalDefId) -> lint::Level { + fn def_lint_level(&self, id: LocalDefId) -> lint::Level { let hir_id = self.tcx.local_def_id_to_hir_id(id); - self.tcx.lint_level_at_node(lint, hir_id).0 + self.tcx.lint_level_at_node(DEAD_CODE, hir_id).0 } // # Panics @@ -803,7 +809,7 @@ fn lint_at_single_level( dead_codes: &[&DeadItem], participle: &str, parent_item: Option, - lint: &'static Lint, + report_on: ReportOn, ) { let Some(&first_item) = dead_codes.first() else { return; @@ -864,8 +870,8 @@ fn lint_at_single_level( None }; - let diag = if LintId::of(lint) == LintId::of(UNUSED_TUPLE_STRUCT_FIELDS) { - MultipleDeadCodes::UnusedTupleStructFields { + let diag = match report_on { + ReportOn::TupleField => MultipleDeadCodes::UnusedTupleStructFields { multiple, num, descr, @@ -874,9 +880,9 @@ fn lint_at_single_level( change_fields_suggestion: ChangeFieldsToBeOfUnitType { num, spans: spans.clone() }, parent_info, ignored_derived_impls, - } - } else { - MultipleDeadCodes::DeadCodes { + }, + + ReportOn::NamedField => MultipleDeadCodes::DeadCodes { multiple, num, descr, @@ -884,11 +890,11 @@ fn lint_at_single_level( name_list, parent_info, ignored_derived_impls, - } + }, }; let hir_id = tcx.local_def_id_to_hir_id(first_item.def_id); - self.tcx.emit_spanned_lint(lint, hir_id, MultiSpan::from_spans(spans), diag); + self.tcx.emit_spanned_lint(DEAD_CODE, hir_id, MultiSpan::from_spans(spans), diag); } fn warn_multiple( @@ -896,7 +902,7 @@ fn warn_multiple( def_id: LocalDefId, participle: &str, dead_codes: Vec, - lint: &'static Lint, + report_on: ReportOn, ) { let mut dead_codes = dead_codes .iter() @@ -907,7 +913,7 @@ fn warn_multiple( } dead_codes.sort_by_key(|v| v.level); for group in dead_codes[..].group_by(|a, b| a.level == b.level) { - self.lint_at_single_level(&group, participle, Some(def_id), lint); + self.lint_at_single_level(&group, participle, Some(def_id), report_on); } } @@ -915,9 +921,9 @@ fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) { let item = DeadItem { def_id: id, name: self.tcx.item_name(id.to_def_id()), - level: self.def_lint_level(DEAD_CODE, id), + level: self.def_lint_level(id), }; - self.lint_at_single_level(&[&item], participle, None, DEAD_CODE); + self.lint_at_single_level(&[&item], participle, None, ReportOn::NamedField); } fn check_definition(&mut self, def_id: LocalDefId) { @@ -964,12 +970,12 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { let def_id = item.id.owner_id.def_id; if !visitor.is_live_code(def_id) { let name = tcx.item_name(def_id.to_def_id()); - let level = visitor.def_lint_level(DEAD_CODE, def_id); + let level = visitor.def_lint_level(def_id); dead_items.push(DeadItem { def_id, name, level }) } } - visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, DEAD_CODE); + visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, ReportOn::NamedField); } if !live_symbols.contains(&item.owner_id.def_id) { @@ -991,7 +997,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { let def_id = variant.def_id.expect_local(); if !live_symbols.contains(&def_id) { // Record to group diagnostics. - let level = visitor.def_lint_level(DEAD_CODE, def_id); + let level = visitor.def_lint_level(def_id); dead_variants.push(DeadItem { def_id, name: variant.name, level }); continue; } @@ -999,24 +1005,30 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { let is_positional = variant.fields.raw.first().map_or(false, |field| { field.name.as_str().starts_with(|c: char| c.is_ascii_digit()) }); - let lint = if is_positional { UNUSED_TUPLE_STRUCT_FIELDS } else { DEAD_CODE }; + let report_on = + if is_positional { ReportOn::TupleField } else { ReportOn::NamedField }; let dead_fields = variant .fields .iter() .filter_map(|field| { let def_id = field.did.expect_local(); if let ShouldWarnAboutField::Yes = visitor.should_warn_about_field(field) { - let level = visitor.def_lint_level(lint, def_id); + let level = visitor.def_lint_level(def_id); Some(DeadItem { def_id, name: field.name, level }) } else { None } }) .collect(); - visitor.warn_multiple(def_id, "read", dead_fields, lint); + visitor.warn_multiple(def_id, "read", dead_fields, report_on); } - visitor.warn_multiple(item.owner_id.def_id, "constructed", dead_variants, DEAD_CODE); + visitor.warn_multiple( + item.owner_id.def_id, + "constructed", + dead_variants, + ReportOn::NamedField, + ); } }