Skip to content

Commit e41be25

Browse files
authored
Rollup merge of rust-lang#99787 - aDotInTheVoid:rdj-dyn, r=camelid,notriddle,GuillaumeGomez
Rustdoc-Json: Document HRTB's on DynTrait Closes rust-lang#99118 Probably best reviewed commit by commit. `@rustbot` modify labels: +A-rustdoc-json cc `@Enselic` r? `@CraftSpider`
2 parents 1dc4858 + 6290f92 commit e41be25

File tree

5 files changed

+159
-77
lines changed

5 files changed

+159
-77
lines changed

src/etc/check_missing_items.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ def check_type(ty):
8888
for bound in binding["binding"]["constraint"]:
8989
check_generic_bound(bound)
9090
elif "parenthesized" in args:
91-
for ty in args["parenthesized"]["inputs"]:
92-
check_type(ty)
91+
for input_ty in args["parenthesized"]["inputs"]:
92+
check_type(input_ty)
9393
if args["parenthesized"]["output"]:
9494
check_type(args["parenthesized"]["output"])
9595
if not valid_id(ty["inner"]["id"]):

src/librustdoc/json/conversions.rs

+59-61
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ where
119119
}
120120
}
121121

122+
impl<I, T, U> FromWithTcx<I> for Vec<U>
123+
where
124+
I: IntoIterator<Item = T>,
125+
U: FromWithTcx<T>,
126+
{
127+
fn from_tcx(f: I, tcx: TyCtxt<'_>) -> Vec<U> {
128+
f.into_iter().map(|x| x.into_tcx(tcx)).collect()
129+
}
130+
}
131+
122132
pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
123133
#[rustfmt::skip]
124134
let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
@@ -130,11 +140,11 @@ impl FromWithTcx<clean::GenericArgs> for GenericArgs {
130140
use clean::GenericArgs::*;
131141
match args {
132142
AngleBracketed { args, bindings } => GenericArgs::AngleBracketed {
133-
args: args.into_vec().into_iter().map(|a| a.into_tcx(tcx)).collect(),
134-
bindings: bindings.into_iter().map(|a| a.into_tcx(tcx)).collect(),
143+
args: args.into_vec().into_tcx(tcx),
144+
bindings: bindings.into_tcx(tcx),
135145
},
136146
Parenthesized { inputs, output } => GenericArgs::Parenthesized {
137-
inputs: inputs.into_vec().into_iter().map(|a| a.into_tcx(tcx)).collect(),
147+
inputs: inputs.into_vec().into_tcx(tcx),
138148
output: output.map(|a| (*a).into_tcx(tcx)),
139149
},
140150
}
@@ -145,7 +155,7 @@ impl FromWithTcx<clean::GenericArg> for GenericArg {
145155
fn from_tcx(arg: clean::GenericArg, tcx: TyCtxt<'_>) -> Self {
146156
use clean::GenericArg::*;
147157
match arg {
148-
Lifetime(l) => GenericArg::Lifetime(l.0.to_string()),
158+
Lifetime(l) => GenericArg::Lifetime(convert_lifetime(l)),
149159
Type(t) => GenericArg::Type(t.into_tcx(tcx)),
150160
Const(box c) => GenericArg::Const(c.into_tcx(tcx)),
151161
Infer => GenericArg::Infer,
@@ -177,9 +187,7 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
177187
use clean::TypeBindingKind::*;
178188
match kind {
179189
Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)),
180-
Constraint { bounds } => {
181-
TypeBindingKind::Constraint(bounds.into_iter().map(|a| a.into_tcx(tcx)).collect())
182-
}
190+
Constraint { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
183191
}
184192
}
185193
}
@@ -244,7 +252,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
244252
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
245253
MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, header.unwrap(), tcx)),
246254
TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, header.unwrap(), tcx)),
247-
ImplItem(i) => ItemEnum::Impl(i.into_tcx(tcx)),
255+
ImplItem(i) => ItemEnum::Impl((*i).into_tcx(tcx)),
248256
StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
249257
ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
250258
ForeignTypeItem => ItemEnum::ForeignType,
@@ -260,12 +268,12 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
260268
}
261269
TyAssocTypeItem(g, b) => ItemEnum::AssocType {
262270
generics: (*g).into_tcx(tcx),
263-
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
271+
bounds: b.into_tcx(tcx),
264272
default: None,
265273
},
266274
AssocTypeItem(t, b) => ItemEnum::AssocType {
267275
generics: t.generics.into_tcx(tcx),
268-
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
276+
bounds: b.into_tcx(tcx),
269277
default: Some(t.item_type.unwrap_or(t.type_).into_tcx(tcx)),
270278
},
271279
// `convert_item` early returns `None` for stripped items and keywords.
@@ -347,15 +355,15 @@ fn convert_abi(a: RustcAbi) -> Abi {
347355
}
348356
}
349357

