-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
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