summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/clean/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/clean/utils.rs')
-rw-r--r--src/librustdoc/clean/utils.rs59
1 files changed, 35 insertions, 24 deletions
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 366f93952..b786ecbe3 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -21,6 +21,7 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_span::symbol::{kw, sym, Symbol};
use std::fmt::Write as _;
use std::mem;
+use std::sync::LazyLock as Lazy;
use thin_vec::{thin_vec, ThinVec};
#[cfg(test)]
@@ -53,8 +54,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
let primitives = local_crate.primitives(cx.tcx);
let keywords = local_crate.keywords(cx.tcx);
{
- let ItemKind::ModuleItem(ref mut m) = *module.kind
- else { unreachable!() };
+ let ItemKind::ModuleItem(ref mut m) = *module.kind else { unreachable!() };
m.items.extend(primitives.iter().map(|&(def_id, prim)| {
Item::from_def_id_and_parts(
def_id,
@@ -73,28 +73,37 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
pub(crate) fn substs_to_args<'tcx>(
cx: &mut DocContext<'tcx>,
- substs: ty::Binder<'tcx, &[ty::subst::GenericArg<'tcx>]>,
- mut skip_first: bool,
+ args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
+ has_self: bool,
+ container: Option<DefId>,
) -> Vec<GenericArg> {
+ let mut skip_first = has_self;
let mut ret_val =
- Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
- 1
- } else {
- 0
- }));
- ret_val.extend(substs.iter().filter_map(|kind| match kind.skip_binder().unpack() {
- GenericArgKind::Lifetime(lt) => {
- Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
- }
- GenericArgKind::Type(_) if skip_first => {
- skip_first = false;
- None
- }
- GenericArgKind::Type(ty) => {
- Some(GenericArg::Type(clean_middle_ty(kind.rebind(ty), cx, None)))
- }
- GenericArgKind::Const(ct) => {
- Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
+ Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));
+
+ ret_val.extend(args.iter().enumerate().filter_map(|(index, kind)| {
+ match kind.skip_binder().unpack() {
+ GenericArgKind::Lifetime(lt) => {
+ Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
+ }
+ GenericArgKind::Type(_) if skip_first => {
+ skip_first = false;
+ None
+ }
+ GenericArgKind::Type(ty) => Some(GenericArg::Type(clean_middle_ty(
+ kind.rebind(ty),
+ cx,
+ None,
+ container.map(|container| crate::clean::ContainerTy::Regular {
+ ty: container,
+ args,
+ has_self,
+ arg: index,
+ }),
+ ))),
+ GenericArgKind::Const(ct) => {
+ Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
+ }
}
}));
ret_val
@@ -107,7 +116,7 @@ fn external_generic_args<'tcx>(
bindings: ThinVec<TypeBinding>,
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
) -> GenericArgs {
- let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self);
+ let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self, Some(did));
if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
let ty = substs
@@ -118,7 +127,7 @@ fn external_generic_args<'tcx>(
let inputs =
// The trait's first substitution is the one after self, if there is one.
match ty.skip_binder().kind() {
- ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None)).collect::<Vec<_>>().into(),
+ ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
};
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
@@ -571,6 +580,8 @@ pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
///
/// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
pub(crate) const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
+pub(crate) static DOC_CHANNEL: Lazy<&'static str> =
+ Lazy::new(|| DOC_RUST_LANG_ORG_CHANNEL.rsplit("/").filter(|c| !c.is_empty()).next().unwrap());
/// Render a sequence of macro arms in a format suitable for displaying to the user
/// as part of an item declaration.