rustdoc + rustdoc-json support for non_lifetime_binders
This commit is contained in:
parent
bf57e8ada6
commit
be9fd75d32
7 changed files with 73 additions and 29 deletions
|
@ -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(),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -49,11 +49,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP
|
|||
equalities.retain(|(lhs, rhs, bound_params)| {
|
||||
let Some((ty, trait_did, name)) = lhs.projection() else { return true; };
|
||||
let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
|
||||
let bound_params = bound_params
|
||||
.into_iter()
|
||||
.map(|param| clean::GenericParamDef::lifetime(param.0))
|
||||
.collect();
|
||||
merge_bounds(cx, bounds, bound_params, trait_did, name, rhs)
|
||||
merge_bounds(cx, bounds, bound_params.clone(), trait_did, name, rhs)
|
||||
});
|
||||
|
||||
// And finally, let's reassemble everything
|
||||
|
|
|
@ -1236,9 +1236,9 @@ impl Lifetime {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum WherePredicate {
|
||||
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
|
||||
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<GenericParamDef> },
|
||||
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
|
||||
EqPredicate { lhs: Box<Type>, rhs: Box<Term>, bound_params: Vec<Lifetime> },
|
||||
EqPredicate { lhs: Box<Type>, rhs: Box<Term>, bound_params: Vec<GenericParamDef> },
|
||||
}
|
||||
|
||||
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<Lifetime> },
|
||||
Type { did: DefId, bounds: Vec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
|
||||
Const { did: DefId, ty: Box<Type>, default: Option<Box<String>> },
|
||||
Const { ty: Box<Type>, default: Option<Box<String>> },
|
||||
}
|
||||
|
||||
impl GenericParamDefKind {
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> 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<clean::WherePredicate> 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(),
|
||||
},
|
||||
|
|
24
tests/rustdoc-json/non_lifetime_binders.rs
Normal file
24
tests/rustdoc-json/non_lifetime_binders.rs
Normal file
|
@ -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<T_>;
|
||||
|
||||
pub struct Wrapper<T_>(PhantomData<T_>);
|
||||
|
||||
// @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<T>: Trait {}
|
9
tests/rustdoc/non_lifetime_binders.rs
Normal file
9
tests/rustdoc/non_lifetime_binders.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
#![feature(non_lifetime_binders)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub trait Trait {}
|
||||
|
||||
pub struct Wrapper<T: ?Sized>(Box<T>);
|
||||
|
||||
// @has non_lifetime_binders/fn.foo.html '//pre' "fn foo()where for<'a, T> &'a Wrapper<T>: Trait"
|
||||
pub fn foo() where for<'a, T> &'a Wrapper<T>: Trait {}
|
Loading…
Add table
Add a link
Reference in a new issue