Skip to content

rustdoc-json: Dangling ID when private struct used in bound for pub-on-pub impl #113674

Open
@aDotInTheVoid

Description

@aDotInTheVoid

With the code:

#![feature(no_core)]
#![no_core]

pub trait Trait {}

pub struct Pub;
struct Priv;

impl Trait for Pub where Priv: Trait {}

fails to valididate in jsondoclint:

---- [rustdoc-json] tests/rustdoc-json/impls/private_generic_bound.rs stdout ----

error: jsondoclint failed!
status: exit status: 1
command: "/home/gh-aDotInTheVoid/rust/build/aarch64-unknown-linux-gnu/stage0-tools-bin/jsondoclint" "/home/gh-aDotInTheVoid/rust/build/aarch64-unknown-linux-gnu/test/rustdoc-json/impls/private_generic_bound/private_generic_bound.json"
stdout: none
--- stderr -------------------------------
0:4:1635 not in index or paths, but referred to at '$.index["0:6"].inner.impl.generics.where_predicates[0].bound_predicate.type.resolved_path.id'
Error: Errors validating json /home/gh-aDotInTheVoid/rust/build/aarch64-unknown-linux-gnu/test/rustdoc-json/impls/private_generic_bound/private_generic_bound.json
------------------------------------------

Because it produces (redacted)

    "0:6": {
      "inner": {
        "impl": {
          "blanket_impl": null,
          "for": {"resolved_path": {"id": "0:2:1634", "name": "Pub"}},
          "generics": {
            "where_predicates": [
              {
                "bound_predicate": {
                  "bounds": [
                    {
                      "trait_bound": {"modifier": "none", "trait": {"id": "0:1:1633", "name": "Trait"}}
                    }
                  ],
                  "type": {"resolved_path": {"id": "0:4:1635", "name": "Priv"}}
                }
              }
            ]
          },
          "is_unsafe": false,
          "items": [],
          "negative": false,
          "provided_trait_methods": [],
          "synthetic": false,
          "trait": {"id": "0:1:1633", "name": "Trait"}
        }
      },
      "name": null
    }
  },

This pattern comes up in practice eg:

unsafe impl<I, U, F> TrustedLen for FlatMap<I, U, F>
where
I: Iterator,
U: IntoIterator,
F: FnMut(I::Item) -> U,
FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>: TrustedLen,
{
}

where TrustedLen and FlatMap are part of cores public API, but FlattenCompat isn't.

HTML get's arround this by not linking to the item:

screenshot of impl from core in rustdoc

screenshot of impl from MCVE in rustdoc

I have no idea what the right thing to do here is design-wise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-rustdoc-jsonArea: Rustdoc JSON backendC-bugCategory: This is a bug.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