Skip to content

Commit ee9a896

Browse files
committed
Warn about dead tuple struct fields
1 parent ec4bcaa commit ee9a896

File tree

207 files changed

+422
-284
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

207 files changed

+422
-284
lines changed

compiler/rustc_apfloat/src/ppc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub type DoubleDouble = DoubleFloat<ieee::Double>;
3030
// FIXME: Implement all operations in DoubleDouble, and delete these
3131
// semantics.
3232
// FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
33-
pub struct FallbackS<F>(F);
33+
pub struct FallbackS<F>(#[allow(dead_code)] F);
3434
type Fallback<F> = ieee::IeeeFloat<FallbackS<F>>;
3535
impl<F: Float> ieee::Semantics for FallbackS<F> {
3636
// Forbid any conversion to/from bits.
@@ -45,7 +45,7 @@ impl<F: Float> ieee::Semantics for FallbackS<F> {
4545
// truncate the mantissa. The result of that second conversion
4646
// may be inexact, but should never underflow.
4747
// FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
48-
pub struct FallbackExtendedS<F>(F);
48+
pub struct FallbackExtendedS<F>(#[allow(dead_code)] F);
4949
type FallbackExtended<F> = ieee::IeeeFloat<FallbackExtendedS<F>>;
5050
impl<F: Float> ieee::Semantics for FallbackExtendedS<F> {
5151
// Forbid any conversion to/from bits.

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -2377,9 +2377,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
23772377
#[derive(Debug)]
23782378
enum SubOrigin<'hir> {
23792379
GAT(&'hir hir::Generics<'hir>),
2380-
Impl(&'hir hir::Generics<'hir>),
2381-
Trait(&'hir hir::Generics<'hir>),
2382-
Fn(&'hir hir::Generics<'hir>),
2380+
Impl,
2381+
Trait,
2382+
Fn,
23832383
Unknown,
23842384
}
23852385
let sub_origin = 'origin: {
@@ -2397,31 +2397,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
23972397
}) => SubOrigin::GAT(generics),
23982398
Node::ImplItem(hir::ImplItem {
23992399
kind: hir::ImplItemKind::Fn(..),
2400-
generics,
24012400
..
2402-
}) => SubOrigin::Fn(generics),
2401+
}) => SubOrigin::Fn,
24032402
Node::TraitItem(hir::TraitItem {
24042403
kind: hir::TraitItemKind::Type(..),
24052404
generics,
24062405
..
24072406
}) => SubOrigin::GAT(generics),
24082407
Node::TraitItem(hir::TraitItem {
24092408
kind: hir::TraitItemKind::Fn(..),
2410-
generics,
24112409
..
2412-
}) => SubOrigin::Fn(generics),
2410+
}) => SubOrigin::Fn,
24132411
Node::Item(hir::Item {
2414-
kind: hir::ItemKind::Trait(_, _, generics, _, _),
2412+
kind: hir::ItemKind::Trait(..),
24152413
..
2416-
}) => SubOrigin::Trait(generics),
2414+
}) => SubOrigin::Trait,
24172415
Node::Item(hir::Item {
2418-
kind: hir::ItemKind::Impl(hir::Impl { generics, .. }),
2416+
kind: hir::ItemKind::Impl(hir::Impl { .. }),
24192417
..
2420-
}) => SubOrigin::Impl(generics),
2418+
}) => SubOrigin::Impl,
24212419
Node::Item(hir::Item {
2422-
kind: hir::ItemKind::Fn(_, generics, _),
2423-
..
2424-
}) => SubOrigin::Fn(generics),
2420+
kind: hir::ItemKind::Fn(..), ..
2421+
}) => SubOrigin::Fn,
24252422
_ => continue,
24262423
};
24272424
}

compiler/rustc_passes/src/check_attr.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub(crate) fn target_from_impl_item<'tcx>(
5151
#[derive(Clone, Copy)]
5252
enum ItemLike<'tcx> {
5353
Item(&'tcx Item<'tcx>),
54-
ForeignItem(&'tcx ForeignItem<'tcx>),
54+
ForeignItem,
5555
}
5656

5757
struct CheckAttrVisitor<'tcx> {
@@ -1889,12 +1889,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
18891889

