Skip to content

ICE on rustdoc-json with re-export due to ID collision #80664

Closed
@aDotInTheVoid

Description

@aDotInTheVoid

Code

mod inner {
    pub struct Public;
}
pub use inner::Public as Reexported;

Meta

Invoke with rustdoc broke.rs --output-format json

rustdoc --version --verbose:

rustdoc 1.51.0-nightly (fde692739 2021-01-02)
binary: rustdoc
commit-hash: fde692739576089729885b7f79aa2232cb9778c5
commit-date: 2021-01-02
host: x86_64-apple-darwin
release: 1.51.0-nightly

Error output

thread 'rustc' panicked at 'assertion failed: `(left == right)`
  left: `Item { id: Id("0:4"), crate_id: 0, name: Some("Reexported"), source: Some(Span { filename: "broke.rs", begin: (2, 4), end: (2, 22) }), visibility: Public, docs: "", links: {}, attrs: [], deprecation: None, kind: Struct, inner: StructItem(Struct { struct_type: Unit, generics: Generics { params: [], where_predicates: [] }, fields_stripped: false, fields: [], impls: [Id("0:9"), Id("0:10"), Id("0:11"), Id("0:13"), Id("0:14")] }) }`,
 right: `Item { id: Id("0:4"), crate_id: 0, name: Some("Public"), source: Some(Span { filename: "broke.rs", begin: (2, 4), end: (2, 22) }), visibility: Public, docs: "", links: {}, attrs: [], deprecation: None, kind: Struct, inner: StructItem(Struct { struct_type: Unit, generics: Generics { params: [], where_predicates: [] }, fields_stripped: false, fields: [], impls: [Id("0:9"), Id("0:10"), Id("0:11"), Id("0:13"), Id("0:14")] }) }`', src/librustdoc/json/mod.rs:167:17
Backtrace

RUST_BACKTRACE=1 rustdoc broke.rs --output-format json
thread 'rustc' panicked at 'assertion failed: `(left == right)`
  left: `Item { id: Id("0:4"), crate_id: 0, name: Some("Reexported"), source: Some(Span { filename: "broke.rs", begin: (2, 4), end: (2, 22) }), visibility: Public, docs: "", links: {}, attrs: [], deprecation: None, kind: Struct, inner: StructItem(Struct { struct_type: Unit, generics: Generics { params: [], where_predicates: [] }, fields_stripped: false, fields: [], impls: [Id("0:9"), Id("0:10"), Id("0:11"), Id("0:13"), Id("0:14")] }) }`,
 right: `Item { id: Id("0:4"), crate_id: 0, name: Some("Public"), source: Some(Span { filename: "broke.rs", begin: (2, 4), end: (2, 22) }), visibility: Public, docs: "", links: {}, attrs: [], deprecation: None, kind: Struct, inner: StructItem(Struct { struct_type: Unit, generics: Generics { params: [], where_predicates: [] }, fields_stripped: false, fields: [], impls: [Id("0:9"), Id("0:10"), Id("0:11"), Id("0:13"), Id("0:14")] }) }`', src/librustdoc/json/mod.rs:167:17
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_fmt
   2: <rustdoc::json::JsonRenderer as rustdoc::formats::renderer::FormatRenderer>::item
   3: rustdoc::formats::renderer::run_format
   4: rustdoc::run_renderer
   5: rustc_session::utils::<impl rustc_session::session::Session>::time
   6: rustc_interface::passes::QueryContext::enter
   7: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
   8: rustc_span::with_source_map
   9: rustc_interface::interface::create_compiler_and_run
  10: rustdoc::main_options
  11: scoped_tls::ScopedKey<T>::set
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

error: Unrecognized option: 'output-format'

Working variants

mod inner { pub struct Public; }
use inner::Public as Reexported;
json
{
    "root": "0:0",
    "crate_version": null,
    "includes_private": false,
    "index": {
        "0:0": {
            "id": "0:0",
            "inner": {
                "is_crate": true,
                "items": []
            },
            "kind": "module",
            "name": "work1",
            "visibility": "public"
        }
    },
    "paths": {
        "0:0": {
            "crate_id": 0,
            "path": ["work1"],
            "kind": "module"
        }
    },
    "external_crates": {},
    "format_version": 1
}
mod inner { pub struct Public; }
pub use inner::Public;
json
{
    "root": "0:0",
    "crate_version": null,
    "includes_private": false,
    "index": {
        "0:0": {
            "id": "0:0",
            "inner": {
                "is_crate": true,
                "items": ["0:4"]
            },
            "kind": "module",
            "name": "work2",
            "visibility": "public"
        },
        "0:4": {
            "id": "0:4",
            "inner": {
                "struct_type": "unit",
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "fields_stripped": false,
                "fields": [],
                "impls": ["0:9", "0:10", "0:11", "0:13", "0:14"]
            },
            "kind": "struct",
            "name": "Public",
            "visibility": "public"
        }
    },
    "paths": {
        "0:4": {
            "crate_id": 0,
            "path": ["work2", "Public"],
            "kind": "struct"
        },
        "0:0": {
            "crate_id": 0,
            "path": ["work2"],
            "kind": "module"
        }
    },
    "external_crates": {},
    "format_version": 1
}
pub mod inner { pub struct Public; }
pub use inner::Public as Reexported;
json
{
    "root": "0:0",
    "crate_version": null,
    "includes_private": false,
    "index": {
        "0:6": {
            "id": "0:6",
            "inner": {
                "span": "inner::Public",
                "name": "Reexported",
                "id": "0:4",
                "glob": false
            },
            "kind": "import",
            "name": null,
            "visibility": "public"
        },
        "0:3": {
            "id": "0:3",
            "inner": {
                "is_crate": false,
                "items": ["0:4"]
            },
            "kind": "module",
            "name": "inner",
            "visibility": "public"
        },
        "0:0": {
            "id": "0:0",
            "inner": {
                "is_crate": true,
                "items": ["0:6", "0:3"]
            },
            "kind": "module",
            "name": "work3",
            "visibility": "public"
        },
        "0:4": {
            "id": "0:4",
            "inner": {
                "struct_type": "unit",
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "fields_stripped": false,
                "fields": [],
                "impls": ["0:9", "0:10", "0:11", "0:13", "0:14"]
            },
            "kind": "struct",
            "name": "Public",
            "visibility": "public"
        }
    },
    "paths": {
        "0:4": {
            "crate_id": 0,
            "path": ["work3", "inner", "Public"],
            "kind": "struct"
        },
        "0:3": {
            "crate_id": 0,
            "path": ["work3", "inner"],
            "kind": "module"
        },
        "0:0": {
            "crate_id": 0,
            "path": ["work3"],
            "kind": "module"
        }
    },
    "external_crates": {},
    "format_version": 1
}

Whats happening

The panic is here

let removed = self.index.borrow_mut().insert(id.into(), new_item.clone());
// FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
// to make sure the items are unique.
if let Some(old_item) = removed {
assert_eq!(old_item, new_item);
}
}

inner::Public is being added to the index when is shouldn't (I think), so when Reexported is added, the IDs colide, and we bail.

I think the solution is that inner::Public should never have been added into the index.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-rustdoc-jsonArea: Rustdoc JSON backendC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions