Skip to content

Add new style lint: Warn if first paragraph in docstring is too long. #12989

Closed
@emilk

Description

@emilk

What it does

Warn when the first paragraph of a docstring is overly long.

cargo doc will show the first paragraph of the doscstring in the summary page on a crate and module, so having a nice, short summary in the first paragraph is part of writing good docs.

A very long first paragraph can be easily created by mistake. That's because cargo doc (and most markdown viewers) ignores single newlines and requires a double newline to register as a new paragraph. So this is one paragraph:

/// A very short summary.
/// A much longer explanation that goes into a lot more detail about
/// how the thing works, possibly with doclinks and so one,
/// and probably spanning a many rows.
struct Foo {}

while this is two paragraphs:

/// A very short summary.
///
/// A much longer explanation that goes into a lot more detail about
/// how the thing works, possibly with doclinks and so one,
/// and probably spanning a many rows.
struct Foo {}

Advantage

An overly long first paragraph makes for a bad summary, and a bad overview in a docs page for a crate:

Screenshot 2024-06-23 at 22 44 27

Here's how it looks with an added ///:
Screenshot 2024-06-23 at 22 52 57

Drawbacks

It might be annoying if the length limit is set too low.

I suggest a default of 80 chars, but configurable in clippy.toml.

Example

/// A rectangular region of space.
/// Usually a [`Rect`] has a positive (or zero) size,
/// and then [`Self::min`] `<=` [`Self::max`].
/// In these cases [`Self::min`] is the left-top corner
/// and [`Self::max`] is the right-bottom corner.
/// A rectangle is allowed to have a negative size, which happens when the order
/// of `min` and `max` are swapped. These are usually a sign of an error.
/// Normally the unit is points (logical pixels) in screen space coordinates.
/// `Rect` does NOT implement `Default`, because there is no obvious default value.
/// [`Rect::ZERO`] may seem reasonable, but when used as a bounding box, [`Rect::NOTHING`]
/// is a better default - so be explicit instead!
#[derive(Clone, Copy, Eq, PartialEq)]
struct Rect {}

Could be written as:

/// A rectangular region of space.
/// 
/// Usually a [`Rect`] has a positive (or zero) size,
/// and then [`Self::min`] `<=` [`Self::max`].
/// In these cases [`Self::min`] is the left-top corner
/// and [`Self::max`] is the right-bottom corner.
/// A rectangle is allowed to have a negative size, which happens when the order
/// of `min` and `max` are swapped. These are usually a sign of an error.
/// Normally the unit is points (logical pixels) in screen space coordinates.
/// `Rect` does NOT implement `Default`, because there is no obvious default value.
/// [`Rect::ZERO`] may seem reasonable, but when used as a bounding box, [`Rect::NOTHING`]
/// is a better default - so be explicit instead!
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Rect {

Note that we should suggest the added extra newline, as no doubt a lot of programmers aren't aware of this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions