Extract function for expanding private type aliases

This commit is contained in:
Noah Lev 2021-10-30 21:21:35 -07:00
parent 68b554e6af
commit eeb2a6203b

View file

@ -1148,7 +1148,6 @@ impl Clean<Item> for ty::AssocItem {
}
fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
use rustc_hir::GenericParamCount;
let hir::Ty { hir_id: _, span, ref kind } = *hir_ty;
let qpath = match kind {
hir::TyKind::Path(qpath) => qpath,
@ -1166,97 +1165,12 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
}
}
let mut alias = None;
if let Res::Def(DefKind::TyAlias, def_id) = path.res {
// Substitute private type aliases
if let Some(def_id) = def_id.as_local() {
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
if !cx.cache.access_levels.is_exported(def_id.to_def_id()) {
alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
}
}
};
if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias {
let provided_params = &path.segments.last().expect("segments were empty");
let mut ty_substs = FxHashMap::default();
let mut lt_substs = FxHashMap::default();
let mut ct_substs = FxHashMap::default();
let generic_args = provided_params.args();
{
let mut indices: GenericParamCount = Default::default();
for param in generics.params.iter() {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {
let mut j = 0;
let lifetime = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Lifetime(lt) => {
if indices.lifetimes == j {
return Some(lt);
}
j += 1;
None
}
_ => None,
});
if let Some(lt) = lifetime.cloned() {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let cleaned = if !lt.is_elided() {
lt.clean(cx)
} else {
self::types::Lifetime::elided()
};
lt_substs.insert(lt_def_id.to_def_id(), cleaned);
}
indices.lifetimes += 1;
}
hir::GenericParamKind::Type { ref default, .. } => {
let ty_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let mut j = 0;
let type_ = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Type(ty) => {
if indices.types == j {
return Some(ty);
}
j += 1;
None
}
_ => None,
});
if let Some(ty) = type_ {
ty_substs.insert(ty_param_def_id.to_def_id(), ty.clean(cx));
} else if let Some(default) = *default {
ty_substs
.insert(ty_param_def_id.to_def_id(), default.clean(cx));
}
indices.types += 1;
}
hir::GenericParamKind::Const { .. } => {
let const_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let mut j = 0;
let const_ = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Const(ct) => {
if indices.consts == j {
return Some(ct);
}
j += 1;
None
}
_ => None,
});
if let Some(ct) = const_ {
ct_substs.insert(const_param_def_id.to_def_id(), ct.clean(cx));
}
// FIXME(const_generics_defaults)
indices.consts += 1;
}
}
}
}
return cx.enter_alias(ty_substs, lt_substs, ct_substs, |cx| ty.clean(cx));
if let Some(expanded) = maybe_expand_private_type_alias(cx, path) {
expanded
} else {
let path = path.clean(cx);
resolve_type(cx, path)
}
let path = path.clean(cx);
resolve_type(cx, path)
}
hir::QPath::Resolved(Some(ref qself), p) => {
// Try to normalize `<X as Y>::T` to a type
@ -1300,6 +1214,99 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
}
}
fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>) -> Option<Type> {
let mut alias = None;
if let Res::Def(DefKind::TyAlias, def_id) = path.res {
// Substitute private type aliases
if let Some(def_id) = def_id.as_local() {
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
if !cx.cache.access_levels.is_exported(def_id.to_def_id()) {
alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
}
}
};
if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias {
let provided_params = &path.segments.last().expect("segments were empty");
let mut ty_substs = FxHashMap::default();
let mut lt_substs = FxHashMap::default();
let mut ct_substs = FxHashMap::default();
let generic_args = provided_params.args();
{
let mut indices: hir::GenericParamCount = Default::default();
for param in generics.params.iter() {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {
let mut j = 0;
let lifetime = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Lifetime(lt) => {
if indices.lifetimes == j {
return Some(lt);
}
j += 1;
None
}
_ => None,
});
if let Some(lt) = lifetime.cloned() {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let cleaned = if !lt.is_elided() {
lt.clean(cx)
} else {
self::types::Lifetime::elided()
};
lt_substs.insert(lt_def_id.to_def_id(), cleaned);
}
indices.lifetimes += 1;
}
hir::GenericParamKind::Type { ref default, .. } => {
let ty_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let mut j = 0;
let type_ = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Type(ty) => {
if indices.types == j {
return Some(ty);
}
j += 1;
None
}
_ => None,
});
if let Some(ty) = type_ {
ty_substs.insert(ty_param_def_id.to_def_id(), ty.clean(cx));
} else if let Some(default) = *default {
ty_substs.insert(ty_param_def_id.to_def_id(), default.clean(cx));
}
indices.types += 1;
}
hir::GenericParamKind::Const { .. } => {
let const_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let mut j = 0;
let const_ = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Const(ct) => {
if indices.consts == j {
return Some(ct);
}
j += 1;
None
}
_ => None,
});
if let Some(ct) = const_ {
ct_substs.insert(const_param_def_id.to_def_id(), ct.clean(cx));
}
// FIXME(const_generics_defaults)
indices.consts += 1;
}
}
}
}
Some(cx.enter_alias(ty_substs, lt_substs, ct_substs, |cx| ty.clean(cx)))
} else {
None
}
}
impl Clean<Type> for hir::Ty<'_> {
fn clean(&self, cx: &mut DocContext<'_>) -> Type {
use rustc_hir::*;