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