18901890
fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) {
18911891
let target = Target::from_foreign_item(f_item);
1892-
self.check_attributes(
1893-
f_item.hir_id(),
1894-
&f_item.span,
1895-
target,
1896-
Some(ItemLike::ForeignItem(f_item)),
1897-
);
1892+
self.check_attributes(f_item.hir_id(), &f_item.span, target, Some(ItemLike::ForeignItem));
18981893
intravisit::walk_foreign_item(self, f_item)
18991894
}
19001895

compiler/rustc_passes/src/dead.rs

+64-5
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ struct MarkSymbolVisitor<'tcx> {
4141
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
4242
live_symbols: FxHashSet<LocalDefId>,
4343
repr_has_repr_c: bool,
44+
repr_has_repr_simd: bool,
4445
in_pat: bool,
4546
inherited_pub_visibility: bool,
4647
pub_visibility: bool,
48+
allow_dead_field: bool,
4749
ignore_variant_stack: Vec<DefId>,
4850
// maps from tuple struct constructors to tuple struct items
4951
struct_constructors: FxHashMap<LocalDefId, LocalDefId>,
@@ -221,6 +223,32 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
221223
}
222224
}
223225

226+
fn handle_tuple_field_pattern_match(
227+
&mut self,
228+
lhs: &hir::Pat<'_>,
229+
res: Res,
230+
pats: &[hir::Pat<'_>],
231+
dotdot: Option<usize>,
232+
) {
233+
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
234+
ty::Adt(adt, _) => adt.variant_of_res(res),
235+
_ => span_bug!(lhs.span, "non-ADT in tuple struct pattern"),
236+
};
237+
let first_n = pats.iter().enumerate().take(dotdot.unwrap_or(pats.len()));
238+
let missing = variant.fields.len() - pats.len();
239+
let last_n = pats
240+
.iter()
241+
.enumerate()
242+
.skip(dotdot.unwrap_or(pats.len()))
243+
.map(|(idx, pat)| (idx + missing, pat));
244+
for (idx, pat) in first_n.chain(last_n) {
245+
if let PatKind::Wild = pat.kind {
246+
continue;
247+
}
248+
self.insert_def_id(variant.fields[idx].did);
249+
}
250+
}
251+
224252
fn mark_live_symbols(&mut self) {
225253
let mut scanned = FxHashSet::default();
226254
while let Some(id) = self.worklist.pop() {
@@ -269,19 +297,38 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
269297
}
270298

271299
let had_repr_c = self.repr_has_repr_c;
300+
let had_repr_simd = self.repr_has_repr_simd;
272301
let had_inherited_pub_visibility = self.inherited_pub_visibility;
273302
let had_pub_visibility = self.pub_visibility;
303+
let had_allow_dead_field = self.allow_dead_field;
274304
self.repr_has_repr_c = false;
305+
self.repr_has_repr_simd = false;
275306
self.inherited_pub_visibility = false;
276307
self.pub_visibility = false;
308+
self.allow_dead_field = false;
277309
match node {
278310
Node::Item(item) => {
279311
self.pub_visibility = item.vis.node.is_pub();
280312

281-
match item.kind {
282-
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
313+
match &item.kind {
314+
hir::ItemKind::Struct(vd, ..) | hir::ItemKind::Union(vd, ..) => {
283315
let def = self.tcx.adt_def(item.def_id);
284316
self.repr_has_repr_c = def.repr.c();
317+
self.repr_has_repr_simd = def.repr.simd();
318+
319+
// A single non-public field of unit type in a public tuple struct
320+
// can be used to make the tuple struct constructor private. This
321+
// is allowed and shouldn't yield a "field is never read" warning.
322+
if let hir::VariantData::Tuple([field_def], _) = vd {
323+
match field_def.vis.node {
324+
hir::VisibilityKind::Public => {}
325+
_ => {
326+
if let hir::TyKind::Tup([]) = field_def.ty.kind {
327+
self.allow_dead_field = true;
328+
}
329+
}
330+
}
331+
}
285332

286333
intravisit::walk_item(self, &item);
287334
}
@@ -307,8 +354,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
307354
}
308355
_ => {}
309356
}
357+
self.allow_dead_field = had_allow_dead_field;
310358
self.pub_visibility = had_pub_visibility;
311359
self.inherited_pub_visibility = had_inherited_pub_visibility;
360+
self.repr_has_repr_simd = had_repr_simd;
312361
self.repr_has_repr_c = had_repr_c;
313362
}
314363

@@ -346,10 +395,15 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
346395
_: rustc_span::Span,
347396
) {
348397
let has_repr_c = self.repr_has_repr_c;
398+
let has_repr_simd = self.repr_has_repr_simd;
349399
let inherited_pub_visibility = self.inherited_pub_visibility;
350400
let pub_visibility = self.pub_visibility;
401+
let allow_dead_field = self.allow_dead_field;
351402
let live_fields = def.fields().iter().filter(|f| {
352-
has_repr_c || (pub_visibility && (inherited_pub_visibility || f.vis.node.is_pub()))
403+
has_repr_c
404+
|| (pub_visibility && (inherited_pub_visibility || f.vis.node.is_pub()))
405+
|| (f.is_positional() && has_repr_simd)
406+
|| allow_dead_field
353407
});
354408
let hir = self.tcx.hir();
355409
self.live_symbols.extend(live_fields.map(|f| hir.local_def_id(f.hir_id)));
@@ -403,6 +457,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
403457
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
404458
self.handle_res(res);
405459
}
460+
PatKind::TupleStruct(ref qpath, ref fields, dotdot) => {
461+
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
462+
self.handle_tuple_field_pattern_match(pat, res, fields, dotdot);
463+
}
406464
_ => (),
407465
}
408466

