Skip to content

Commit 55bef83

Browse files
authored
Rollup merge of rust-lang#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
2 parents d567d95 + 9c43789 commit 55bef83

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

src/librustdoc/json/conversions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,10 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
335335
Lifetime { outlives } => GenericParamDefKind::Lifetime {
336336
outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(),
337337
},
338-
Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type {
338+
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
339339
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
340340
default: default.map(|x| (*x).into_tcx(tcx)),
341+
synthetic,
341342
},
342343
Const { did: _, ty, default } => {
343344
GenericParamDefKind::Const { ty: (*ty).into_tcx(tcx), default: default.map(|x| *x) }

src/rustdoc-json-types/lib.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::path::PathBuf;
99
use serde::{Deserialize, Serialize};
1010

1111
/// rustdoc format-version.
12-
pub const FORMAT_VERSION: u32 = 11;
12+
pub const FORMAT_VERSION: u32 = 12;
1313

1414
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
1515
/// about the language items in the local crate, as well as info about external items to allow
@@ -344,9 +344,41 @@ pub struct GenericParamDef {
344344
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
345345
#[serde(rename_all = "snake_case")]
346346
pub enum GenericParamDefKind {
347-
Lifetime { outlives: Vec<String> },
348-
Type { bounds: Vec<GenericBound>, default: Option<Type> },
349-
Const { ty: Type, default: Option<String> },
347+
Lifetime {
348+
outlives: Vec<String>,
349+
},
350+
Type {
351+
bounds: Vec<GenericBound>,
352+
default: Option<Type>,
353+
/// This is normally `false`, which means that this generic parameter is
354+
/// declared in the Rust source text.
355+
///
356+
/// If it is `true`, this generic parameter has been introduced by the
357+
/// compiler behind the scenes.
358+
///
359+
/// # Example
360+
///
361+
/// Consider
362+
///
363+
/// ```ignore (pseudo-rust)
364+
/// pub fn f(_: impl Trait) {}
365+
/// ```
366+
///
367+
/// The compiler will transform this behind the scenes to
368+
///
369+
/// ```ignore (pseudo-rust)
370+
/// pub fn f<impl Trait: Trait>(_: impl Trait) {}
371+
/// ```
372+
///
373+
/// In this example, the generic parameter named `impl Trait` (and which
374+
/// is bound by `Trait`) is synthetic, because it was not originally in
375+
/// the Rust source text.
376+
synthetic: bool,
377+
},
378+
Const {
379+
ty: Type,
380+
default: Option<String>,
381+
},
350382
}
351383

352384
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]

src/test/rustdoc-json/fns/generics.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// ignore-tidy-linelength
2+
3+
#![feature(no_core)]
4+
#![no_core]
5+
6+
// @set wham_id = generics.json "$.index[*][?(@.name=='Wham')].id"
7+
pub trait Wham {}
8+
9+
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
10+
// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
11+
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
12+
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
13+
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
14+
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
15+
pub fn one_generic_param_fn<T: Wham>(w: T) {}
16+
17+
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
18+
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
19+
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
20+
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
21+
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
22+
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
23+
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
24+
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
25+
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
26+
pub fn one_synthetic_generic_param_fn(w: impl Wham) {}

0 commit comments

Comments
 (0)