rust-lang / rust-lang/rust

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

Open
#147,927 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-auto-traits A-impl-trait A-rustdoc-json C-feature-request T-rustdoc
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

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
}

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the rustdoc-json representation of RPIT and async-fn return types, then investigate the typechecker work described in the linked HackMD. Compare the JSON output for the Send/Sync examples and consider the separate JSON-before-HTML path mentioned in the issue. Done means rustdoc-json preserves the relevant leaked auto-trait information for cargo-semver-checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.