Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,12 @@ pub(crate) struct RustcTrivialFieldReadsParser;

impl NoArgsAttributeParser for RustcTrivialFieldReadsParser {
const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads];
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
]);
const STABILITY: AttributeStability = unstable!(rustc_attrs);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads;
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_builtin_macros/src/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ pub(crate) fn expand_deriving_clone(
explicit_self: true,
nonself_args: Vec::new(),
ret_ty: Self_,
attributes: thin_vec![cx.attr_word(sym::inline, span)],
attributes: thin_vec![
cx.attr_word(sym::inline, span),
cx.attr_word(sym::rustc_trivial_field_reads, span)
],
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: substructure,
}],
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ pub(crate) fn expand_deriving_debug(
explicit_self: true,
nonself_args: vec![(fmtr, sym::character('f'))],
ret_ty: Path(path_std!(fmt::Result)),
attributes: thin_vec![cx.attr_word(sym::inline, span)],
attributes: thin_vec![
cx.attr_word(sym::inline, span),
cx.attr_word(sym::rustc_trivial_field_reads, span)
],
fieldless_variants_strategy:
FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
| DefKind::ExternCrate
| DefKind::Use
| DefKind::Ctor(..)
| DefKind::ForeignMod => true,
| DefKind::ForeignMod => !find_attr!(tcx, def_id, RustcTrivialFieldReads),

@mejrs mejrs Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm or maybe do this check for the things we support? I think that's DefKind::Fn only

View changes since the review


DefKind::TyParam
| DefKind::ConstParam
Expand Down Expand Up @@ -432,17 +432,16 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
ControlFlow::Continue(())
}

/// Automatically generated items marked with `rustc_trivial_field_reads`
/// Items marked with `rustc_trivial_field_reads`
/// will be ignored for the purposes of dead code analysis (see PR #85200
/// for discussion).
/// for discussion, and PR #160666).
fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool {
if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind
&& let impl_of = self.tcx.local_parent(impl_item.owner_id.def_id)
&& self.tcx.is_automatically_derived(impl_of.to_def_id())
&& let trait_ref =
self.tcx.impl_trait_ref(impl_of).instantiate_identity().skip_norm_wip()
&& find_attr!(self.tcx, trait_ref.def_id, RustcTrivialFieldReads)
&& find_attr!(self.tcx, impl_item.owner_id.def_id, RustcTrivialFieldReads)

@mejrs mejrs Aug 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attribute check is redundant now, right?

View changes since the review

{
let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity().skip_norm_wip();

if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
&& let Some(adt_def_id) = adt_def.did().as_local()
{
Expand All @@ -451,7 +450,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
return true;
}

false
return false;
}

fn visit_node(
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ mod uninit;
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "clone"]
#[rustc_diagnostic_item = "Clone"]
#[rustc_trivial_field_reads]
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
pub const trait Clone: Sized {
/// Returns a duplicate of the value.
Expand Down Expand Up @@ -285,7 +284,7 @@ pub const unsafe trait TrivialClone: [const] Clone {}
/// Derive macro generating an impl of the trait `Clone`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_clone_copy_internals, trivial_clone)]
#[allow_internal_unstable(core_intrinsics, derive_clone_copy_internals, trivial_clone, rustc_attrs)]
pub macro Clone($item:item) {
/* compiler built-in */
}
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,6 @@ impl Display for Arguments<'_> {
)]
#[doc(alias = "{:?}")]
#[rustc_diagnostic_item = "Debug"]
#[rustc_trivial_field_reads]
pub trait Debug: PointeeSized {
#[doc = include_str!("fmt_trait_method_doc.md")]
///
Expand Down Expand Up @@ -1089,7 +1088,7 @@ pub(crate) mod macros {
/// Derive macro generating an impl of the trait `Debug`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, fmt_helpers_for_derive)]
#[allow_internal_unstable(core_intrinsics, fmt_helpers_for_derive, rustc_attrs)]
pub macro Debug($item:item) {
/* compiler built-in */
}
Expand Down
23 changes: 23 additions & 0 deletions tests/ui/attributes/trivial-field-reads-invalid-targets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Checks that `#[rustc_trivial_field_reads]` are not allowed due to invalid targets

#![feature(rustc_attrs)]
#![deny(dead_code)]

trait Whatever {
#[rustc_trivial_field_reads] //~ERROR the `rustc_trivial_field_reads` attribute cannot be used on required trait methods
fn read(&self);
}

#[rustc_trivial_field_reads] //~ERROR the `rustc_trivial_field_reads` attribute cannot be used on traits
trait Whatever1 {}

#[rustc_trivial_field_reads] //~ERROR the `rustc_trivial_field_reads` attribute cannot be used on macro defs
macro_rules! number {
() => {
67
};
}

fn main() {
let _ = number!();
}
26 changes: 26 additions & 0 deletions tests/ui/attributes/trivial-field-reads-invalid-targets.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: the `rustc_trivial_field_reads` attribute cannot be used on required trait methods
--> $DIR/trivial-field-reads-invalid-targets.rs:7:7
|
LL | #[rustc_trivial_field_reads]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the `rustc_trivial_field_reads` attribute can only be applied to functions with a body

error: the `rustc_trivial_field_reads` attribute cannot be used on traits
--> $DIR/trivial-field-reads-invalid-targets.rs:11:3
|
LL | #[rustc_trivial_field_reads]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the `rustc_trivial_field_reads` attribute can only be applied to functions

error: the `rustc_trivial_field_reads` attribute cannot be used on macro defs
--> $DIR/trivial-field-reads-invalid-targets.rs:14:3
|
LL | #[rustc_trivial_field_reads]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the `rustc_trivial_field_reads` attribute can only be applied to functions

error: aborting due to 3 previous errors

Loading
Loading