#![allow(rustc::default_hash_types)]
use std::convert::From;
+use std::fmt;
use rustc_ast::ast;
-use rustc_hir::def::CtorKind;
+use rustc_hir::{def::CtorKind, def_id::DefId};
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::CRATE_DEF_INDEX;
use rustc_span::Pos;
use rustdoc_json_types::*;
use crate::clean::utils::print_const_expr;
-use crate::clean::{self, FakeDefId};
+use crate::clean::{self, ItemId};
use crate::formats::item_type::ItemType;
use crate::json::JsonRenderer;
use std::collections::HashSet;
.into_iter()
.flatten()
.filter_map(|clean::ItemLink { link, did, .. }| {
- did.map(|did| (link.clone(), from_def_id(did.into())))
+ did.map(|did| (link.clone(), from_item_id(did.into())))
})
.collect();
let docs = item.attrs.collapsed_doc_value();
_ => from_clean_item(item, self.tcx),
};
Some(Item {
- id: from_def_id(def_id),
+ id: from_item_id(def_id),
crate_id: def_id.krate().as_u32(),
name: name.map(|sym| sym.to_string()),
span: self.convert_span(span),
Inherited => Visibility::Default,
Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate,
Restricted(did) => Visibility::Restricted {
- parent: from_def_id(did.into()),
+ parent: from_item_id(did.into()),
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
},
}
}
}
-crate fn from_def_id(did: FakeDefId) -> Id {
+crate fn from_item_id(did: ItemId) -> Id {
+ struct DisplayDefId(DefId);
+
+ impl fmt::Display for DisplayDefId {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}:{}", self.0.krate.as_u32(), u32::from(self.0.index))
+ }
+ }
+
match did {
- FakeDefId::Real(did) => Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))),
- // We need to differentiate real and fake ids, because the indices might overlap for fake
- // and real DefId's, which would cause two different Id's treated as they were the same.
- FakeDefId::Fake(idx, krate) => Id(format!("F{}:{}", krate.as_u32(), u32::from(idx))),
+ ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did))),
+ ItemId::Blanket { for_, impl_id } => {
+ Id(format!("b:{}-{}", DisplayDefId(impl_id), DisplayDefId(for_)))
+ }
+ ItemId::Auto { for_, trait_ } => {
+ Id(format!("a:{}-{}", DisplayDefId(trait_), DisplayDefId(for_)))
+ }
+ ItemId::Primitive(ty, krate) => Id(format!("p:{}:{}", krate.as_u32(), ty.as_sym())),
}
}
fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self {
use clean::WherePredicate::*;
match predicate {
- BoundPredicate { ty, bounds } => WherePredicate::BoundPredicate {
+ BoundPredicate { ty, bounds, .. } => WherePredicate::BoundPredicate {
ty: ty.into_tcx(tcx),
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ // FIXME: add `bound_params` to rustdoc-json-params?
},
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
lifetime: lifetime.0.to_string(),
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
use clean::Type::*;
match ty {
- ResolvedPath { path, param_names, did, is_generic: _ } => Type::ResolvedPath {
+ ResolvedPath { path, did, is_generic: _ } => Type::ResolvedPath {
name: path.whole_name(),
- id: from_def_id(did.into()),
+ id: from_item_id(did.into()),
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
- param_names: param_names
- .map(|v| v.into_iter().map(|x| x.into_tcx(tcx)).collect())
- .unwrap_or_default(),
+ param_names: Vec::new(),
},
+ DynTrait(mut bounds, lt) => {
+ let (path, id) = match bounds.remove(0).trait_ {
+ ResolvedPath { path, did, .. } => (path, did),
+ _ => unreachable!(),
+ };
+
+ Type::ResolvedPath {
+ name: path.whole_name(),
+ id: from_item_id(id.into()),
+ args: path
+ .segments
+ .last()
+ .map(|args| Box::new(args.clone().args.into_tcx(tcx))),
+ param_names: bounds
+ .into_iter()
+ .map(|t| {
+ clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None)
+ })
+ .chain(lt.into_iter().map(|lt| clean::GenericBound::Outlives(lt)))
+ .map(|bound| bound.into_tcx(tcx))
+ .collect(),
+ }
+ }
Generic(s) => Type::Generic(s.to_string()),
Primitive(p) => Type::Primitive(p.as_sym().to_string()),
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
Simple(s) => Import {
source: import.source.path.whole_name(),
name: s.to_string(),
- id: import.source.did.map(FakeDefId::from).map(from_def_id),
+ id: import.source.did.map(ItemId::from).map(from_item_id),
glob: false,
},
Glob => Import {
source: import.source.path.whole_name(),
name: import.source.path.last_name().to_string(),
- id: import.source.did.map(FakeDefId::from).map(from_def_id),
+ id: import.source.did.map(ItemId::from).map(from_item_id),
glob: true,
},
}
}
fn ids(items: impl IntoIterator<Item = clean::Item>) -> Vec<Id> {
- items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_def_id(i.def_id)).collect()
+ items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_item_id(i.def_id)).collect()
}