diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 508407144c2..93bce10a2d6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -222,7 +222,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime { | rl::Region::Free(_, node_id), ) = def { - if let Some(lt) = cx.lt_substs.get(&node_id).cloned() { + if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() { return lt; } } @@ -1157,7 +1157,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { match qpath { hir::QPath::Resolved(None, ref path) => { if let Res::Def(DefKind::TyParam, did) = path.res { - if let Some(new_ty) = cx.ty_substs.get(&did).cloned() { + if let Some(new_ty) = cx.substs.get(&did).and_then(|p| p.as_ty()).cloned() { return new_ty; } if let Some(bounds) = cx.impl_trait_bounds.remove(&did.into()) { @@ -1227,9 +1227,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_> let hir::ItemKind::TyAlias(ty, generics) = alias else { return None }; 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 mut substs = FxHashMap::default(); let generic_args = provided_params.args(); let mut indices: hir::GenericParamCount = Default::default(); @@ -1254,7 +1252,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_> } else { self::types::Lifetime::elided() }; - lt_substs.insert(lt_def_id.to_def_id(), cleaned); + substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned)); } indices.lifetimes += 1; } @@ -1272,9 +1270,9 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_> _ => None, }); if let Some(ty) = type_ { - ty_substs.insert(ty_param_def_id.to_def_id(), ty.clean(cx)); + substs.insert(ty_param_def_id.to_def_id(), SubstParam::Type(ty.clean(cx))); } else if let Some(default) = *default { - ty_substs.insert(ty_param_def_id.to_def_id(), default.clean(cx)); + substs.insert(ty_param_def_id.to_def_id(), SubstParam::Type(default.clean(cx))); } indices.types += 1; } @@ -1292,7 +1290,8 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_> _ => None, }); if let Some(ct) = const_ { - ct_substs.insert(const_param_def_id.to_def_id(), ct.clean(cx)); + substs + .insert(const_param_def_id.to_def_id(), SubstParam::Constant(ct.clean(cx))); } // FIXME(const_generics_defaults) indices.consts += 1; @@ -1300,7 +1299,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_> } } - Some(cx.enter_alias(ty_substs, lt_substs, ct_substs, |cx| ty.clean(cx))) + Some(cx.enter_alias(substs, |cx| ty.clean(cx))) } impl Clean for hir::Ty<'_> { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 88fffaecb93..e91d0aa839d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2247,3 +2247,32 @@ impl TypeBinding { } } } + +/// The type, lifetime, or constant that a private type alias's parameter should be +/// replaced with when expanding a use of that type alias. +/// +/// For example: +/// +/// ``` +/// type PrivAlias = Vec; +/// +/// pub fn public_fn() -> PrivAlias { vec![] } +/// ``` +/// +/// `public_fn`'s docs will show it as returning `Vec`, since `PrivAlias` is private. +/// [`SubstParam`] is used to record that `T` should be mapped to `i32`. +crate enum SubstParam { + Type(Type), + Lifetime(Lifetime), + Constant(Constant), +} + +impl SubstParam { + crate fn as_ty(&self) -> Option<&Type> { + if let Self::Type(ty) = self { Some(ty) } else { None } + } + + crate fn as_lt(&self) -> Option<&Lifetime> { + if let Self::Lifetime(lt) = self { Some(lt) } else { None } + } +} diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b7251e8f571..7fa6484d238 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -54,14 +54,10 @@ /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. crate active_extern_traits: FxHashSet, - // The current set of type and lifetime substitutions, + // The current set of parameter substitutions, // for expanding type aliases at the HIR level: - /// Table `DefId` of type parameter -> substituted type - crate ty_substs: FxHashMap, - /// Table `DefId` of lifetime parameter -> substituted lifetime - crate lt_substs: FxHashMap, - /// Table `DefId` of const parameter -> substituted const - crate ct_substs: FxHashMap, + /// Table `DefId` of type, lifetime, or const parameter -> substituted type, lifetime, or const + crate substs: FxHashMap, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds crate impl_trait_bounds: FxHashMap>, /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. @@ -104,25 +100,13 @@ impl<'tcx> DocContext<'tcx> { /// Call the closure with the given parameters set as /// the substitutions for a type alias' RHS. - crate fn enter_alias( - &mut self, - ty_substs: FxHashMap, - lt_substs: FxHashMap, - ct_substs: FxHashMap, - f: F, - ) -> R + crate fn enter_alias(&mut self, substs: FxHashMap, f: F) -> R where F: FnOnce(&mut Self) -> R, { - let (old_tys, old_lts, old_cts) = ( - mem::replace(&mut self.ty_substs, ty_substs), - mem::replace(&mut self.lt_substs, lt_substs), - mem::replace(&mut self.ct_substs, ct_substs), - ); + let old_substs = mem::replace(&mut self.substs, substs); let r = f(self); - self.ty_substs = old_tys; - self.lt_substs = old_lts; - self.ct_substs = old_cts; + self.substs = old_substs; r } @@ -350,9 +334,7 @@ impl<'tcx> DocContext<'tcx> { param_env: ParamEnv::empty(), external_traits: Default::default(), active_extern_traits: Default::default(), - ty_substs: Default::default(), - lt_substs: Default::default(), - ct_substs: Default::default(), + substs: Default::default(), impl_trait_bounds: Default::default(), generated_synthetics: Default::default(), auto_traits: tcx