Rollup merge of #94150 - Enselic:synthetic-generic-parameters-in-json, r=CraftSpider
rustdoc-json: Include GenericParamDefKind::Type::synthetic in JSON The rustdoc JSON for ``` pub fn f(_: impl Clone) {} ``` will effectively be ``` pub fn f<impl Clone: Clone>(_: impl Clone) {} ``` where a synthetic generic parameter called `impl Clone` with generic trait bound `Clone` is added to the function declaration. The generated HTML filters out these generic parameters by doing `self.params.iter().filter(|p| !p.is_synthetic_type_param())`, because the synthetic generic paramter is not of interest to regular users. For the same reason, we should expose whether or not a generic parameter is synthetic or not also in the rustdoc JSON, so that rustdoc JSON clients can also have the option to hide syntehtic generic parameters. `@rustbot` modify labels: +A-rustdoc-json
This commit is contained in:
commit
27e674d9e9
@ -340,9 +340,10 @@ fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self {
|
||||
Lifetime { outlives } => GenericParamDefKind::Lifetime {
|
||||
outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(),
|
||||
},
|
||||
Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type {
|
||||
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
|
||||
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
|
||||
default: default.map(|x| (*x).into_tcx(tcx)),
|
||||
synthetic,
|
||||
},
|
||||
Const { did: _, ty, default } => {
|
||||
GenericParamDefKind::Const { ty: (*ty).into_tcx(tcx), default: default.map(|x| *x) }
|
||||
|
@ -9,7 +9,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// rustdoc format-version.
|
||||
pub const FORMAT_VERSION: u32 = 12;
|
||||
pub const FORMAT_VERSION: u32 = 13;
|
||||
|
||||
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
|
||||
/// about the language items in the local crate, as well as info about external items to allow
|
||||
@ -346,9 +346,41 @@ pub struct GenericParamDef {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenericParamDefKind {
|
||||
Lifetime { outlives: Vec<String> },
|
||||
Type { bounds: Vec<GenericBound>, default: Option<Type> },
|
||||
Const { ty: Type, default: Option<String> },
|
||||
Lifetime {
|
||||
outlives: Vec<String>,
|
||||
},
|
||||
Type {
|
||||
bounds: Vec<GenericBound>,
|
||||
default: Option<Type>,
|
||||
/// This is normally `false`, which means that this generic parameter is
|
||||
/// declared in the Rust source text.
|
||||
///
|
||||
/// If it is `true`, this generic parameter has been introduced by the
|
||||
/// compiler behind the scenes.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Consider
|
||||
///
|
||||
/// ```ignore (pseudo-rust)
|
||||
/// pub fn f(_: impl Trait) {}
|
||||
/// ```
|
||||
///
|
||||
/// The compiler will transform this behind the scenes to
|
||||
///
|
||||
/// ```ignore (pseudo-rust)
|
||||
/// pub fn f<impl Trait: Trait>(_: impl Trait) {}
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the generic parameter named `impl Trait` (and which
|
||||
/// is bound by `Trait`) is synthetic, because it was not originally in
|
||||
/// the Rust source text.
|
||||
synthetic: bool,
|
||||
},
|
||||
Const {
|
||||
ty: Type,
|
||||
default: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
|
26
src/test/rustdoc-json/fns/generics.rs
Normal file
26
src/test/rustdoc-json/fns/generics.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_core]
|
||||
|
||||
// @set wham_id = generics.json "$.index[*][?(@.name=='Wham')].id"
|
||||
pub trait Wham {}
|
||||
|
||||
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
|
||||
// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
|
||||
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
|
||||
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
|
||||
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
|
||||
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
|
||||
pub fn one_generic_param_fn<T: Wham>(w: T) {}
|
||||
|
||||
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
|
||||
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
|
||||
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
|
||||
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
|
||||
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
|
||||
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
|
||||
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
|
||||
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
|
||||
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
|
||||
pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
|
Loading…
Reference in New Issue
Block a user