mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Allow reexports of items with same name but different types to both appear
This commit is contained in:
parent
9a7cc6c32f
commit
0541a0c8c3
@ -38,7 +38,7 @@ impl JsonRenderer<'_> {
|
|||||||
Some(UrlFragment::UserWritten(_)) | None => *page_id,
|
Some(UrlFragment::UserWritten(_)) | None => *page_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
(link.clone(), from_item_id(id.into(), self.tcx))
|
(link.clone(), id_from_item_inner(id.into(), self.tcx, None))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let docs = item.attrs.collapsed_doc_value();
|
let docs = item.attrs.collapsed_doc_value();
|
||||||
@ -50,7 +50,8 @@ impl JsonRenderer<'_> {
|
|||||||
.collect();
|
.collect();
|
||||||
let span = item.span(self.tcx);
|
let span = item.span(self.tcx);
|
||||||
let visibility = item.visibility(self.tcx);
|
let visibility = item.visibility(self.tcx);
|
||||||
let clean::Item { name, attrs: _, kind: _, item_id, cfg: _, .. } = item;
|
let clean::Item { name, item_id, .. } = item;
|
||||||
|
let id = id_from_item(&item, self.tcx);
|
||||||
let inner = match *item.kind {
|
let inner = match *item.kind {
|
||||||
clean::KeywordItem => return None,
|
clean::KeywordItem => return None,
|
||||||
clean::StrippedItem(ref inner) => {
|
clean::StrippedItem(ref inner) => {
|
||||||
@ -69,7 +70,7 @@ impl JsonRenderer<'_> {
|
|||||||
_ => from_clean_item(item, self.tcx),
|
_ => from_clean_item(item, self.tcx),
|
||||||
};
|
};
|
||||||
Some(Item {
|
Some(Item {
|
||||||
id: from_item_id_with_name(item_id, self.tcx, name),
|
id,
|
||||||
crate_id: item_id.krate().as_u32(),
|
crate_id: item_id.krate().as_u32(),
|
||||||
name: name.map(|sym| sym.to_string()),
|
name: name.map(|sym| sym.to_string()),
|
||||||
span: span.and_then(|span| self.convert_span(span)),
|
span: span.and_then(|span| self.convert_span(span)),
|
||||||
@ -107,7 +108,7 @@ impl JsonRenderer<'_> {
|
|||||||
Some(ty::Visibility::Public) => Visibility::Public,
|
Some(ty::Visibility::Public) => Visibility::Public,
|
||||||
Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
|
Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
|
||||||
Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
|
Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
|
||||||
parent: from_item_id(did.into(), self.tcx),
|
parent: id_from_item_inner(did.into(), self.tcx, None),
|
||||||
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
|
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -207,54 +208,61 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
|
|||||||
/// It generates an ID as follows:
|
/// It generates an ID as follows:
|
||||||
///
|
///
|
||||||
/// `CRATE_ID:ITEM_ID[:NAME_ID]` (if there is no name, NAME_ID is not generated).
|
/// `CRATE_ID:ITEM_ID[:NAME_ID]` (if there is no name, NAME_ID is not generated).
|
||||||
pub(crate) fn from_item_id(item_id: ItemId, tcx: TyCtxt<'_>) -> Id {
|
pub(crate) fn id_from_item_inner(item_id: ItemId, tcx: TyCtxt<'_>, extra: Option<&Id>) -> Id {
|
||||||
from_item_id_with_name(item_id, tcx, None)
|
struct DisplayDefId<'a, 'b>(DefId, TyCtxt<'a>, Option<&'b Id>);
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: this function (and appending the name at the end of the ID) should be removed when
|
impl<'a, 'b> fmt::Display for DisplayDefId<'a, 'b> {
|
||||||
// reexports are not inlined anymore for json format. It should be done in #93518.
|
|
||||||
pub(crate) fn from_item_id_with_name(item_id: ItemId, tcx: TyCtxt<'_>, name: Option<Symbol>) -> Id {
|
|
||||||
struct DisplayDefId<'a>(DefId, TyCtxt<'a>, Option<Symbol>);
|
|
||||||
|
|
||||||
impl<'a> fmt::Display for DisplayDefId<'a> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let DisplayDefId(def_id, tcx, name) = self;
|
let DisplayDefId(def_id, tcx, extra) = self;
|
||||||
let name = match name {
|
// We need this workaround because primitive types' DefId actually refers to
|
||||||
Some(name) => format!(":{}", name.as_u32()),
|
// their parent module, which isn't present in the output JSON items. So
|
||||||
None => {
|
// instead, we directly get the primitive symbol and convert it to u32 to
|
||||||
// We need this workaround because primitive types' DefId actually refers to
|
// generate the ID.
|
||||||
// their parent module, which isn't present in the output JSON items. So
|
let s;
|
||||||
// instead, we directly get the primitive symbol and convert it to u32 to
|
let extra = if let Some(e) = extra {
|
||||||
// generate the ID.
|
s = format!("-{}", e.0);
|
||||||
if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
|
&s
|
||||||
let Some(prim) = tcx.get_attrs(*def_id, sym::doc)
|
} else {
|
||||||
.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, "{}:{}{}", self.0.krate.as_u32(), u32::from(self.0.index), name)
|
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()
|
||||||
|
};
|
||||||
|
write!(f, "{}:{}{name}{extra}", self.0.krate.as_u32(), u32::from(self.0.index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match item_id {
|
match item_id {
|
||||||
ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did, tcx, name))),
|
ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did, tcx, extra))),
|
||||||
ItemId::Blanket { for_, impl_id } => {
|
ItemId::Blanket { for_, impl_id } => {
|
||||||
Id(format!("b:{}-{}", DisplayDefId(impl_id, tcx, None), DisplayDefId(for_, tcx, name)))
|
Id(format!("b:{}-{}", DisplayDefId(impl_id, tcx, None), DisplayDefId(for_, tcx, extra)))
|
||||||
}
|
}
|
||||||
ItemId::Auto { for_, trait_ } => {
|
ItemId::Auto { for_, trait_ } => {
|
||||||
Id(format!("a:{}-{}", DisplayDefId(trait_, tcx, None), DisplayDefId(for_, tcx, name)))
|
Id(format!("a:{}-{}", DisplayDefId(trait_, tcx, None), DisplayDefId(for_, tcx, extra)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
_ => id_from_item_inner(item.item_id, tcx, None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
|
fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
|
||||||
use clean::ItemKind::*;
|
use clean::ItemKind::*;
|
||||||
let name = item.name;
|
let name = item.name;
|
||||||
@ -525,7 +533,7 @@ impl FromWithTcx<clean::Path> for Path {
|
|||||||
fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
|
fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
|
||||||
Path {
|
Path {
|
||||||
name: path.whole_name(),
|
name: path.whole_name(),
|
||||||
id: from_item_id(path.def_id().into(), tcx),
|
id: id_from_item_inner(path.def_id().into(), tcx, None),
|
||||||
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
|
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -702,7 +710,7 @@ impl FromWithTcx<clean::Import> for Import {
|
|||||||
Import {
|
Import {
|
||||||
source: import.source.path.whole_name(),
|
source: import.source.path.whole_name(),
|
||||||
name,
|
name,
|
||||||
id: import.source.did.map(ItemId::from).map(|i| from_item_id(i, tcx)),
|
id: import.source.did.map(ItemId::from).map(|i| id_from_item_inner(i, tcx, None)),
|
||||||
glob,
|
glob,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -791,7 +799,7 @@ fn ids(items: impl IntoIterator<Item = clean::Item>, tcx: TyCtxt<'_>) -> Vec<Id>
|
|||||||
items
|
items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !x.is_stripped() && !x.is_keyword())
|
.filter(|x| !x.is_stripped() && !x.is_keyword())
|
||||||
.map(|i| from_item_id_with_name(i.item_id, tcx, i.name))
|
.map(|i| id_from_item(&i, tcx))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,12 +809,10 @@ fn ids_keeping_stripped(
|
|||||||
) -> Vec<Option<Id>> {
|
) -> Vec<Option<Id>> {
|
||||||
items
|
items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|i| {
|
.map(
|
||||||
if !i.is_stripped() && !i.is_keyword() {
|
|i| {
|
||||||
Some(from_item_id_with_name(i.item_id, tcx, i.name))
|
if !i.is_stripped() && !i.is_keyword() { Some(id_from_item(&i, tcx)) } else { None }
|
||||||
} else {
|
},
|
||||||
None
|
)
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ use crate::docfs::PathError;
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::formats::cache::Cache;
|
use crate::formats::cache::Cache;
|
||||||
use crate::formats::FormatRenderer;
|
use crate::formats::FormatRenderer;
|
||||||
use crate::json::conversions::{from_item_id, from_item_id_with_name, IntoWithTcx};
|
use crate::json::conversions::{id_from_item, id_from_item_inner, IntoWithTcx};
|
||||||
use crate::{clean, try_err};
|
use crate::{clean, try_err};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -58,7 +58,7 @@ impl<'tcx> JsonRenderer<'tcx> {
|
|||||||
.map(|i| {
|
.map(|i| {
|
||||||
let item = &i.impl_item;
|
let item = &i.impl_item;
|
||||||
self.item(item.clone()).unwrap();
|
self.item(item.clone()).unwrap();
|
||||||
from_item_id_with_name(item.item_id, self.tcx, item.name)
|
id_from_item(&item, self.tcx)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
@ -89,7 +89,7 @@ impl<'tcx> JsonRenderer<'tcx> {
|
|||||||
|
|
||||||
if item.item_id.is_local() || is_primitive_impl {
|
if item.item_id.is_local() || is_primitive_impl {
|
||||||
self.item(item.clone()).unwrap();
|
self.item(item.clone()).unwrap();
|
||||||
Some(from_item_id_with_name(item.item_id, self.tcx, item.name))
|
Some(id_from_item(&item, self.tcx))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -150,7 +150,6 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||||||
// Flatten items that recursively store other items
|
// Flatten items that recursively store other items
|
||||||
item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());
|
item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());
|
||||||
|
|
||||||
let name = item.name;
|
|
||||||
let item_id = item.item_id;
|
let item_id = item.item_id;
|
||||||
if let Some(mut new_item) = self.convert_item(item) {
|
if let Some(mut new_item) = self.convert_item(item) {
|
||||||
let can_be_ignored = match new_item.inner {
|
let can_be_ignored = match new_item.inner {
|
||||||
@ -193,10 +192,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||||||
| types::ItemEnum::Macro(_)
|
| types::ItemEnum::Macro(_)
|
||||||
| types::ItemEnum::ProcMacro(_) => false,
|
| types::ItemEnum::ProcMacro(_) => false,
|
||||||
};
|
};
|
||||||
let removed = self
|
let removed = self.index.borrow_mut().insert(new_item.id.clone(), new_item.clone());
|
||||||
.index
|
|
||||||
.borrow_mut()
|
|
||||||
.insert(from_item_id_with_name(item_id, self.tcx, name), new_item.clone());
|
|
||||||
|
|
||||||
// FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
|
// FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
|
||||||
// to make sure the items are unique. The main place this happens is when an item, is
|
// to make sure the items are unique. The main place this happens is when an item, is
|
||||||
@ -207,6 +203,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||||||
if !can_be_ignored {
|
if !can_be_ignored {
|
||||||
assert_eq!(old_item, new_item);
|
assert_eq!(old_item, new_item);
|
||||||
}
|
}
|
||||||
|
trace!("replaced {:?}\nwith {:?}", old_item, new_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +243,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||||||
.chain(&self.cache.external_paths)
|
.chain(&self.cache.external_paths)
|
||||||
.map(|(&k, &(ref path, kind))| {
|
.map(|(&k, &(ref path, kind))| {
|
||||||
(
|
(
|
||||||
from_item_id(k.into(), self.tcx),
|
id_from_item_inner(k.into(), self.tcx, None),
|
||||||
types::ItemSummary {
|
types::ItemSummary {
|
||||||
crate_id: k.krate.as_u32(),
|
crate_id: k.krate.as_u32(),
|
||||||
path: path.iter().map(|s| s.to_string()).collect(),
|
path: path.iter().map(|s| s.to_string()).collect(),
|
||||||
|
Loading…
Reference in New Issue
Block a user