Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make precise capturing args in rustdoc Json typed #138109

Merged
merged 1 commit into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3368,13 +3368,16 @@ pub struct OpaqueTy<'hir> {
pub span: Span,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum PreciseCapturingArg<'hir> {
Lifetime(&'hir Lifetime),
#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
pub enum PreciseCapturingArgKind<T, U> {
Lifetime(T),
/// Non-lifetime argument (type or const)
Param(PreciseCapturingNonLifetimeArg),
Param(U),
}

pub type PreciseCapturingArg<'hir> =
PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;

impl PreciseCapturingArg<'_> {
pub fn hir_id(self) -> HirId {
match self {
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_errors::{
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
use rustc_hir::{self as hir, GenericParamKind, HirId, Node};
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter;
Expand Down Expand Up @@ -1792,7 +1792,7 @@ fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueT
fn rendered_precise_capturing_args<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> Option<&'tcx [Symbol]> {
) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
if let Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
tcx.opt_rpitit_info(def_id.to_def_id())
{
Expand All @@ -1801,7 +1801,12 @@ fn rendered_precise_capturing_args<'tcx>(

tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
hir::GenericBound::Use(args, ..) => {
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| match arg {
PreciseCapturingArgKind::Lifetime(_) => {
PreciseCapturingArgKind::Lifetime(arg.name())
}
PreciseCapturingArgKind::Param(_) => PreciseCapturingArgKind::Param(arg.name()),
})))
}
_ => None,
})
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_abi::{FieldIdx, ReprOptions, VariantIdx};
use rustc_ast::expand::StrippedCfgItem;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::svh::Svh;
use rustc_hir::PreciseCapturingArgKind;
use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, StableCrateId};
use rustc_hir::definitions::DefKey;
Expand Down Expand Up @@ -440,7 +441,7 @@ define_tables! {
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,
rendered_const: Table<DefIndex, LazyValue<String>>,
rendered_precise_capturing_args: Table<DefIndex, LazyArray<Symbol>>,
rendered_precise_capturing_args: Table<DefIndex, LazyArray<PreciseCapturingArgKind<Symbol, Symbol>>>,
asyncness: Table<DefIndex, ty::Asyncness>,
fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_hir::def_id::{
CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId,
};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate};
use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate};
use rustc_index::IndexVec;
use rustc_lint_defs::LintId;
use rustc_macros::rustc_queries;
Expand Down Expand Up @@ -1430,7 +1430,7 @@ rustc_queries! {
}

/// Gets the rendered precise capturing args for an opaque for use in rustdoc.
query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [Symbol]> {
query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
desc { |tcx| "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/parameterized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::hash::Hash;
use rustc_data_structures::unord::UnordMap;
use rustc_hir::def_id::DefIndex;
use rustc_index::{Idx, IndexVec};
use rustc_span::Symbol;

use crate::ty;

Expand Down Expand Up @@ -96,6 +97,7 @@ trivially_parameterized_over_tcx! {
rustc_hir::def_id::DefIndex,
rustc_hir::definitions::DefKey,
rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
rustc_hir::PreciseCapturingArgKind<Symbol, Symbol>,
rustc_index::bit_set::DenseBitSet<u32>,
rustc_index::bit_set::FiniteBitSet<u32>,
rustc_session::cstore::ForeignModule,
Expand Down
27 changes: 25 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ fn clean_generic_bound<'tcx>(
GenericBound::TraitBound(clean_poly_trait_ref(t, cx), t.modifiers)
}
hir::GenericBound::Use(args, ..) => {
GenericBound::Use(args.iter().map(|arg| arg.name()).collect())
GenericBound::Use(args.iter().map(|arg| clean_precise_capturing_arg(arg, cx)).collect())
}
})
}
Expand Down Expand Up @@ -286,6 +286,18 @@ fn clean_lifetime(lifetime: &hir::Lifetime, cx: &DocContext<'_>) -> Lifetime {
Lifetime(lifetime.ident.name)
}

pub(crate) fn clean_precise_capturing_arg(
arg: &hir::PreciseCapturingArg<'_>,
cx: &DocContext<'_>,
) -> PreciseCapturingArg {
match arg {
hir::PreciseCapturingArg::Lifetime(lt) => {
PreciseCapturingArg::Lifetime(clean_lifetime(lt, cx))
}
hir::PreciseCapturingArg::Param(param) => PreciseCapturingArg::Param(param.ident.name),
}
}

pub(crate) fn clean_const<'tcx>(
constant: &hir::ConstArg<'tcx>,
_cx: &mut DocContext<'tcx>,
Expand Down Expand Up @@ -2364,7 +2376,18 @@ fn clean_middle_opaque_bounds<'tcx>(
}

if let Some(args) = cx.tcx.rendered_precise_capturing_args(impl_trait_def_id) {
bounds.push(GenericBound::Use(args.to_vec()));
bounds.push(GenericBound::Use(
args.iter()
.map(|arg| match arg {
hir::PreciseCapturingArgKind::Lifetime(lt) => {
PreciseCapturingArg::Lifetime(Lifetime(*lt))
}
hir::PreciseCapturingArgKind::Param(param) => {
PreciseCapturingArg::Param(*param)
}
})
.collect(),
));
}

ImplTrait(bounds)
Expand Down
17 changes: 16 additions & 1 deletion src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ pub(crate) enum GenericBound {
TraitBound(PolyTrait, hir::TraitBoundModifiers),
Outlives(Lifetime),
/// `use<'a, T>` precise-capturing bound syntax
Use(Vec<Symbol>),
Use(Vec<PreciseCapturingArg>),
}

impl GenericBound {
Expand Down Expand Up @@ -1304,6 +1304,21 @@ impl Lifetime {
}
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub(crate) enum PreciseCapturingArg {
Lifetime(Lifetime),
Param(Symbol),
}

impl PreciseCapturingArg {
pub(crate) fn name(self) -> Symbol {
match self {
PreciseCapturingArg::Lifetime(lt) => lt.0,
PreciseCapturingArg::Param(param) => param,
}
}
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub(crate) enum WherePredicate {
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<GenericParamDef> },
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl clean::GenericBound {
} else {
f.write_str("use&lt;")?;
}
args.iter().joined(", ", f)?;
args.iter().map(|arg| arg.name()).joined(", ", f)?;
if f.alternate() { f.write_str(">") } else { f.write_str("&gt;") }
}
})
Expand Down
13 changes: 12 additions & 1 deletion src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,18 @@ impl FromClean<clean::GenericBound> for GenericBound {
}
}
Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
Use(args) => GenericBound::Use(args.into_iter().map(|arg| arg.to_string()).collect()),
Use(args) => GenericBound::Use(
args.iter()
.map(|arg| match arg {
clean::PreciseCapturingArg::Lifetime(lt) => {
PreciseCapturingArg::Lifetime(convert_lifetime(*lt))
}
clean::PreciseCapturingArg::Param(param) => {
PreciseCapturingArg::Param(param.to_string())
}
})
.collect(),
),
}
}
}
Expand Down
20 changes: 18 additions & 2 deletions src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
/// This integer is incremented with every breaking change to the API,
/// and is returned along with the JSON blob as [`Crate::format_version`].
/// Consuming code should assert that this value matches the format version(s) that it supports.
pub const FORMAT_VERSION: u32 = 40;
pub const FORMAT_VERSION: u32 = 41;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is taking place at the same time as #137956, which also (currently) makes the 40->41 change. Once one of these merges, the other should rebase then bump again. See #94591 for details.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: This PR is gonna do 40->41, others will need to be rebased after this lands.


/// The root of the emitted JSON blob.
///
Expand Down Expand Up @@ -909,7 +909,7 @@ pub enum GenericBound {
/// ```
Outlives(String),
/// `use<'a, T>` precise-capturing bound syntax
Use(Vec<String>),
Use(Vec<PreciseCapturingArg>),
}

/// A set of modifiers applied to a trait.
Expand All @@ -927,6 +927,22 @@ pub enum TraitBoundModifier {
MaybeConst,
}

/// One precise capturing argument. See [the rust reference](https://doc.rust-lang.org/reference/types/impl-trait.html#precise-capturing).
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PreciseCapturingArg {
/// A lifetime.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should give an example here, eg:

pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
//                                                        ^^

/// ```rust
/// pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
/// // ^^
Lifetime(String),
/// A type or constant parameter.
/// ```rust
/// pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
/// // ^ ^
Param(String),
}

/// Either a type or a constant, usually stored as the right-hand side of an equation in places like
/// [`AssocItemConstraint`]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
Expand Down
6 changes: 3 additions & 3 deletions tests/rustdoc-json/impl-trait-precise-capturing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[0]" \"\'a\"
//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[1]" \"T\"
//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[2]" \"N\"
//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[0].lifetime" \"\'a\"
//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[1].param" \"T\"
//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[2].param" \"N\"
pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
Loading