Add RTN support to rustdoc
This commit is contained in:
parent
4d30011f6c
commit
e3ac1fa81a
10 changed files with 98 additions and 32 deletions
|
@ -252,7 +252,9 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
|||
// def-ID that will be used to determine the traits/predicates in
|
||||
// scope. This is derived from the enclosing item-like thing.
|
||||
let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id);
|
||||
collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty)
|
||||
collect::ItemCtxt::new(tcx, env_def_id.def_id)
|
||||
.lowerer()
|
||||
.lower_ty_maybe_return_type_notation(hir_ty)
|
||||
}
|
||||
|
||||
/// This is for rustdoc.
|
||||
|
|
|
@ -1488,6 +1488,9 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
|||
// The only time this happens is if we're inside the rustdoc for Fn(),
|
||||
// which only has one associated type, which is not a GAT, so whatever.
|
||||
}
|
||||
GenericArgs::ReturnTypeNotation => {
|
||||
// Never move these.
|
||||
}
|
||||
}
|
||||
bounds.extend(mem::take(pred_bounds));
|
||||
false
|
||||
|
@ -2553,36 +2556,42 @@ fn clean_generic_args<'tcx>(
|
|||
generic_args: &hir::GenericArgs<'tcx>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> GenericArgs {
|
||||
// FIXME(return_type_notation): Fix RTN parens rendering
|
||||
if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() {
|
||||
let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect();
|
||||
let output = match output.kind {
|
||||
hir::TyKind::Tup(&[]) => None,
|
||||
_ => Some(Box::new(clean_ty(output, cx))),
|
||||
};
|
||||
GenericArgs::Parenthesized { inputs, output }
|
||||
} else {
|
||||
let args = generic_args
|
||||
.args
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => {
|
||||
GenericArg::Lifetime(clean_lifetime(lt, cx))
|
||||
}
|
||||
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
||||
hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty.as_unambig_ty(), cx)),
|
||||
hir::GenericArg::Const(ct) => {
|
||||
GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), cx)))
|
||||
}
|
||||
hir::GenericArg::Infer(_inf) => GenericArg::Infer,
|
||||
})
|
||||
.collect();
|
||||
let constraints = generic_args
|
||||
.constraints
|
||||
.iter()
|
||||
.map(|c| clean_assoc_item_constraint(c, cx))
|
||||
.collect::<ThinVec<_>>();
|
||||
GenericArgs::AngleBracketed { args, constraints }
|
||||
match generic_args.parenthesized {
|
||||
hir::GenericArgsParentheses::No => {
|
||||
let args = generic_args
|
||||
.args
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => {
|
||||
GenericArg::Lifetime(clean_lifetime(lt, cx))
|
||||
}
|
||||
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
||||
hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty.as_unambig_ty(), cx)),
|
||||
hir::GenericArg::Const(ct) => {
|
||||
GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), cx)))
|
||||
}
|
||||
hir::GenericArg::Infer(_inf) => GenericArg::Infer,
|
||||
})
|
||||
.collect();
|
||||
let constraints = generic_args
|
||||
.constraints
|
||||
.iter()
|
||||
.map(|c| clean_assoc_item_constraint(c, cx))
|
||||
.collect::<ThinVec<_>>();
|
||||
GenericArgs::AngleBracketed { args, constraints }
|
||||
}
|
||||
hir::GenericArgsParentheses::ParenSugar => {
|
||||
let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() else {
|
||||
bug!();
|
||||
};
|
||||
let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect();
|
||||
let output = match output.kind {
|
||||
hir::TyKind::Tup(&[]) => None,
|
||||
_ => Some(Box::new(clean_ty(output, cx))),
|
||||
};
|
||||
GenericArgs::Parenthesized { inputs, output }
|
||||
}
|
||||
hir::GenericArgsParentheses::ReturnTypeNotation => GenericArgs::ReturnTypeNotation,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,10 @@ pub(crate) fn merge_bounds(
|
|||
}
|
||||
}
|
||||
},
|
||||
PP::ReturnTypeNotation => {
|
||||
// Cannot merge bounds with RTN.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
true
|
||||
})
|
||||
|
|
|
@ -2259,8 +2259,12 @@ impl GenericArg {
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub(crate) enum GenericArgs {
|
||||
/// `<args, constraints = ..>`
|
||||
AngleBracketed { args: ThinVec<GenericArg>, constraints: ThinVec<AssocItemConstraint> },
|
||||
/// `(inputs) -> output`
|
||||
Parenthesized { inputs: ThinVec<Type>, output: Option<Box<Type>> },
|
||||
/// `(..)`
|
||||
ReturnTypeNotation,
|
||||
}
|
||||
|
||||
impl GenericArgs {
|
||||
|
@ -2270,6 +2274,7 @@ impl GenericArgs {
|
|||
args.is_empty() && constraints.is_empty()
|
||||
}
|
||||
GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
|
||||
GenericArgs::ReturnTypeNotation => false,
|
||||
}
|
||||
}
|
||||
pub(crate) fn constraints(&self) -> Box<dyn Iterator<Item = AssocItemConstraint> + '_> {
|
||||
|
@ -2294,6 +2299,7 @@ impl GenericArgs {
|
|||
})
|
||||
.into_iter(),
|
||||
),
|
||||
GenericArgs::ReturnTypeNotation => Box::new([].into_iter()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2305,8 +2311,10 @@ impl<'a> IntoIterator for &'a GenericArgs {
|
|||
match self {
|
||||
GenericArgs::AngleBracketed { args, .. } => Box::new(args.iter().cloned()),
|
||||
GenericArgs::Parenthesized { inputs, .. } => {
|
||||
// FIXME: This isn't really right, since `Fn(A, B)` is `Fn<(A, B)>`
|
||||
Box::new(inputs.iter().cloned().map(GenericArg::Type))
|
||||
}
|
||||
GenericArgs::ReturnTypeNotation => Box::new([].into_iter()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -332,6 +332,9 @@ impl clean::GenericArgs {
|
|||
}
|
||||
}
|
||||
}
|
||||
clean::GenericArgs::ReturnTypeNotation => {
|
||||
f.write_str("(..)")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
|
|
@ -176,6 +176,7 @@ impl FromClean<clean::GenericArgs> for GenericArgs {
|
|||
inputs: inputs.into_json(renderer),
|
||||
output: output.map(|a| (*a).into_json(renderer)),
|
||||
},
|
||||
ReturnTypeNotation => GenericArgs::ReturnTypeNotation,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
|
|||
/// This integer is incremented with every breaking change to the API,
|
||||
/// and is returned along with the JSON blob as [`Crate::format_version`].
|
||||
/// Consuming code should assert that this value matches the format version(s) that it supports.
|
||||
pub const FORMAT_VERSION: u32 = 41;
|
||||
pub const FORMAT_VERSION: u32 = 42;
|
||||
|
||||
/// The root of the emitted JSON blob.
|
||||
///
|
||||
|
@ -229,6 +229,8 @@ pub enum GenericArgs {
|
|||
/// The output type provided after the `->`, if present.
|
||||
output: Option<Type>,
|
||||
},
|
||||
/// `T::method(..)`
|
||||
ReturnTypeNotation,
|
||||
}
|
||||
|
||||
/// One argument in a list of generic arguments to a path segment.
|
||||
|
|
|
@ -326,6 +326,7 @@ impl<'a> Validator<'a> {
|
|||
self.check_type(o);
|
||||
}
|
||||
}
|
||||
GenericArgs::ReturnTypeNotation => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
tests/rustdoc-json/return-type-notation.rs
Normal file
18
tests/rustdoc-json/return-type-notation.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
//@ edition: 2021
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(return_type_notation)]
|
||||
|
||||
pub trait Foo {
|
||||
async fn bar();
|
||||
}
|
||||
|
||||
//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.args.angle_bracketed.constraints[0].args" '"return_type_notation"'
|
||||
//@ ismany "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[*].bound_predicate.type.qualified_path.args" '"return_type_notation"' '"return_type_notation"'
|
||||
pub fn foo<T: Foo<bar(..): Send>>()
|
||||
where
|
||||
<T as Foo>::bar(..): 'static,
|
||||
T::bar(..): Sync,
|
||||
{
|
||||
}
|
18
tests/rustdoc/return-type-notation.rs
Normal file
18
tests/rustdoc/return-type-notation.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(return_type_notation)]
|
||||
|
||||
pub trait Foo {
|
||||
async fn bar();
|
||||
}
|
||||
|
||||
//@ has "return_type_notation/fn.foo.html"
|
||||
//@ has - '//pre[@class="rust item-decl"]' "pub fn foo<T: Foo<bar(..): Send>>()"
|
||||
//@ has - '//pre[@class="rust item-decl"]' "where <T as Foo>::bar(..): 'static, T::bar(..): Sync"
|
||||
pub fn foo<T: Foo<bar(..): Send>>()
|
||||
where
|
||||
<T as Foo>::bar(..): 'static,
|
||||
T::bar(..): Sync,
|
||||
{
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue