-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Description
Currently, these two functions have the same type signature in rustdoc-json:
pub fn foo() -> impl Debug {
0i32
}
pub fn bar() -> impl Debug {
Cell::new(10)
} {
"inputs": [],
"is_c_variadic": false,
"output": {
"impl_trait": [
{
"trait_bound": {
"generic_params": [],
"modifier": "none",
"trait": {"args": null, "id": 1, "path": "Debug"}
}
}
]
}
}However, in practice, they are different types:
pub fn foo() -> impl Debug {
0i32
}
pub fn bar() -> impl Debug {
Cell::new(10)
}
pub fn check_sync<T: Sync>(_: T) {}
fn main() {
check_sync(foo()); // Ok
check_sync(bar()); // Errors
}This is because impl-trait's in return position implement the auto-traits of the underling type:
The type would not be known to implement any other trait, with the exception of OIBITS (aka “auto traits”) and default traits like Sized.
-- RFC 1522: conservative_impl_trait
A similar behavior occurs for the auto-traits of the opaque Future type returned by async fn's:
pub async fn foo() -> i32 {
0
}
pub async fn bar() -> i32 {
let x = Cell::new(10);
foo().await;
x.get()
}
pub fn check_sync<T: Sync>(_: T) {}
fn main() {
check_sync(foo()); // Ok
check_sync(bar()); // Errors
}Again, there's information about the type of this function that rustdoc-json doesn't currently capture.
It'd be nice to capture this in rustdoc-json. The motivating use case comes from cargo-semver-checks, which would like to be able to warn users if their RPIT's (or async-fn futures) are no longer Send/Sync when they used to be.
I think doing this is going to be difficult to implement, as it requires being able to run the typechecker, which rustdoc currently doesn't do: https://hackmd.io/@fhcjVaPtST635ujGv6RF4w/SkulRNn93. Maybe we could seperatly land that for JSON before HTML, as JSON isn't stable.