Skip to content

Commit 7f60ee0

Browse files
committed
Refactor clean_qpath into a separate function
1 parent 25a6910 commit 7f60ee0

File tree

1 file changed

+151
-139
lines changed

1 file changed

+151
-139
lines changed

src/librustdoc/clean/mod.rs

+151-139
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,156 @@ impl Clean<Item> for ty::AssocItem {
12831283
}
12841284
}
12851285

1286+
fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
1287+
use rustc_hir::GenericParamCount;
1288+
let hir::Ty { hir_id, span, ref kind } = *hir_ty;
1289+
let qpath = match kind {
1290+
hir::TyKind::Path(qpath) => qpath,
1291+
_ => unreachable!(),
1292+
};
1293+
match qpath {
1294+
hir::QPath::Resolved(None, ref path) => {
1295+
if let Res::Def(DefKind::TyParam, did) = path.res {
1296+
if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() {
1297+
return new_ty;
1298+
}
1299+
if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) {
1300+
return ImplTrait(bounds);
1301+
}
1302+
}
1303+
1304+
let mut alias = None;
1305+
if let Res::Def(DefKind::TyAlias, def_id) = path.res {
1306+
// Substitute private type aliases
1307+
if let Some(def_id) = def_id.as_local() {
1308+
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
1309+
if !cx.renderinfo.borrow().access_levels.is_exported(def_id.to_def_id()) {
1310+
alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
1311+
}
1312+
}
1313+
};
1314+
1315+
if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias {
1316+
let provided_params = &path.segments.last().expect("segments were empty");
1317+
let mut ty_substs = FxHashMap::default();
1318+
let mut lt_substs = FxHashMap::default();
1319+
let mut ct_substs = FxHashMap::default();
1320+
let generic_args = provided_params.generic_args();
1321+
{
1322+
let mut indices: GenericParamCount = Default::default();
1323+
for param in generics.params.iter() {
1324+
match param.kind {
1325+
hir::GenericParamKind::Lifetime { .. } => {
1326+
let mut j = 0;
1327+
let lifetime = generic_args.args.iter().find_map(|arg| match arg {
1328+
hir::GenericArg::Lifetime(lt) => {
1329+
if indices.lifetimes == j {
1330+
return Some(lt);
1331+
}
1332+
j += 1;
1333+
None
1334+
}
1335+
_ => None,
1336+
});
1337+
if let Some(lt) = lifetime.cloned() {
1338+
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1339+
let cleaned = if !lt.is_elided() {
1340+
lt.clean(cx)
1341+
} else {
1342+
self::types::Lifetime::elided()
1343+
};
1344+
lt_substs.insert(lt_def_id.to_def_id(), cleaned);
1345+
}
1346+
indices.lifetimes += 1;
1347+
}
1348+
hir::GenericParamKind::Type { ref default, .. } => {
1349+
let ty_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1350+
let mut j = 0;
1351+
let type_ = generic_args.args.iter().find_map(|arg| match arg {
1352+
hir::GenericArg::Type(ty) => {
1353+
if indices.types == j {
1354+
return Some(ty);
1355+
}
1356+
j += 1;
1357+
None
1358+
}
1359+
_ => None,
1360+
});
1361+
if let Some(ty) = type_ {
1362+
ty_substs.insert(ty_param_def_id.to_def_id(), ty.clean(cx));
1363+
} else if let Some(default) = *default {
1364+
ty_substs
1365+
.insert(ty_param_def_id.to_def_id(), default.clean(cx));
1366+
}
1367+
indices.types += 1;
1368+
}
1369+
hir::GenericParamKind::Const { .. } => {
1370+
let const_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1371+
let mut j = 0;
1372+
let const_ = generic_args.args.iter().find_map(|arg| match arg {
1373+
hir::GenericArg::Const(ct) => {
1374+
if indices.consts == j {
1375+
return Some(ct);
1376+
}
1377+
j += 1;
1378+
None
1379+
}
1380+
_ => None,
1381+
});
1382+
if let Some(ct) = const_ {
1383+
ct_substs.insert(const_param_def_id.to_def_id(), ct.clean(cx));
1384+
}
1385+
// FIXME(const_generics:defaults)
1386+
indices.consts += 1;
1387+
}
1388+
}
1389+
}
1390+
}
1391+
return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
1392+
}
1393+
resolve_type(cx, path.clean(cx), hir_id)
1394+
}
1395+
hir::QPath::Resolved(Some(ref qself), ref p) => {
1396+
let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
1397+
let trait_segments = &segments[..segments.len() - 1];
1398+
let trait_path = self::Path {
1399+
global: p.is_global(),
1400+
res: Res::Def(
1401+
DefKind::Trait,
1402+
cx.tcx.associated_item(p.res.def_id()).container.id(),
1403+
),
1404+
segments: trait_segments.clean(cx),
1405+
};
1406+
Type::QPath {
1407+
name: p.segments.last().expect("segments were empty").ident.name.clean(cx),
1408+
self_type: box qself.clean(cx),
1409+
trait_: box resolve_type(cx, trait_path, hir_id),
1410+
}
1411+
}
1412+
hir::QPath::TypeRelative(ref qself, ref segment) => {
1413+
let mut res = Res::Err;
1414+
/*
1415+
let hir_ty = hir::Ty {
1416+
kind: hir::TyKind::Path((*qpath).clone()),
1417+
hir_id,
1418+
span,
1419+
};
1420+
*/
1421+
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
1422+
if let ty::Projection(proj) = ty.kind() {
1423+
res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
1424+
}
1425+
let trait_path = hir::Path { span, res, segments: &[] };
1426+
Type::QPath {
1427+
name: segment.ident.name.clean(cx),
1428+
self_type: box qself.clean(cx),
1429+
trait_: box resolve_type(cx, trait_path.clean(cx), hir_id),
1430+
}
1431+
}
1432+
hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
1433+
}
1434+
}
1435+
12861436
impl Clean<Type> for hir::Ty<'_> {
12871437
fn clean(&self, cx: &DocContext<'_>) -> Type {
12881438
use rustc_hir::*;
@@ -1318,145 +1468,7 @@ impl Clean<Type> for hir::Ty<'_> {
13181468
unreachable!()
13191469
}
13201470
}
1321-
TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
1322-
if let Res::Def(DefKind::TyParam, did) = path.res {
1323-
if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() {
1324-
return new_ty;
1325-
}
1326-
if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) {
1327-
return ImplTrait(bounds);
1328-
}
1329-
}
1330-
1331-
let mut alias = None;
1332-
if let Res::Def(DefKind::TyAlias, def_id) = path.res {
1333-
// Substitute private type aliases
1334-
if let Some(def_id) = def_id.as_local() {
1335-
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
1336-
if !cx.renderinfo.borrow().access_levels.is_exported(def_id.to_def_id()) {
1337-
alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
1338-
}
1339-
}
1340-
};
1341-
1342-
if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias {
1343-
let provided_params = &path.segments.last().expect("segments were empty");
1344-
let mut ty_substs = FxHashMap::default();
1345-
let mut lt_substs = FxHashMap::default();
1346-
let mut ct_substs = FxHashMap::default();
1347-
let generic_args = provided_params.generic_args();
1348-
{
1349-
let mut indices: GenericParamCount = Default::default();
1350-
for param in generics.params.iter() {
1351-
match param.kind {
1352-
hir::GenericParamKind::Lifetime { .. } => {
1353-
let mut j = 0;
1354-
let lifetime =
1355-
generic_args.args.iter().find_map(|arg| match arg {
1356-
hir::GenericArg::Lifetime(lt) => {
1357-
if indices.lifetimes == j {
1358-
return Some(lt);
1359-
}
1360-
j += 1;
1361-
None
1362-
}
1363-
_ => None,
1364-
});
1365-
if let Some(lt) = lifetime.cloned() {
1366-
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1367-
let cleaned = if !lt.is_elided() {
1368-
lt.clean(cx)
1369-
} else {
1370-
self::types::Lifetime::elided()
1371-
};
1372-
lt_substs.insert(lt_def_id.to_def_id(), cleaned);
1373-
}
1374-
indices.lifetimes += 1;
1375-
}
1376-
hir::GenericParamKind::Type { ref default, .. } => {
1377-
let ty_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1378-
let mut j = 0;
1379-
let type_ =
1380-
generic_args.args.iter().find_map(|arg| match arg {
1381-
hir::GenericArg::Type(ty) => {
1382-
if indices.types == j {
1383-
return Some(ty);
1384-
}
1385-
j += 1;
1386-
None
1387-
}
1388-
_ => None,
1389-
});
1390-
if let Some(ty) = type_ {
1391-
ty_substs.insert(ty_param_def_id.to_def_id(), ty.clean(cx));
1392-
} else if let Some(default) = *default {
1393-
ty_substs
1394-
.insert(ty_param_def_id.to_def_id(), default.clean(cx));
1395-
}
1396-
indices.types += 1;
1397-
}
1398-
hir::GenericParamKind::Const { .. } => {
1399-
let const_param_def_id =
1400-
cx.tcx.hir().local_def_id(param.hir_id);
1401-
let mut j = 0;
1402-
let const_ =
1403-
generic_args.args.iter().find_map(|arg| match arg {
1404-
hir::GenericArg::Const(ct) => {
1405-
if indices.consts == j {
1406-
return Some(ct);
1407-
}
1408-
j += 1;
1409-
None
1410-
}
1411-
_ => None,
1412-
});
1413-
if let Some(ct) = const_ {
1414-
ct_substs
1415-
.insert(const_param_def_id.to_def_id(), ct.clean(cx));
1416-
}
1417-
// FIXME(const_generics:defaults)
1418-
indices.consts += 1;
1419-
}
1420-
}
1421-
}
1422-
}
1423-
return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
1424-
}
1425-
resolve_type(cx, path.clean(cx), self.hir_id)
1426-
}
1427-
TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => {
1428-
let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
1429-
let trait_segments = &segments[..segments.len() - 1];
1430-
let trait_path = self::Path {
1431-
global: p.is_global(),
1432-
res: Res::Def(
1433-
DefKind::Trait,
1434-
cx.tcx.associated_item(p.res.def_id()).container.id(),
1435-
),
1436-
segments: trait_segments.clean(cx),
1437-
};
1438-
Type::QPath {
1439-
name: p.segments.last().expect("segments were empty").ident.name.clean(cx),
1440-
self_type: box qself.clean(cx),
1441-
trait_: box resolve_type(cx, trait_path, self.hir_id),
1442-
}
1443-
}
1444-
TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
1445-
let mut res = Res::Err;
1446-
let ty = hir_ty_to_ty(cx.tcx, self);
1447-
if let ty::Projection(proj) = ty.kind() {
1448-
res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
1449-
}
1450-
let trait_path = hir::Path { span: self.span, res, segments: &[] };
1451-
Type::QPath {
1452-
name: segment.ident.name.clean(cx),
1453-
self_type: box qself.clean(cx),
1454-
trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id),
1455-
}
1456-
}
1457-
TyKind::Path(hir::QPath::LangItem(..)) => {
1458-
bug!("clean: requiring documentation of lang item")
1459-
}
1471+
TyKind::Path(_) => clean_qpath(&self, cx),
14601472
TyKind::TraitObject(ref bounds, ref lifetime) => {
14611473
match bounds[0].clean(cx).trait_ {
14621474
ResolvedPath { path, param_names: None, did, is_generic } => {

0 commit comments

Comments
 (0)