358+
fn convert_lifetime(l: clean::Lifetime) -> String {
359+
l.0.to_string()
360+
}
361+
350362
impl FromWithTcx<clean::Generics> for Generics {
351363
fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self {
352364
Generics {
353-
params: generics.params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
354-
where_predicates: generics
355-
.where_predicates
356-
.into_iter()
357-
.map(|x| x.into_tcx(tcx))
358-
.collect(),
365+
params: generics.params.into_tcx(tcx),
366+
where_predicates: generics.where_predicates.into_tcx(tcx),
359367
}
360368
}
361369
}
@@ -374,10 +382,10 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
374382
use clean::GenericParamDefKind::*;
375383
match kind {
376384
Lifetime { outlives } => GenericParamDefKind::Lifetime {
377-
outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(),
385+
outlives: outlives.into_iter().map(convert_lifetime).collect(),
378386
},
379387
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
380-
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
388+
bounds: bounds.into_tcx(tcx),
381389
default: default.map(|x| (*x).into_tcx(tcx)),
382390
synthetic,
383391
},
@@ -395,7 +403,7 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
395403
match predicate {
396404
BoundPredicate { ty, bounds, bound_params } => WherePredicate::BoundPredicate {
397405
type_: ty.into_tcx(tcx),
398-
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
406+
bounds: bounds.into_tcx(tcx),
399407
generic_params: bound_params
400408
.into_iter()
401409
.map(|x| GenericParamDef {
@@ -405,8 +413,8 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
405413
.collect(),
406414
},
407415
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
408-
lifetime: lifetime.0.to_string(),
409-
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
416+
lifetime: convert_lifetime(lifetime),
417+
bounds: bounds.into_tcx(tcx),
410418
},
411419
EqPredicate { lhs, rhs } => {
412420
WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) }
@@ -424,11 +432,11 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
424432
let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
425433
GenericBound::TraitBound {
426434
trait_,
427-
generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
435+
generic_params: generic_params.into_tcx(tcx),
428436
modifier: from_trait_bound_modifier(modifier),
429437
}
430438
}
431-
Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()),
439+
Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
432440
}
433441
}
434442
}
@@ -447,8 +455,8 @@ pub(crate) fn from_trait_bound_modifier(
447455
impl FromWithTcx<clean::Type> for Type {
448456
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
449457
use clean::Type::{
450-
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive,
451-
QPath, RawPointer, Slice, Tuple,
458+
Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
459+
RawPointer, Slice, Tuple,
452460
};
453461

454462
match ty {
@@ -458,40 +466,24 @@ impl FromWithTcx<clean::Type> for Type {
458466
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
459467
param_names: Vec::new(),
460468
},
461-
DynTrait(mut bounds, lt) => {
462-
let first_trait = bounds.remove(0).trait_;
463-
464-
Type::ResolvedPath {
465-
name: first_trait.whole_name(),
466-
id: from_item_id(first_trait.def_id().into(), tcx),
467-
args: first_trait
468-
.segments
469-
.last()
470-
.map(|args| Box::new(args.clone().args.into_tcx(tcx))),
471-
param_names: bounds
472-
.into_iter()
473-
.map(|t| {
474-
clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None)
475-
})
476-
.chain(lt.map(clean::GenericBound::Outlives))
477-
.map(|bound| bound.into_tcx(tcx))
478-
.collect(),
479-
}
480-
}
469+
clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
470+
lifetime: lt.map(convert_lifetime),
471+
traits: bounds.into_tcx(tcx),
472+
}),
481473
Generic(s) => Type::Generic(s.to_string()),
482474
Primitive(p) => Type::Primitive(p.as_sym().to_string()),
483475
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
484-
Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
476+
Tuple(t) => Type::Tuple(t.into_tcx(tcx)),
485477
Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))),
486478
Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s },
487-
ImplTrait(g) => Type::ImplTrait(g.into_iter().map(|x| x.into_tcx(tcx)).collect()),
479+
ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)),
488480
Infer => Type::Infer,
489481
RawPointer(mutability, type_) => Type::RawPointer {
490482
mutable: mutability == ast::Mutability::Mut,
491483
type_: Box::new((*type_).into_tcx(tcx)),
492484
},
493485
BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef {
494-
lifetime: lifetime.map(|l| l.0.to_string()),
486+
lifetime: lifetime.map(convert_lifetime),
495487
mutable: mutability == ast::Mutability::Mut,
496488
type_: Box::new((*type_).into_tcx(tcx)),
497489
},
@@ -528,7 +520,7 @@ impl FromWithTcx<clean::BareFunctionDecl> for FunctionPointer {
528520
async_: false,
529521
abi: convert_abi(abi),
530522
},
531-
generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
523+
generic_params: generic_params.into_tcx(tcx),
532524
decl: decl.into_tcx(tcx),
533525
}
534526
}
@@ -562,16 +554,28 @@ impl FromWithTcx<clean::Trait> for Trait {
562554
is_unsafe,
563555
items: ids(items, tcx),
564556
generics: generics.into_tcx(tcx),
565-
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
557+
bounds: bounds.into_tcx(tcx),
566558
implementations: Vec::new(), // Added in JsonRenderer::item
567559
}
568560
}
569561
}
570562

