diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d57fad6ba4c..4561f9d9b49 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2708,6 +2708,13 @@ pub fn hir_id(self) -> HirId { PreciseCapturingArg::Param(param) => param.hir_id, } } + + pub fn name(self) -> Symbol { + match self { + PreciseCapturingArg::Lifetime(lt) => lt.ident.name, + PreciseCapturingArg::Param(param) => param.ident.name, + } + } } /// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aa596897fc4..98ce268a774 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -228,8 +228,9 @@ fn clean_generic_bound<'tcx>( GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier) } - // FIXME(precise_capturing): Implement rustdoc support - hir::GenericBound::Use(..) => return None, + hir::GenericBound::Use(args, ..) => { + GenericBound::Use(args.iter().map(|arg| arg.name()).collect()) + } }) } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 58eef36677b..1b7d84add1f 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -79,7 +79,7 @@ pub(crate) fn merge_bounds( !bounds.iter_mut().any(|b| { let trait_ref = match *b { clean::GenericBound::TraitBound(ref mut tr, _) => tr, - clean::GenericBound::Outlives(..) => return false, + clean::GenericBound::Outlives(..) | clean::GenericBound::Use(_) => return false, }; // If this QPath's trait `trait_did` is the same as, or a supertrait // of, the bound's trait `did` then we can keep going, otherwise diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index fe01d17b08a..a31adc9949a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1244,6 +1244,8 @@ impl Eq for Attributes {} pub(crate) enum GenericBound { TraitBound(PolyTrait, hir::TraitBoundModifier), Outlives(Lifetime), + /// `use<'a, T>` precise-capturing bound syntax + Use(Vec), } impl GenericBound { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 4268fadd6c5..9b0b2571ec1 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -412,6 +412,20 @@ pub(crate) fn print<'a, 'tcx: 'a>( })?; ty.print(cx).fmt(f) } + clean::GenericBound::Use(args) => { + if f.alternate() { + f.write_str("use<")?; + } else { + f.write_str("use<")?; + } + for (i, arg) in args.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + arg.fmt(f)?; + } + if f.alternate() { f.write_str(">") } else { f.write_str(">") } + } }) } } diff --git a/tests/rustdoc/impl-trait-precise-capturing.rs b/tests/rustdoc/impl-trait-precise-capturing.rs new file mode 100644 index 00000000000..d1987a555c1 --- /dev/null +++ b/tests/rustdoc/impl-trait-precise-capturing.rs @@ -0,0 +1,14 @@ +#![crate_name = "foo"] +#![feature(precise_capturing)] + +//@ has foo/fn.two.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'b, 'a>" +pub fn two<'a, 'b, 'c>() -> impl Sized + use<'b, 'a /* no 'c */> {} + +//@ has foo/fn.params.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'a, T, N>" +pub fn params<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} + +//@ has foo/fn.none.html '//section[@id="main-content"]//pre' "-> impl Sized + use<>" +pub fn none() -> impl Sized + use<> {} + +//@ has foo/fn.first.html '//section[@id="main-content"]//pre' "-> impl use<> + Sized" +pub fn first() -> impl use<> + Sized {}