From be9fd75d32f9af0ebed5aad348891603f2e17ac2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Feb 2023 04:43:15 +0000 Subject: [PATCH] rustdoc + rustdoc-json support for non_lifetime_binders --- src/librustdoc/clean/mod.rs | 17 ++--------- src/librustdoc/clean/simplify.rs | 6 +--- src/librustdoc/clean/types.rs | 8 ++--- src/librustdoc/html/format.rs | 4 +-- src/librustdoc/json/conversions.rs | 34 +++++++++++++++++++--- tests/rustdoc-json/non_lifetime_binders.rs | 24 +++++++++++++++ tests/rustdoc/non_lifetime_binders.rs | 9 ++++++ 7 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 tests/rustdoc-json/non_lifetime_binders.rs create mode 100644 tests/rustdoc/non_lifetime_binders.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5f5521caf68b9..2d247bd537bdf 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -31,7 +31,6 @@ use rustc_span::hygiene::{AstPass, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, ExpnKind}; -use std::assert_matches::assert_matches; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::BTreeMap; @@ -270,15 +269,7 @@ fn clean_where_predicate<'tcx>( let bound_params = wbp .bound_generic_params .iter() - .map(|param| { - // Higher-ranked params must be lifetimes. - // Higher-ranked lifetimes can't have bounds. - assert_matches!( - param, - hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. } - ); - Lifetime(param.name.ident().name) - }) + .map(|param| clean_generic_param(cx, None, param)) .collect(); WherePredicate::BoundPredicate { ty: clean_ty(wbp.bounded_ty, cx), @@ -410,7 +401,7 @@ fn clean_projection_predicate<'tcx>( .collect_referenced_late_bound_regions(&pred) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) if br.is_named() => Some(Lifetime(name)), + ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)), _ => None, }) .collect(); @@ -508,7 +499,6 @@ fn clean_generic_param_def<'tcx>( ty::GenericParamDefKind::Const { has_default } => ( def.name, GenericParamDefKind::Const { - did: def.def_id, ty: Box::new(clean_middle_ty( ty::Binder::dummy( cx.tcx @@ -578,7 +568,6 @@ fn clean_generic_param<'tcx>( hir::GenericParamKind::Const { ty, default } => ( param.name.ident().name, GenericParamDefKind::Const { - did: param.def_id.to_def_id(), ty: Box::new(clean_ty(ty, cx)), default: default .map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())), @@ -831,7 +820,7 @@ fn clean_ty_generics<'tcx>( p.get_bound_params() .into_iter() .flatten() - .map(|param| GenericParamDef::lifetime(param.0)) + .cloned() .collect(), )); } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index dbbc25739aa07..3c72b0bf9f2f6 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -49,11 +49,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec, bound_params: Vec }, + BoundPredicate { ty: Type, bounds: Vec, bound_params: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, - EqPredicate { lhs: Box, rhs: Box, bound_params: Vec }, + EqPredicate { lhs: Box, rhs: Box, bound_params: Vec }, } impl WherePredicate { @@ -1250,7 +1250,7 @@ impl WherePredicate { } } - pub(crate) fn get_bound_params(&self) -> Option<&[Lifetime]> { + pub(crate) fn get_bound_params(&self) -> Option<&[GenericParamDef]> { match self { Self::BoundPredicate { bound_params, .. } | Self::EqPredicate { bound_params, .. } => { Some(bound_params) @@ -1264,7 +1264,7 @@ impl WherePredicate { pub(crate) enum GenericParamDefKind { Lifetime { outlives: Vec }, Type { did: DefId, bounds: Vec, default: Option>, synthetic: bool }, - Const { did: DefId, ty: Box, default: Option> }, + Const { ty: Box, default: Option> }, } impl GenericParamDefKind { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f2b9c0bcf3ee7..0895bb510d481 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -307,13 +307,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( write!( f, "for<{:#}> {ty_cx:#}: {generic_bounds:#}", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) + comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true) ) } else { write!( f, "for<{}> {ty_cx}: {generic_bounds}", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) + comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true) ) } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 18c45fd699155..59d67f27b3006 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -456,7 +456,7 @@ impl FromWithTcx for GenericParamDefKind { default: default.map(|x| (*x).into_tcx(tcx)), synthetic, }, - Const { did: _, ty, default } => GenericParamDefKind::Const { + Const { ty, default } => GenericParamDefKind::Const { type_: (*ty).into_tcx(tcx), default: default.map(|x| *x), }, @@ -473,9 +473,35 @@ impl FromWithTcx for WherePredicate { bounds: bounds.into_tcx(tcx), generic_params: bound_params .into_iter() - .map(|x| GenericParamDef { - name: x.0.to_string(), - kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + .map(|x| { + let name = x.name.to_string(); + let kind = match x.kind { + clean::GenericParamDefKind::Lifetime { outlives } => { + GenericParamDefKind::Lifetime { + outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(), + } + } + clean::GenericParamDefKind::Type { + did: _, + bounds, + default, + synthetic, + } => GenericParamDefKind::Type { + bounds: bounds + .into_iter() + .map(|bound| bound.into_tcx(tcx)) + .collect(), + default: default.map(|ty| (*ty).into_tcx(tcx)), + synthetic, + }, + clean::GenericParamDefKind::Const { ty, default } => { + GenericParamDefKind::Const { + type_: (*ty).into_tcx(tcx), + default: default.map(|d| *d), + } + } + }; + GenericParamDef { name, kind } }) .collect(), }, diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs new file mode 100644 index 0000000000000..ca5a008344af2 --- /dev/null +++ b/tests/rustdoc-json/non_lifetime_binders.rs @@ -0,0 +1,24 @@ +// ignore-tidy-linelength + +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] + +#![no_core] +#![feature(lang_items, no_core)] + +#[lang = "sized"] +pub trait Sized {} + +pub trait Trait {} + +#[lang = "phantom_data"] +struct PhantomData; + +pub struct Wrapper(PhantomData); + +// @count "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[*]" 2 +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\" +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\" +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }' +pub fn foo() where for<'a, T> &'a Wrapper: Trait {} diff --git a/tests/rustdoc/non_lifetime_binders.rs b/tests/rustdoc/non_lifetime_binders.rs new file mode 100644 index 0000000000000..da9a4e6a84d5a --- /dev/null +++ b/tests/rustdoc/non_lifetime_binders.rs @@ -0,0 +1,9 @@ +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] + +pub trait Trait {} + +pub struct Wrapper(Box); + +// @has non_lifetime_binders/fn.foo.html '//pre' "fn foo()where for<'a, T> &'a Wrapper: Trait" +pub fn foo() where for<'a, T> &'a Wrapper: Trait {}