rust-lang / rust-lang/rust-clippy

Add clippy::exposed_private_fields for macros that generate constructors

Open
#9,090 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

Various derive macros, most famously serde::Deserialize, generate constructors for objects. These constructors expose a vector to set arbitrary values on the fields of the struct, including private fields.

I propose an annotation: #[clippy::check_for_private_fields]. Throughout the Rust ecosystem, macros that generate constructors will add this lint to structs. When Clippy encounters a struct with this annotation, it will check for the presence of private fields, and emit the clippy::exposed_private_fields lint warning if it finds any private fields.

I am co-author of the zerovec crate, and I am interested in applying this lint to our #[derive(ULE)] macro. Downstream issue: https://github.com/unicode-org/icu4x/issues/1691

Lint Name

clippy::exposed_private_fields

Category

suspicious, pedantic

Advantage

Reminds developers to check for invariants on private fields when using derive macros that create constructors.

Drawbacks

There may not be any invariants to check. Private fields do not necessarily imply the existence of an invariant. In these cases, the lint can be suppressed with #[allow(clippy::exposed_private_fields)].

Example

The following struct has an invariant that is trivially violated by using the deserialize constructor generated by #[derive(Deserialize)]

#[derive(Deserialize)]
pub struct EvenNumber {
    // Invariant: number is even
    num: u32
}

There should instead be a custom Deserialize impl, or some other method to check for invariants like serde::deserialize_with.

pub struct EvenNumber {
    // Invariant: number is even
    num: u32
}

impl Deserialize for EvenNumber {
    // Some impl that checks that the number is even
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading this proposal and its EvenNumber example, then review the linked ICU4X downstream issue for the motivating use case. Done means defining the annotation and clippy::exposed_private_fields behavior so annotated structs with private fields receive the proposed warning, with suppression remaining possible as described.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.