Skip to content

Commit 14e17b8

Browse files
authored
Rollup merge of #127632 - compiler-errors:precise-capturing-rustdoc, r=fmease
Implement `precise_capturing` support for rustdoc Implements rustdoc (+json) support for local (i.e. non-cross-crate-inlined) RPITs with `use<...>` precise capturing syntax. Tests kinda suck. They're really hard to write 😰 r? `@fmease` or re-roll if you're too busy! also cc `@aDotInTheVoid` for the json side Tracking: * #127228 (comment) (not fully fixed for cross-crate-inlined opaques) * #123432
2 parents 5e4ff01 + caf1457 commit 14e17b8

File tree

11 files changed

+54
-4
lines changed

11 files changed

+54
-4
lines changed

compiler/rustc_hir/src/hir.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,13 @@ impl PreciseCapturingArg<'_> {
27082708
PreciseCapturingArg::Param(param) => param.hir_id,
27092709
}
27102710
}
2711+
2712+
pub fn name(self) -> Symbol {
2713+
match self {
2714+
PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
2715+
PreciseCapturingArg::Param(param) => param.ident.name,
2716+
}
2717+
}
27112718
}
27122719

27132720
/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param

rustfmt.toml

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ ignore = [
2222
"/tests/rustdoc-ui/", # Some have syntax errors, some are whitespace-sensitive.
2323
"/tests/ui/", # Some have syntax errors, some are whitespace-sensitive.
2424
"/tests/ui-fulldeps/", # Some are whitespace-sensitive (e.g. `// ~ERROR` comments).
25+
# #[cfg(bootstrap)] so that t-release sees this when they search for it
26+
"/tests/rustdoc-json/impl-trait-precise-capturing.rs",
2527

2628
# Do not format submodules.
2729
# FIXME: sync submodule list with tidy/bootstrap/etc

src/librustdoc/clean/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,9 @@ fn clean_generic_bound<'tcx>(
228228

229229
GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier)
230230
}
231-
// FIXME(precise_capturing): Implement rustdoc support
232-
hir::GenericBound::Use(..) => return None,
231+
hir::GenericBound::Use(args, ..) => {
232+
GenericBound::Use(args.iter().map(|arg| arg.name()).collect())
233+
}
233234
})
234235
}
235236

src/librustdoc/clean/simplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub(crate) fn merge_bounds(
7979
!bounds.iter_mut().any(|b| {
8080
let trait_ref = match *b {
8181
clean::GenericBound::TraitBound(ref mut tr, _) => tr,
82-
clean::GenericBound::Outlives(..) => return false,
82+
clean::GenericBound::Outlives(..) | clean::GenericBound::Use(_) => return false,
8383
};
8484
// If this QPath's trait `trait_did` is the same as, or a supertrait
8585
// of, the bound's trait `did` then we can keep going, otherwise

src/librustdoc/clean/types.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,8 @@ impl Eq for Attributes {}
12441244
pub(crate) enum GenericBound {
12451245
TraitBound(PolyTrait, hir::TraitBoundModifier),
12461246
Outlives(Lifetime),
1247+
/// `use<'a, T>` precise-capturing bound syntax
1248+
Use(Vec<Symbol>),
12471249
}
12481250

12491251
impl GenericBound {

src/librustdoc/html/format.rs

+14
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,20 @@ impl clean::GenericBound {
412412
})?;
413413
ty.print(cx).fmt(f)
414414
}
415+
clean::GenericBound::Use(args) => {
416+
if f.alternate() {
417+
f.write_str("use&lt;")?;
418+
} else {
419+
f.write_str("use<")?;
420+
}
421+
for (i, arg) in args.iter().enumerate() {
422+
if i > 0 {
423+
write!(f, ", ")?;
424+
}
425+
arg.fmt(f)?;
426+
}
427+
if f.alternate() { f.write_str("&gt;") } else { f.write_str(">") }
428+
}
415429
})
416430
}
417431
}

src/librustdoc/json/conversions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
542542
}
543543
}
544544
Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
545+
Use(args) => GenericBound::Use(args.into_iter().map(|arg| arg.to_string()).collect()),
545546
}
546547
}
547548
}

src/rustdoc-json-types/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
88
use std::path::PathBuf;
99

1010
/// rustdoc format-version.
11-
pub const FORMAT_VERSION: u32 = 31;
11+
pub const FORMAT_VERSION: u32 = 32;
1212

1313
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
1414
/// about the language items in the local crate, as well as info about external items to allow
@@ -538,6 +538,8 @@ pub enum GenericBound {
538538
modifier: TraitBoundModifier,
539539
},
540540
Outlives(String),
541+
/// `use<'a, T>` precise-capturing bound syntax
542+
Use(Vec<String>),
541543
}
542544

543545
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]

src/tools/jsondoclint/src/validator.rs

+1
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ impl<'a> Validator<'a> {
298298
generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
299299
}
300300
GenericBound::Outlives(_) => {}
301+
GenericBound::Use(_) => {}
301302
}
302303
}
303304

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![feature(precise_capturing)]
2+
3+
// @is "$.index[*][?(@.name=='hello')].inner.function.decl.output.impl_trait[1].use[0]" \"\'a\"
4+
// @is "$.index[*][?(@.name=='hello')].inner.function.decl.output.impl_trait[1].use[1]" \"T\"
5+
// @is "$.index[*][?(@.name=='hello')].inner.function.decl.output.impl_trait[1].use[2]" \"N\"
6+
pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![crate_name = "foo"]
2+
#![feature(precise_capturing)]
3+
4+
//@ has foo/fn.two.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'b, 'a>"
5+
pub fn two<'a, 'b, 'c>() -> impl Sized + use<'b, 'a /* no 'c */> {}
6+
7+
//@ has foo/fn.params.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'a, T, N>"
8+
pub fn params<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
9+
10+
//@ has foo/fn.none.html '//section[@id="main-content"]//pre' "-> impl Sized + use<>"
11+
pub fn none() -> impl Sized + use<> {}
12+
13+
//@ has foo/fn.first.html '//section[@id="main-content"]//pre' "-> impl use<> + Sized"
14+
pub fn first() -> impl use<> + Sized {}

0 commit comments

Comments
 (0)