Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix bad handling of primitive types
  • Loading branch information
GuillaumeGomez committed Feb 18, 2023
commit 3adc0812542e6c9b13c78b85407dcc9d54885e0e
76 changes: 47 additions & 29 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl JsonRenderer<'_> {
Some(UrlFragment::UserWritten(_)) | None => *page_id,
};

(link.clone(), id_from_item_inner(id.into(), self.tcx, None))
(link.clone(), id_from_item_inner(id.into(), self.tcx, None, None))
})
.collect();
let docs = item.attrs.collapsed_doc_value();
Expand Down Expand Up @@ -108,7 +108,7 @@ impl JsonRenderer<'_> {
Some(ty::Visibility::Public) => Visibility::Public,
Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
parent: id_from_item_inner(did.into(), self.tcx, None),
parent: id_from_item_inner(did.into(), self.tcx, None, None),
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
},
}
Expand Down Expand Up @@ -208,12 +208,17 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
/// It generates an ID as follows:
///
/// `CRATE_ID:ITEM_ID[:NAME_ID]` (if there is no name, NAME_ID is not generated).
pub(crate) fn id_from_item_inner(item_id: ItemId, tcx: TyCtxt<'_>, extra: Option<&Id>) -> Id {
struct DisplayDefId<'a, 'b>(DefId, TyCtxt<'a>, Option<&'b Id>);
pub(crate) fn id_from_item_inner(
item_id: ItemId,
tcx: TyCtxt<'_>,
extra: Option<&Id>,
name: Option<Symbol>,
) -> Id {
struct DisplayDefId<'a, 'b>(DefId, TyCtxt<'a>, Option<&'b Id>, Option<Symbol>);

impl<'a, 'b> fmt::Display for DisplayDefId<'a, 'b> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let DisplayDefId(def_id, tcx, extra) = self;
let DisplayDefId(def_id, tcx, extra, name) = self;
// We need this workaround because primitive types' DefId actually refers to
// their parent module, which isn't present in the output JSON items. So
// instead, we directly get the primitive symbol and convert it to u32 to
Expand All @@ -225,41 +230,54 @@ pub(crate) fn id_from_item_inner(item_id: ItemId, tcx: TyCtxt<'_>, extra: Option
} else {
""
};
let name = if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
let Some(prim) = tcx.get_attrs(*def_id, sym::doc)
.flat_map(|attr| attr.meta_item_list().unwrap_or_default())
.filter(|attr| attr.has_name(sym::primitive))
.find_map(|attr| attr.value_str()) {
format!(":{}", prim.as_u32())
} else {
tcx
.opt_item_name(*def_id)
.map(|n| format!(":{}", n.as_u32()))
.unwrap_or_default()
let name = match name {
Some(name) => format!(":{}", name.as_u32()),
None => {
// We need this workaround because primitive types' DefId actually refers to
// their parent module, which isn't present in the output JSON items. So
// instead, we directly get the primitive symbol and convert it to u32 to
// generate the ID.
if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
let Some(prim) = tcx.get_attrs(*def_id, sym::doc)
.flat_map(|attr| attr.meta_item_list().unwrap_or_default())
.filter(|attr| attr.has_name(sym::primitive))
.find_map(|attr| attr.value_str()) {
format!(":{}", prim.as_u32())
} else {
tcx
.opt_item_name(*def_id)
.map(|n| format!(":{}", n.as_u32()))
.unwrap_or_default()
}
}
};
write!(f, "{}:{}{name}{extra}", self.0.krate.as_u32(), u32::from(self.0.index))
write!(f, "{}:{}{name}{extra}", def_id.krate.as_u32(), u32::from(def_id.index))
}
}

match item_id {
ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did, tcx, extra))),
ItemId::Blanket { for_, impl_id } => {
Id(format!("b:{}-{}", DisplayDefId(impl_id, tcx, None), DisplayDefId(for_, tcx, extra)))
}
ItemId::Auto { for_, trait_ } => {
Id(format!("a:{}-{}", DisplayDefId(trait_, tcx, None), DisplayDefId(for_, tcx, extra)))
}
ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did, tcx, extra, name))),
ItemId::Blanket { for_, impl_id } => Id(format!(
"b:{}-{}",
DisplayDefId(impl_id, tcx, None, None),
DisplayDefId(for_, tcx, extra, name)
)),
ItemId::Auto { for_, trait_ } => Id(format!(
"a:{}-{}",
DisplayDefId(trait_, tcx, None, None),
DisplayDefId(for_, tcx, extra, name)
)),
}
}

pub(crate) fn id_from_item(item: &clean::Item, tcx: TyCtxt<'_>) -> Id {
match *item.kind {
clean::ItemKind::ImportItem(ref import) => {
let extra =
import.source.did.map(ItemId::from).map(|i| id_from_item_inner(i, tcx, None));
id_from_item_inner(item.item_id, tcx, extra.as_ref())
import.source.did.map(ItemId::from).map(|i| id_from_item_inner(i, tcx, None, None));
id_from_item_inner(item.item_id, tcx, extra.as_ref(), item.name)
}
_ => id_from_item_inner(item.item_id, tcx, None),
_ => id_from_item_inner(item.item_id, tcx, None, item.name),
}
}

Expand Down Expand Up @@ -533,7 +551,7 @@ impl FromWithTcx<clean::Path> for Path {
fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
Path {
name: path.whole_name(),
id: id_from_item_inner(path.def_id().into(), tcx, None),
id: id_from_item_inner(path.def_id().into(), tcx, None, None),
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
}
}
Expand Down Expand Up @@ -710,7 +728,7 @@ impl FromWithTcx<clean::Import> for Import {
Import {
source: import.source.path.whole_name(),
name,
id: import.source.did.map(ItemId::from).map(|i| id_from_item_inner(i, tcx, None)),
id: import.source.did.map(ItemId::from).map(|i| id_from_item_inner(i, tcx, None, None)),
glob,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
.chain(&self.cache.external_paths)
.map(|(&k, &(ref path, kind))| {
(
id_from_item_inner(k.into(), self.tcx, None),
id_from_item_inner(k.into(), self.tcx, None, None),
types::ItemSummary {
crate_id: k.krate.as_u32(),
path: path.iter().map(|s| s.to_string()).collect(),
Expand Down