@@ -585,9 +643,11 @@ fn find_live<'tcx>(
585643
maybe_typeck_results: None,
586644
live_symbols: Default::default(),
587645
repr_has_repr_c: false,
646+
repr_has_repr_simd: false,
588647
in_pat: false,
589648
inherited_pub_visibility: false,
590649
pub_visibility: false,
650+
allow_dead_field: false,
591651
ignore_variant_stack: vec![],
592652
struct_constructors,
593653
};
@@ -618,8 +678,7 @@ impl<'tcx> DeadVisitor<'tcx> {
618678
fn should_warn_about_field(&mut self, field: &hir::FieldDef<'_>) -> bool {
619679
let def_id = self.tcx.hir().local_def_id(field.hir_id);
620680
let field_type = self.tcx.type_of(def_id);
621-
!field.is_positional()
622-
&& !self.symbol_is_live(def_id)
681+
!self.symbol_is_live(def_id)
623682
&& !field_type.is_phantom_data()
624683
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id)
625684
}

compiler/rustc_resolve/src/build_reduced_graph.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
515515
let crate_root = self.r.resolve_crate_root(source.ident);
516516
let crate_name = match crate_root.kind {
517517
ModuleKind::Def(.., name) => name,
518-
ModuleKind::Block(..) => unreachable!(),
518+
ModuleKind::Block => unreachable!(),
519519
};
520520
// HACK(eddyb) unclear how good this is, but keeping `$crate`
521521
// in `source` breaks `src/test/ui/imports/import-crate-var.rs`,
@@ -927,7 +927,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
927927
if self.block_needs_anonymous_module(block) {
928928
let module = self.r.new_module(
929929
Some(parent),
930-
ModuleKind::Block(block.id),
930+
ModuleKind::Block,
931931
expansion.to_expn_id(),
932932
block.span,
933933
parent.no_implicit_prelude,

compiler/rustc_resolve/src/late/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
13071307
// Items from this module
13081308
self.r.add_module_candidates(module, &mut names, &filter_fn);
13091309

1310-
if let ModuleKind::Block(..) = module.kind {
1310+
if let ModuleKind::Block = module.kind {
13111311
// We can see through blocks
13121312
} else {
13131313
// Items from the prelude

compiler/rustc_resolve/src/lib.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ enum ModuleKind {
465465
/// f(); // Resolves to (1)
466466
/// }
467467
/// ```
468-
Block(NodeId),
468+
Block,
469469
/// Any module with a name.
470470
///
471471
/// This could be:
@@ -482,7 +482,7 @@ impl ModuleKind {
482482
/// Get name of the module.
483483
pub fn name(&self) -> Option<Symbol> {
484484
match self {
485-
ModuleKind::Block(..) => None,
485+
ModuleKind::Block => None,
486486
ModuleKind::Def(.., name) => Some(*name),
487487
}
488488
}
@@ -558,7 +558,7 @@ impl<'a> ModuleData<'a> {
558558
) -> Self {
559559
let is_foreign = match kind {
560560
ModuleKind::Def(_, def_id, _) => !def_id.is_local(),
561-
ModuleKind::Block(_) => false,
561+
ModuleKind::Block => false,
562562
};
563563
ModuleData {
564564
parent,
@@ -1987,7 +1987,7 @@ impl<'a> Resolver<'a> {
19871987
};
19881988

19891989
match module.kind {
1990-
ModuleKind::Block(..) => {} // We can see through blocks
1990+
ModuleKind::Block => {} // We can see through blocks
19911991
_ => break,
19921992
}
19931993

@@ -2026,7 +2026,7 @@ impl<'a> Resolver<'a> {
20262026
return Some((self.expn_def_scope(ctxt.remove_mark()), None));
20272027
}
20282028

2029-
if let ModuleKind::Block(..) = module.kind {
2029+
if let ModuleKind::Block = module.kind {
20302030
return Some((module.parent.unwrap().nearest_item_scope(), None));
20312031
}
20322032

@@ -3029,7 +3029,7 @@ impl<'a> Resolver<'a> {
30293029

30303030
let container = match parent.kind {
30313031
ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()),
3032-
ModuleKind::Block(..) => "block",
3032+
ModuleKind::Block => "block",
30333033
};
30343034

30353035
let old_noun = match old_binding.is_import() {

compiler/rustc_serialize/tests/json.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,8 @@ struct DecodeStruct {
627627
}
628628
#[derive(Decodable)]
629629
enum DecodeEnum {
630-
A(f64),
631-
B(string::String),
630+
A(#[allow(dead_code)] f64),
631+
B(#[allow(dead_code)] string::String),
632632
}
633633
fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected: DecoderError) {
634634
let res: DecodeResult<T> = match from_str(to_parse) {

library/alloc/src/boxed.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
//!
2626
//! ```
2727
//! #[derive(Debug)]
28+
//! # #[allow(dead_code)]
2829
//! enum List<T> {
2930
//! Cons(T, Box<List<T>>),
3031
//! Nil,

library/alloc/src/collections/btree/set/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ fn test_extend_ref() {
469469
#[test]
470470
fn test_recovery() {
471471
#[derive(Debug)]
472-
struct Foo(&'static str, i32);
472+
struct Foo(&'static str, #[allow(dead_code)] i32);
473473

474474
impl PartialEq for Foo {
475475
fn eq(&self, other: &Self) -> bool {

library/alloc/src/collections/vec_deque/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ fn test_clone_from() {
630630
fn test_vec_deque_truncate_drop() {
631631
static mut DROPS: u32 = 0;
632632
#[derive(Clone)]
633-
struct Elem(i32);
633+
struct Elem(#[allow(dead_code)] i32);
634634
impl Drop for Elem {
635635
fn drop(&mut self) {
636636
unsafe {

library/alloc/tests/vec.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ fn test_cmp() {
492492
#[test]
493493
fn test_vec_truncate_drop() {
494494
static mut DROPS: u32 = 0;
495-
struct Elem(i32);
495+
struct Elem(#[allow(dead_code)] i32);
496496
impl Drop for Elem {
497497
fn drop(&mut self) {
498498
unsafe {
@@ -1077,7 +1077,7 @@ fn test_from_iter_specialization_panic_during_drop_leaks() {
10771077

10781078
#[derive(Debug)]
10791079
enum Droppable {
1080-
DroppedTwice(Box<i32>),
1080+
DroppedTwice(#[allow(dead_code)] Box<i32>),
10811081
PanicOnDrop,
10821082
}
10831083

@@ -2251,7 +2251,7 @@ fn test_vec_dedup_multiple_ident() {
22512251
#[test]
22522252
fn test_vec_dedup_partialeq() {
22532253
#[derive(Debug)]
2254-
struct Foo(i32, i32);
2254+
struct Foo(i32, #[allow(dead_code)] i32);
22552255

22562256
impl PartialEq for Foo {
22572257
fn eq(&self, other: &Foo) -> bool {

0 commit comments

Comments
 (0)