Skip to content

rustdoc-json: show leaked auto-trait definition for RPIT and async-fn #147927

@aDotInTheVoid

Description

@aDotInTheVoid

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
}

playground

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
}

playground

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-auto-traitsArea: auto traits (e.g., `auto trait Send {}`)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-rustdoc-jsonArea: Rustdoc JSON backendC-feature-requestCategory: A feature request, i.e: not implemented / a PR.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