Skip to content

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

Open
@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