571-
impl FromWithTcx<Box<clean::Impl>> for Impl {
572-
fn from_tcx(impl_: Box<clean::Impl>, tcx: TyCtxt<'_>) -> Self {
563+
impl FromWithTcx<clean::PolyTrait> for PolyTrait {
564+
fn from_tcx(
565+
clean::PolyTrait { trait_, generic_params }: clean::PolyTrait,
566+
tcx: TyCtxt<'_>,
567+
) -> Self {
568+
PolyTrait {
569+
trait_: clean::Type::Path { path: trait_ }.into_tcx(tcx),
570+
generic_params: generic_params.into_tcx(tcx),
571+
}
572+
}
573+
}
574+
575+
impl FromWithTcx<clean::Impl> for Impl {
576+
fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
573577
let provided_trait_methods = impl_.provided_trait_methods(tcx);
574-
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = *impl_;
578+
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
575579
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
576580
let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
577581
// FIXME: use something like ImplKind in JSON?
@@ -730,10 +734,7 @@ impl FromWithTcx<Box<clean::Typedef>> for Typedef {
730734

731735
impl FromWithTcx<clean::OpaqueTy> for OpaqueTy {
732736
fn from_tcx(opaque: clean::OpaqueTy, tcx: TyCtxt<'_>) -> Self {
733-
OpaqueTy {
734-
bounds: opaque.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
735-
generics: opaque.generics.into_tcx(tcx),
736-
}
737+
OpaqueTy { bounds: opaque.bounds.into_tcx(tcx), generics: opaque.generics.into_tcx(tcx) }
737738
}
738739
}
739740

@@ -749,10 +750,7 @@ impl FromWithTcx<clean::Static> for Static {
749750

750751
impl FromWithTcx<clean::TraitAlias> for TraitAlias {
751752
fn from_tcx(alias: clean::TraitAlias, tcx: TyCtxt<'_>) -> Self {
752-
TraitAlias {
753-
generics: alias.generics.into_tcx(tcx),
754-
params: alias.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
755-
}
753+
TraitAlias { generics: alias.generics.into_tcx(tcx), params: alias.bounds.into_tcx(tcx) }
756754
}
757755
}
758756

src/rustdoc-json-types/lib.rs

+34-4
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 = 16;
12+
pub const FORMAT_VERSION: u32 = 17;
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
@@ -115,6 +115,35 @@ pub enum Visibility {
115115
},
116116
}
117117

118+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
119+
pub struct DynTrait {
120+
/// All the traits implemented. One of them is the vtable, and the rest must be auto traits.
121+
pub traits: Vec<PolyTrait>,
122+
/// The lifetime of the whole dyn object
123+
/// ```text
124+
/// dyn Debug + 'static
125+
/// ^^^^^^^
126+
/// |
127+
/// this part
128+
/// ```
129+
pub lifetime: Option<String>,
130+
}
131+
132+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
133+
/// A trait and potential HRTBs
134+
pub struct PolyTrait {
135+
#[serde(rename = "trait")]
136+
pub trait_: Type,
137+
/// Used for Higher-Rank Trait Bounds (HRTBs)
138+
/// ```text
139+
/// dyn for<'a> Fn() -> &'a i32"
140+
/// ^^^^^^^
141+
/// |
142+
/// this part
143+
/// ```
144+
pub generic_params: Vec<GenericParamDef>,
145+
}
146+
118147
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
119148
#[serde(rename_all = "snake_case")]
120149
pub enum GenericArgs {
@@ -395,7 +424,7 @@ pub enum WherePredicate {
395424
type_: Type,
396425
bounds: Vec<GenericBound>,
397426
/// Used for Higher-Rank Trait Bounds (HRTBs)
398-
/// ```plain
427+
/// ```text
399428
/// where for<'a> &'a T: Iterator,"
400429
/// ^^^^^^^
401430
/// |
@@ -420,7 +449,7 @@ pub enum GenericBound {
420449
#[serde(rename = "trait")]
421450
trait_: Type,
422451
/// Used for Higher-Rank Trait Bounds (HRTBs)
423-
/// ```plain
452+
/// ```text
424453
/// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
425454
/// ^^^^^^^^^^^
426455
/// |
@@ -458,6 +487,7 @@ pub enum Type {
458487
args: Option<Box<GenericArgs>>,
459488
param_names: Vec<GenericBound>,
460489
},
490+
DynTrait(DynTrait),
461491
/// Parameterized types
462492
Generic(String),
463493
/// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples
@@ -505,7 +535,7 @@ pub enum Type {
505535
pub struct FunctionPointer {
506536
pub decl: FnDecl,
507537
/// Used for Higher-Rank Trait Bounds (HRTBs)
508-
/// ```plain
538+
/// ```text
509539
/// for<'c> fn(val: &'c i32) -> i32
510540
/// ^^^^^^^
511541
/// |

0 commit comments

Comments
 (0)