rustdoc: Render for<'_>
lifetimes in trait objects
This commit is contained in:
parent
e0162a8a56
commit
1f65f56461
6 changed files with 61 additions and 29 deletions
|
@ -1378,8 +1378,9 @@ impl Clean<Type> for hir::Ty<'_> {
|
|||
}
|
||||
TyKind::Path(_) => clean_qpath(&self, cx),
|
||||
TyKind::TraitObject(ref bounds, ref lifetime, _) => {
|
||||
match bounds[0].clean(cx).trait_ {
|
||||
ResolvedPath { path, param_names: None, did, is_generic } => {
|
||||
let cleaned = bounds[0].clean(cx);
|
||||
match cleaned.trait_ {
|
||||
ResolvedPath { path, param_names: None, did, is_generic, .. } => {
|
||||
let mut bounds: Vec<self::GenericBound> = bounds[1..]
|
||||
.iter()
|
||||
.map(|bound| {
|
||||
|
@ -1392,7 +1393,12 @@ impl Clean<Type> for hir::Ty<'_> {
|
|||
if !lifetime.is_elided() {
|
||||
bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
|
||||
}
|
||||
ResolvedPath { path, param_names: Some(bounds), did, is_generic }
|
||||
ResolvedPath {
|
||||
path,
|
||||
param_names: Some((bounds, cleaned.generic_params)),
|
||||
did,
|
||||
is_generic,
|
||||
}
|
||||
}
|
||||
_ => Infer, // shouldn't happen
|
||||
}
|
||||
|
@ -1542,7 +1548,12 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
|
||||
let path =
|
||||
external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs);
|
||||
ResolvedPath { path, param_names: Some(param_names), did, is_generic: false }
|
||||
ResolvedPath {
|
||||
path,
|
||||
param_names: Some((param_names, vec![])),
|
||||
did,
|
||||
is_generic: false,
|
||||
}
|
||||
}
|
||||
ty::Tuple(ref t) => {
|
||||
Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx))
|
||||
|
@ -2248,7 +2259,7 @@ impl From<GenericBound> for SimpleBound {
|
|||
GenericBound::TraitBound(t, mod_) => match t.trait_ {
|
||||
Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
|
||||
path.segments,
|
||||
param_names.map_or_else(Vec::new, |v| {
|
||||
param_names.map_or_else(Vec::new, |(v, _)| {
|
||||
v.iter().map(|p| SimpleBound::from(p.clone())).collect()
|
||||
}),
|
||||
t.generic_params,
|
||||
|
|
|
@ -1407,7 +1407,9 @@ crate enum Type {
|
|||
/// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
|
||||
ResolvedPath {
|
||||
path: Path,
|
||||
param_names: Option<Vec<GenericBound>>,
|
||||
/// If `param_names` is `Some`, this path is a trait object and the Vecs repsresent
|
||||
/// `(generic bounds, generic parameters)`
|
||||
param_names: Option<(Vec<GenericBound>, Vec<GenericParamDef>)>,
|
||||
did: DefId,
|
||||
/// `true` if is a `T::Name` path for associated types.
|
||||
is_generic: bool,
|
||||
|
|
|
@ -646,11 +646,11 @@ fn primitive_link(
|
|||
|
||||
/// Helper to render type parameters
|
||||
fn tybounds<'a, 'tcx: 'a>(
|
||||
param_names: &'a Option<Vec<clean::GenericBound>>,
|
||||
param_names: Option<&'a Vec<clean::GenericBound>>,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl fmt::Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match *param_names {
|
||||
Some(ref params) => {
|
||||
display_fn(move |f| match param_names {
|
||||
Some(params) => {
|
||||
for param in params {
|
||||
write!(f, " + ")?;
|
||||
fmt::Display::fmt(¶m.print(cx), f)?;
|
||||
|
@ -695,8 +695,27 @@ fn fmt_type<'cx>(
|
|||
match *t {
|
||||
clean::Generic(name) => write!(f, "{}", name),
|
||||
clean::ResolvedPath { did, ref param_names, ref path, is_generic } => {
|
||||
if param_names.is_some() {
|
||||
let generic_params = param_names.as_ref().map(|(_, x)| x);
|
||||
let param_names = param_names.as_ref().map(|(x, _)| x);
|
||||
|
||||
if let Some(generic_params) = generic_params {
|
||||
f.write_str("dyn ")?;
|
||||
|
||||
if !generic_params.is_empty() {
|
||||
if f.alternate() {
|
||||
write!(
|
||||
f,
|
||||
"for<{:#}> ",
|
||||
comma_sep(generic_params.iter().map(|g| g.print(cx)))
|
||||
)?;
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"for<{}> ",
|
||||
comma_sep(generic_params.iter().map(|g| g.print(cx)))
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
|
||||
resolved_path(f, did, path, is_generic, use_absolute, cx)?;
|
||||
|
@ -835,7 +854,7 @@ fn fmt_type<'cx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
clean::ResolvedPath { param_names: Some(ref v), .. } if !v.is_empty() => {
|
||||
clean::ResolvedPath { param_names: Some((ref v, _)), .. } if !v.is_empty() => {
|
||||
write!(f, "{}{}{}(", amp, lt, m)?;
|
||||
fmt_type(&ty, f, use_absolute, cx)?;
|
||||
write!(f, ")")
|
||||
|
|
|
@ -378,7 +378,7 @@ impl FromWithTcx<clean::Type> for Type {
|
|||
id: from_def_id(did.into()),
|
||||
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
|
||||
param_names: param_names
|
||||
.map(|v| v.into_iter().map(|x| x.into_tcx(tcx)).collect())
|
||||
.map(|(v, _)| v.into_iter().map(|x| x.into_tcx(tcx)).collect())
|
||||
.unwrap_or_default(),
|
||||
},
|
||||
Generic(s) => Type::Generic(s.to_string()),
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#![crate_name = "foo"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub struct Foo {
|
||||
pub some_func: for<'a> fn(val: &'a i32) -> i32,
|
||||
pub some_trait: dyn for<'a> Trait<'a>,
|
||||
}
|
||||
|
||||
// @has foo/struct.Foo.html '//span[@id="structfield.some_func"]' "some_func: for<'a> fn(val: &'a i32) -> i32"
|
||||
// @has foo/struct.Foo.html '//span[@id="structfield.some_trait"]' "some_trait: dyn Trait<'a>"
|
||||
|
||||
pub trait Trait<'a> {}
|
|
@ -1,6 +1,7 @@
|
|||
#![crate_name = "foo"]
|
||||
|
||||
trait A<'x> {}
|
||||
// @has foo/trait.Trait.html
|
||||
pub trait Trait<'x> {}
|
||||
|
||||
// @has foo/fn.test1.html
|
||||
// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
|
||||
|
@ -11,10 +12,10 @@ where
|
|||
}
|
||||
|
||||
// @has foo/fn.test2.html
|
||||
// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: A<'b>,"
|
||||
// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: Trait<'b>,"
|
||||
pub fn test2<T>()
|
||||
where
|
||||
for<'a, 'b> &'a T: A<'b>,
|
||||
for<'a, 'b> &'a T: Trait<'b>,
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -29,13 +30,24 @@ where
|
|||
// @has foo/struct.Foo.html
|
||||
pub struct Foo<'a> {
|
||||
_x: &'a u8,
|
||||
pub some_trait: &'a dyn for<'b> Trait<'b>,
|
||||
pub some_func: for<'c> fn(val: &'c i32) -> i32,
|
||||
}
|
||||
|
||||
// @has - '//span[@id="structfield.some_func"]' "some_func: for<'c> fn(val: &'c i32) -> i32"
|
||||
// @has - '//span[@id="structfield.some_trait"]' "some_trait: &'a dyn for<'b> Trait<'b>"
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
// @has - '//code' "pub fn bar<T>() where T: A<'a>,"
|
||||
// @has - '//code' "pub fn bar<T>() where T: Trait<'a>,"
|
||||
pub fn bar<T>()
|
||||
where
|
||||
T: A<'a>,
|
||||
T: Trait<'a>,
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// @has foo/trait.B.html
|
||||
pub trait B<'x> {}
|
||||
|
||||
// @has - '//code[@class="in-band"]' "impl<'a> B<'a> for dyn for<'b> Trait<'b>"
|
||||
impl<'a> B<'a> for dyn for<'b> Trait<'b> {}
|
||||
|
|
Loading…
Add table
Reference in a new issue