Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --field contains wrong IDs for some kind of items. Items for which no independent HTML is generated (link target URL is ) appear to have incorrect IDs. I tried this code: I expected to see this happen: contains the IDs of link targets Instead, this happened: contains the ID of the items containing the link targets <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
modify labels: +A-rustdoc-json +T-rustdoc +A-intra-doc-links
claim

Discussion:
.get(&self.item_id) .map_or(&[][..], |v| v.as_slice()) .iter() <del> .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| { </del> <ins> .filter_map(|ItemLink { link: s, link_text, page_id: did, ref fragment }| { </ins> debug!(?did); if let Ok((mut href, ..)) = href(*did, cx) { debug!(?href);

/// This may not be the same as `link` if there was a disambiguator /// in an intra-doc link (e.g. [`fn@f`]) pub(crate) link_text: String, <del> pub(crate) did: DefId, </del> <ins> /// The `DefId` of the Item whose **HTML Page** contains the item being /// linked to. This will be different to `item_id` on item's that don't /// have their own page, such as struct fields and enum variants. pub(crate) page_id: DefId, </ins> /// The url fragment to append to the link pub(crate) fragment: Option<UrlFragment>, }

use crate::clean::{self, ItemId}; use crate::formats::item_type::ItemType; use crate::json::JsonRenderer; <ins> use crate::passes::collect_intra_doc_links::UrlFragment; </ins> impl JsonRenderer<'_> { pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {

.get(&item.item_id) .into_iter() .flatten() <del> .map(|clean::ItemLink { link, did, .. }| { (link.clone(), from_item_id((*did).into(), self.tcx)) </del> <ins> .map(|clean::ItemLink { link, page_id, fragment, .. }| { let id = match fragment { Some(UrlFragment::Item(frag_id)) => *frag_id, // FIXME: Pass the `UserWritten` segment to JSON consumer. Some(UrlFragment::UserWritten(_)) | None => *page_id, }; (link.clone(), from_item_id(id.into(), self.tcx)) </ins> }) .collect(); let docs = item.attrs.collapsed_doc_value();

#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub(crate) enum UrlFragment { Item(DefId), <ins> /// A part of a page that isn't a rust item. /// /// Eg: `[Vector Examples](std::vec::Vec#examples)` </ins> UserWritten(String), }

Some(ItemLink { link: ori_link.link.clone(), link_text: link_text.clone(), <del> did: res.def_id(self.cx.tcx), </del> <ins> page_id: res.def_id(self.cx.tcx), </ins> fragment, }) }

item, &diag_info, )?; <del> let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); </del> <ins> let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); </ins> Some(ItemLink { link: ori_link.link.clone(), link_text: link_text.clone(), <del> did: id, </del> <ins> page_id, </ins> fragment, }) }

<ins> // Regression test for <https://github.com/rust-lang/rust/issues/101531>, // where links where to the item who's HTML page had the item linked to. //! [`Struct::struct_field`] //! [`Enum::Variant`] //! [`Trait::AssocType`] //! [`Trait::ASSOC_CONST`] //! [`Trait::method`] // @set struct_field = "$.index[*][?(@.name=='struct_field')].id" // @set Variant = "$.index[*][?(@.name=='Variant')].id" // @set AssocType = "$.index[*][?(@.name=='AssocType')].id" // @set ASSOC_CONST = "$.index[*][?(@.name=='ASSOC_CONST')].id" // @set method = "$.index[*][?(@.name=='method')].id" // @is "$.index[*][?(@.name=='non_page')].links['`Struct::struct_field`']" $struct_field // @is "$.index[*][?(@.name=='non_page')].links['`Enum::Variant`']" $Variant // @is "$.index[*][?(@.name=='non_page')].links['`Trait::AssocType`']" $AssocType // @is "$.index[*][?(@.name=='non_page')].links['`Trait::ASSOC_CONST`']" $ASSOC_CONST // @is "$.index[*][?(@.name=='non_page')].links['`Trait::method`']" $method pub struct Struct { pub struct_field: i32, } pub enum Enum { Variant(), } pub trait Trait { const ASSOC_CONST: i32; type AssocType; fn method(); } </ins>

<ins> //! For motivation, see [the reasons](foo#reasons) /// # Reasons /// To test rustdoc json pub fn foo() {} // @set foo = "$.index[*][?(@.name=='foo')].id" // @is "$.index[*][?(@.name=='user_written')].links['foo#reasons']" $foo </ins>