Skip to content

rustdoc: Show whether generic type params actually are ?Sized, not whether definition site syntactically includes ?Sized #143197

@obi1kenobi

Description

@obi1kenobi

Code

?Sized is unlike other bounds: while T: Foo demands that T implement Foo, T: ?Sized allows T to not be Sized — it does not demand it. It relaxes an obligation, that's it.

If that obligation is demanded by another clause, then adding ?Sized has no effect. For example:

trait Private: Sized {} pub fn example<T: Private + ?Sized>(value: &T) {}

Here T: Private and Private: Sized imply T: Sized, so T: ?Sized has no effect. This is confirmed by clippy, which raises a needless_maybe_sized lint here.

Since rustdoc is a tool for documenting the public API of Rust programs, I believe that it is misleading and undesirable for it to report T: ?Sized in circumstances where unsized types will not be accepted. It doesn't matter if the definition site of the generic type parameter syntactically mentions T: ?Sized if that clause has no effect on the public API.

Reproduction Steps

cargo doc for HTML output.

RUSTDOCFLAGS="-Z unstable-options --output-format=json --cap-lints=allow" cargo doc for JSON output.

Expected Outcome

Observe pub fn example<T: Private>(value: &T) as the recorded function signature in HTML docs. T: ?Sized does not apply to the API in practice, so it is excluded.

By the same reasoning, do not include T: ?Sized as a trait bound in rustdoc JSON.

Actual Output

Observe pub fn example<T: Private + ?Sized>(value: &T) as the recorded function signature in HTML docs.

Observe the following item in rustdoc JSON:

{ "id": 0, "crate_id": 0, "name": "example", "span": { // omitted for brevity }, "visibility": "public", "docs": null, "links": {}, "attrs": [], "deprecation": null, "inner": { "function": { "sig": { // omitted for brevity }, "generics": { "params": [ { "name": "T", "kind": { "type": { "bounds": [ { "trait_bound": { "trait": { "path": "Private", "id": 1, "args": { "angle_bracketed": { "args": [], "constraints": [] } } }, "generic_params": [], "modifier": "none" } }, { "trait_bound": { "trait": { "path": "Sized", "id": 2, "args": { "angle_bracketed": { "args": [], "constraints": [] } } }, "generic_params": [], "modifier": "maybe" // <-- `?Sized` } } ], "default": null, "is_synthetic": false } } } ], "where_predicates": [] }, // omitted for brevity } } }

Version

rustc 1.90.0-nightly (28f1c8079 2025-06-24) binary: rustc commit-hash: 28f1c807911c63f08d98e7b468cfcf15a441e34b commit-date: 2025-06-24 host: x86_64-unknown-linux-gnu release: 1.90.0-nightly LLVM version: 20.1.7 

@rustbot label +A-rustdoc-json

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions