Skip to content

Commit acfe7c4

Browse files
authored
Rollup merge of #85200 - FabianWolff:issue-84647, r=nikomatsakis
Ignore derived Clone and Debug implementations during dead code analysis This pull request fixes #84647. Derived implementations of `Clone` and `Debug` always trivially read all fields, so "field is never read" dead code warnings are never triggered. Arguably, though, a user most likely will only be interested in whether _their_ code ever reads those fields, which is the behavior I have implemented here. Note that implementations of `Clone` and `Debug` are only ignored if they are `#[derive(...)]`d; a custom `impl Clone/Debug for ...` will still be analyzed normally (i.e. if a custom `Clone` implementation uses all fields of the struct, this will continue to suppress dead code warnings about unused fields); this seemed like the least intrusive change to me (although it would be easy to change — just drop the `&& [impl_]item.span.in_derive_expansion()` in the if conditions). The only thing that I am slightly unsure about is that in #84647, `@matklad` said > Doesn't seem easy to fix though :( However, it _was_ pretty straightforward to fix, so did I perhaps overlook something obvious? `@matklad,` could you weigh in on this?
2 parents 497ee32 + 79adda9 commit acfe7c4

Some content is hidden

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

54 files changed

+225
-107
lines changed

compiler/rustc_feature/src/accepted.rs

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ macro_rules! declare_features {
1616
since: $ver,
1717
issue: to_nonzero($issue),
1818
edition: None,
19-
description: concat!($($doc,)*),
2019
}
2120
),+
2221
];

compiler/rustc_feature/src/active.rs

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ macro_rules! declare_features {
3737
since: $ver,
3838
issue: to_nonzero($issue),
3939
edition: $edition,
40-
description: concat!($($doc,)*),
4140
}
4241
),+];
4342

compiler/rustc_feature/src/builtin_attrs.rs

+3
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
453453
),
454454
// Enumerates "identity-like" conversion methods to suggest on type mismatch.
455455
rustc_attr!(rustc_conversion_suggestion, Normal, template!(Word), INTERNAL_UNSTABLE),
456+
// Prevents field reads in the marked trait or method to be considered
457+
// during dead code analysis.
458+
rustc_attr!(rustc_trivial_field_reads, Normal, template!(Word), INTERNAL_UNSTABLE),
456459

457460
// ==========================================================================
458461
// Internal attributes, Const related:

compiler/rustc_feature/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ pub struct Feature {
5151
pub since: &'static str,
5252
issue: Option<NonZeroU32>,
5353
pub edition: Option<Edition>,
54-
description: &'static str,
5554
}
5655

5756
#[derive(Copy, Clone, Debug)]

compiler/rustc_feature/src/removed.rs

-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ macro_rules! declare_features {
1616
since: $ver,
1717
issue: to_nonzero($issue),
1818
edition: None,
19-
description: concat!($($doc,)*),
2019
}
2120
),+
2221
];
@@ -34,7 +33,6 @@ macro_rules! declare_features {
3433
since: $ver,
3534
issue: to_nonzero($issue),
3635
edition: None,
37-
description: concat!($($doc,)*),
3836
}
3937
),+
4038
];

compiler/rustc_middle/src/hir/map/collector.rs

-7
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ fn hash_body(
6262
stable_hasher.finish()
6363
}
6464

65-
/// Represents an entry and its parent `HirId`.
66-
#[derive(Copy, Clone, Debug)]
67-
pub struct Entry<'hir> {
68-
parent: HirId,
69-
node: Node<'hir>,
70-
}
71-
7265
impl<'a, 'hir> NodeCollector<'a, 'hir> {
7366
pub(super) fn root(
7467
sess: &'a Session,

compiler/rustc_middle/src/ich/hcx.rs

-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
2828
/// things (e.g., each `DefId`/`DefPath` is only hashed once).
2929
#[derive(Clone)]
3030
pub struct StableHashingContext<'a> {
31-
sess: &'a Session,
3231
definitions: &'a Definitions,
3332
cstore: &'a dyn CrateStore,
3433
pub(super) body_resolver: BodyResolver<'a>,
@@ -78,7 +77,6 @@ impl<'a> StableHashingContext<'a> {
7877
!always_ignore_spans && !sess.opts.debugging_opts.incremental_ignore_spans;
7978

8079
StableHashingContext {
81-
sess,
8280
body_resolver: BodyResolver(krate),
8381
definitions,
8482
cstore,

compiler/rustc_mir_build/src/build/matches/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -900,10 +900,7 @@ fn traverse_candidate<'pat, 'tcx: 'pat, C, T, I>(
900900
struct Binding<'tcx> {
901901
span: Span,
902902
source: Place<'tcx>,
903-
name: Symbol,
904903
var_id: HirId,
905-
var_ty: Ty<'tcx>,
906-
mutability: Mutability,
907904
binding_mode: BindingMode,
908905
}
909906

compiler/rustc_mir_build/src/build/matches/simplify.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
176176
Ok(())
177177
}
178178

179-
PatKind::Binding { name, mutability, mode, var, ty, ref subpattern, is_primary: _ } => {
179+
PatKind::Binding {
180+
name: _,
181+
mutability: _,
182+
mode,
183+
var,
184+
ty: _,
185+
ref subpattern,
186+
is_primary: _,
187+
} => {
180188
if let Ok(place_resolved) =
181189
match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
182190
{
183191
candidate.bindings.push(Binding {
184-
name,
185-
mutability,
186192
span: match_pair.pattern.span,
187193
source: place_resolved.into_place(self.tcx, self.typeck_results),
188194
var_id: var,
189-
var_ty: ty,
190195
binding_mode: mode,
191196
});
192197
}

compiler/rustc_mir_build/src/build/scope.rs

-4
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,6 @@ struct Scope {
118118
/// the region span of this scope within source code.
119119
region_scope: region::Scope,
120120

121-
/// the span of that region_scope
122-
region_scope_span: Span,
123-
124121
/// set of places to drop when exiting this scope. This starts
125122
/// out empty but grows as variables are declared during the
126123
/// building process. This is a stack, so we always drop from the
@@ -420,7 +417,6 @@ impl<'tcx> Scopes<'tcx> {
420417
self.scopes.push(Scope {
421418
source_scope: vis_scope,
422419
region_scope: region_scope.0,
423-
region_scope_span: region_scope.1.span,
424420
drops: vec![],
425421
moved_locals: vec![],
426422
cached_unwind_block: None,

compiler/rustc_mir_transform/src/coverage/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
263263
}
264264

265265
if let Err(e) = result {
266-
bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e)
266+
bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e.message)
267267
};
268268

269269
// Depending on current `debug_options()`, `alert_on_unused_expressions()` could panic, so

compiler/rustc_passes/src/dead.rs

+62
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,69 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
239239
}
240240
}
241241

242+
/// Automatically generated items marked with `rustc_trivial_field_reads`
243+
/// will be ignored for the purposes of dead code analysis (see PR #85200
244+
/// for discussion).
245+
fn should_ignore_item(&self, def_id: DefId) -> bool {
246+
if !self.tcx.has_attr(def_id, sym::automatically_derived)
247+
&& !self
248+
.tcx
249+
.impl_of_method(def_id)
250+
.map_or(false, |impl_id| self.tcx.has_attr(impl_id, sym::automatically_derived))
251+
{
252+
return false;
253+
}
254+
255+
let has_attr = |def_id| self.tcx.has_attr(def_id, sym::rustc_trivial_field_reads);
256+
257+
if has_attr(def_id) {
258+
return true;
259+
}
260+
261+
if let Some(impl_of) = self.tcx.impl_of_method(def_id) {
262+
if has_attr(impl_of) {
263+
return true;
264+
}
265+
266+
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of) {
267+
if has_attr(trait_of) {
268+
return true;
269+
}
270+
271+
if let Some(method_ident) = self.tcx.opt_item_name(def_id) {
272+
if let Some(trait_method) = self
273+
.tcx
274+
.associated_items(trait_of)
275+
.find_by_name_and_kind(self.tcx, method_ident, ty::AssocKind::Fn, trait_of)
276+
{
277+
if has_attr(trait_method.def_id) {
278+
return true;
279+
}
280+
}
281+
}
282+
}
283+
} else if let Some(trait_of) = self.tcx.trait_of_item(def_id) {
284+
if has_attr(trait_of) {
285+
return true;
286+
}
287+
}
288+
289+
return false;
290+
}
291+
242292
fn visit_node(&mut self, node: Node<'tcx>) {
293+
if let Some(item_def_id) = match node {
294+
Node::Item(hir::Item { def_id, .. })
295+
| Node::ForeignItem(hir::ForeignItem { def_id, .. })
296+
| Node::TraitItem(hir::TraitItem { def_id, .. })
297+
| Node::ImplItem(hir::ImplItem { def_id, .. }) => Some(def_id.to_def_id()),
298+
_ => None,
299+
} {
300+
if self.should_ignore_item(item_def_id) {
301+
return;
302+
}
303+
}
304+
243305
let had_repr_c = self.repr_has_repr_c;
244306
let had_inherited_pub_visibility = self.inherited_pub_visibility;
245307
let had_pub_visibility = self.pub_visibility;

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,7 @@ symbols! {
11341134
rustc_synthetic,
11351135
rustc_test_marker,
11361136
rustc_then_this_would_need,
1137+
rustc_trivial_field_reads,
11371138
rustc_unsafe_specialization_marker,
11381139
rustc_variance,
11391140
rustdoc,

library/core/src/clone.rs

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
#[stable(feature = "rust1", since = "1.0.0")]
106106
#[lang = "clone"]
107107
#[rustc_diagnostic_item = "Clone"]
108+
#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
108109
pub trait Clone: Sized {
109110
/// Returns a copy of the value.
110111
///

library/core/src/fmt/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ impl Display for Arguments<'_> {
582582
)]
583583
#[doc(alias = "{:?}")]
584584
#[rustc_diagnostic_item = "debug_trait"]
585+
#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
585586
pub trait Debug {
586587
/// Formats the value using the given formatter.
587588
///

library/core/tests/fmt/builders.rs

+1
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ mod debug_list {
653653
fn test_formatting_parameters_are_forwarded() {
654654
use std::collections::{BTreeMap, BTreeSet};
655655
#[derive(Debug)]
656+
#[allow(dead_code)]
656657
struct Foo {
657658
bar: u32,
658659
baz: u32,

library/std/src/io/buffered/tests.rs

-4
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,6 @@ struct ProgrammableSink {
468468
// Writes append to this slice
469469
pub buffer: Vec<u8>,
470470

471-
// Flush sets this flag
472-
pub flushed: bool,
473-
474471
// If true, writes will always be an error
475472
pub always_write_error: bool,
476473

@@ -520,7 +517,6 @@ impl Write for ProgrammableSink {
520517
if self.always_flush_error {
521518
Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error"))
522519
} else {
523-
self.flushed = true;
524520
Ok(())
525521
}
526522
}

library/test/src/term/terminfo/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use parser::compiled::{msys_terminfo, parse};
1616
use searcher::get_dbpath_for_term;
1717

1818
/// A parsed terminfo database entry.
19+
#[allow(unused)]
1920
#[derive(Debug)]
2021
pub(crate) struct TermInfo {
2122
/// Names for the terminal

src/librustdoc/clean/inline.rs

-2
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,6 @@ fn build_macro(
557557
name: Symbol,
558558
import_def_id: Option<DefId>,
559559
) -> clean::ItemKind {
560-
let imported_from = cx.tcx.crate_name(def_id.krate);
561560
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
562561
LoadedMacro::MacroDef(item_def, _) => {
563562
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
@@ -569,7 +568,6 @@ fn build_macro(
569568
def_id,
570569
cx.tcx.visibility(import_def_id.unwrap_or(def_id)),
571570
),
572-
imported_from: Some(imported_from),
573571
})
574572
} else {
575573
unreachable!()

src/librustdoc/clean/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,6 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
18591859
}
18601860
ItemKind::Macro(ref macro_def) => MacroItem(Macro {
18611861
source: display_macro_source(cx, name, &macro_def, def_id, &item.vis),
1862-
imported_from: None,
18631862
}),
18641863
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
18651864
let items = item_ids

src/librustdoc/clean/types.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2202,7 +2202,6 @@ crate struct ImportSource {
22022202
#[derive(Clone, Debug)]
22032203
crate struct Macro {
22042204
crate source: String,
2205-
crate imported_from: Option<Symbol>,
22062205
}
22072206

22082207
#[derive(Clone, Debug)]

src/librustdoc/html/render/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ struct AllTypes {
224224
opaque_tys: FxHashSet<ItemEntry>,
225225
statics: FxHashSet<ItemEntry>,
226226
constants: FxHashSet<ItemEntry>,
227-
keywords: FxHashSet<ItemEntry>,
228227
attributes: FxHashSet<ItemEntry>,
229228
derives: FxHashSet<ItemEntry>,
230229
trait_aliases: FxHashSet<ItemEntry>,
@@ -245,7 +244,6 @@ impl AllTypes {
245244
opaque_tys: new_set(100),
246245
statics: new_set(100),
247246
constants: new_set(100),
248-
keywords: new_set(100),
249247
attributes: new_set(100),
250248
derives: new_set(100),
251249
trait_aliases: new_set(100),

src/test/ui/array-slice-vec/slice_binary_search.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// Test binary_search_by_key lifetime. Issue #34683
44

5+
#[allow(dead_code)]
56
#[derive(Debug)]
67
struct Assignment {
78
topic: String,

src/test/ui/borrowck/borrowck-unused-mut-locals.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// run-pass
2+
#![allow(dead_code)]
23
#![deny(unused_mut)]
34

45
#[derive(Debug)]

src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// check-pass
44
#![allow(unreachable_code)]
55
#![warn(unused)]
6+
#![allow(dead_code)]
67

78
#[derive(Debug)]
89
struct Point {

0 commit comments

Comments
 (0)