Skip to content

Commit

Permalink
Auto merge of rust-lang#118297 - shepmaster:warn-dead-tuple-fields, r…
Browse files Browse the repository at this point in the history
…=WaffleLapkin

Merge `unused_tuple_struct_fields` into `dead_code`

This implicitly upgrades the lint from `allow` to `warn` and places it into the `unused` lint group.

[Discussion on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Moving.20.60unused_tuple_struct_fields.60.20from.20allow.20to.20warn)
  • Loading branch information
bors committed Jan 5, 2024
2 parents a59a980 + 26194a3 commit 5113ed2
Show file tree
Hide file tree
Showing 227 changed files with 406 additions and 412 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ fn register_builtins(store: &mut LintStore) {
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
Expand Down
36 changes: 7 additions & 29 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ declare_lint_pass! {
UNUSED_MACROS,
UNUSED_MUT,
UNUSED_QUALIFICATIONS,
UNUSED_TUPLE_STRUCT_FIELDS,
UNUSED_UNSAFE,
UNUSED_VARIABLES,
USELESS_DEPRECATED,
Expand Down Expand Up @@ -697,8 +696,13 @@ declare_lint! {
/// 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"
Expand Down Expand Up @@ -732,32 +736,6 @@ declare_lint! {
"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.
///
Expand Down
58 changes: 35 additions & 23 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
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;
Expand Down Expand Up @@ -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()) {
Expand All @@ -787,9 +793,9 @@ impl<'tcx> DeadVisitor<'tcx> {
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
Expand All @@ -803,7 +809,7 @@ impl<'tcx> DeadVisitor<'tcx> {
dead_codes: &[&DeadItem],
participle: &str,
parent_item: Option<LocalDefId>,
lint: &'static Lint,
report_on: ReportOn,
) {
let Some(&first_item) = dead_codes.first() else {
return;
Expand Down Expand Up @@ -864,8 +870,8 @@ impl<'tcx> DeadVisitor<'tcx> {
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,
Expand All @@ -874,29 +880,29 @@ impl<'tcx> DeadVisitor<'tcx> {
change_fields_suggestion: ChangeFieldsToBeOfUnitType { num, spans: spans.clone() },
parent_info,
ignored_derived_impls,
}
} else {
MultipleDeadCodes::DeadCodes {
},

ReportOn::NamedField => MultipleDeadCodes::DeadCodes {
multiple,
num,
descr,
participle,
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(
&self,
def_id: LocalDefId,
participle: &str,
dead_codes: Vec<DeadItem>,
lint: &'static Lint,
report_on: ReportOn,
) {
let mut dead_codes = dead_codes
.iter()
Expand All @@ -907,17 +913,17 @@ impl<'tcx> DeadVisitor<'tcx> {
}
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);
}
}

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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -991,32 +997,38 @@ 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;
}

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,
);
}
}

Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
//! Creating a recursive data structure:
//!
//! ```
//! ##[allow(dead_code)]
//! #[derive(Debug)]
//! enum List<T> {
//! Cons(T, Box<List<T>>),
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/boxed/thin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ struct WithHeader<H>(NonNull<u8>, PhantomData<H>);
/// An opaque representation of `WithHeader<H>` to avoid the
/// projection invariance of `<T as Pointee>::Metadata`.
#[repr(transparent)]
#[allow(unused_tuple_struct_fields)] // Field only used through `WithHeader` type above.
#[allow(dead_code)] // Field only used through `WithHeader` type above.
struct WithOpaqueHeader(NonNull<u8>);

impl WithOpaqueHeader {
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/collections/btree/set/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ fn test_extend_ref() {
#[test]
fn test_recovery() {
#[derive(Debug)]
struct Foo(&'static str, i32);
struct Foo(&'static str, #[allow(dead_code)] i32);

impl PartialEq for Foo {
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/collections/vec_deque/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ fn test_clone_from() {
fn test_vec_deque_truncate_drop() {
static mut DROPS: u32 = 0;
#[derive(Clone)]
struct Elem(i32);
struct Elem(#[allow(dead_code)] i32);
impl Drop for Elem {
fn drop(&mut self) {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/tests/autotraits.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
fn require_sync<T: Sync>(_: T) {}
fn require_send_sync<T: Send + Sync>(_: T) {}

struct NotSend(*const ());
struct NotSend(#[allow(dead_code)] *const ());
unsafe impl Sync for NotSend {}

#[test]
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ fn test_cmp() {
#[test]
fn test_vec_truncate_drop() {
static mut DROPS: u32 = 0;
struct Elem(i32);
struct Elem(#[allow(dead_code)] i32);
impl Drop for Elem {
fn drop(&mut self) {
unsafe {
Expand Down Expand Up @@ -1089,7 +1089,7 @@ fn test_into_iter_advance_by() {

#[test]
fn test_into_iter_drop_allocator() {
struct ReferenceCountedAllocator<'a>(DropCounter<'a>);
struct ReferenceCountedAllocator<'a>(#[allow(dead_code)] DropCounter<'a>);

unsafe impl Allocator for ReferenceCountedAllocator<'_> {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
Expand Down Expand Up @@ -2407,7 +2407,7 @@ fn test_vec_dedup_multiple_ident() {
#[test]
fn test_vec_dedup_partialeq() {
#[derive(Debug)]
struct Foo(i32, i32);
struct Foo(i32, #[allow(dead_code)] i32);

impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions library/core/benches/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn binary_search_l3_worst_case(b: &mut Bencher) {
}

#[derive(Clone)]
struct Rgb(u8, u8, u8);
struct Rgb(#[allow(dead_code)] u8, #[allow(dead_code)] u8, #[allow(dead_code)] u8);

impl Rgb {
fn gen(i: usize) -> Self {
Expand Down Expand Up @@ -154,7 +154,7 @@ swap_with_slice!(swap_with_slice_5x_usize_3000, 3000, |i| [i; 5]);
#[bench]
fn fill_byte_sized(b: &mut Bencher) {
#[derive(Copy, Clone)]
struct NewType(u8);
struct NewType(#[allow(dead_code)] u8);

let mut ary = [NewType(0); 1024];

Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn any_unsized() {
fn distinct_type_names() {
// https://github.com/rust-lang/rust/issues/84666

struct Velocity(f32, f32);
struct Velocity(#[allow(dead_code)] f32, #[allow(dead_code)] f32);

fn type_name_of_val<T>(_: T) -> &'static str {
type_name::<T>()
Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ fn array_default_impl_avoids_leaks_on_panic() {
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug)]
struct Bomb(usize);
struct Bomb(#[allow(dead_code)] usize);

impl Default for Bomb {
fn default() -> Bomb {
Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ fn ptr_bitops() {
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
fn ptr_bitops_tagging() {
#[repr(align(16))]
struct Tagme(u128);
struct Tagme(#[allow(dead_code)] u128);

let tagme = Tagme(1000);
let ptr = &tagme as *const Tagme as *mut Tagme;
Expand Down
6 changes: 3 additions & 3 deletions library/core/tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::intrinsics::assume;
#[test]
fn test_typeid_sized_types() {
struct X;
struct Y(u32);
struct Y(#[allow(dead_code)] u32);

assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
Expand All @@ -14,8 +14,8 @@ fn test_typeid_sized_types() {
#[test]
fn test_typeid_unsized_types() {
trait Z {}
struct X(str);
struct Y(dyn Z + 'static);
struct X(#[allow(dead_code)] str);
struct Y(#[allow(dead_code)] dyn Z + 'static);

assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
Expand Down
Loading

0 comments on commit 5113ed2

Please sign in to comment.