mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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: * https://github.com/rust-lang/rust/issues/127228#issuecomment-2201443216 (not fully fixed for cross-crate-inlined opaques) * https://github.com/rust-lang/rust/issues/123432
This commit is contained in:
commit
c0d949909f
@ -2708,6 +2708,13 @@ impl PreciseCapturingArg<'_> {
|
||||
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
|
||||
|
@ -22,6 +22,8 @@ ignore = [
|
||||
"/tests/rustdoc-ui/", # Some have syntax errors, some are whitespace-sensitive.
|
||||
"/tests/ui/", # Some have syntax errors, some are whitespace-sensitive.
|
||||
"/tests/ui-fulldeps/", # Some are whitespace-sensitive (e.g. `// ~ERROR` comments).
|
||||
# #[cfg(bootstrap)] so that t-release sees this when they search for it
|
||||
"/tests/rustdoc-json/impl-trait-precise-capturing.rs",
|
||||
|
||||
# Do not format submodules.
|
||||
# FIXME: sync submodule list with tidy/bootstrap/etc
|
||||
|
@ -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())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<Symbol>),
|
||||
}
|
||||
|
||||
impl GenericBound {
|
||||
|
@ -412,6 +412,20 @@ impl clean::GenericBound {
|
||||
})?;
|
||||
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(">") }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +542,7 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
|
||||
}
|
||||
}
|
||||
Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
|
||||
Use(args) => GenericBound::Use(args.into_iter().map(|arg| arg.to_string()).collect()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// rustdoc format-version.
|
||||
pub const FORMAT_VERSION: u32 = 31;
|
||||
pub const FORMAT_VERSION: u32 = 32;
|
||||
|
||||
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
|
||||
/// about the language items in the local crate, as well as info about external items to allow
|
||||
@ -538,6 +538,8 @@ pub enum GenericBound {
|
||||
modifier: TraitBoundModifier,
|
||||
},
|
||||
Outlives(String),
|
||||
/// `use<'a, T>` precise-capturing bound syntax
|
||||
Use(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
|
@ -298,6 +298,7 @@ impl<'a> Validator<'a> {
|
||||
generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
|
||||
}
|
||||
GenericBound::Outlives(_) => {}
|
||||
GenericBound::Use(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
6
tests/rustdoc-json/impl-trait-precise-capturing.rs
Normal file
6
tests/rustdoc-json/impl-trait-precise-capturing.rs
Normal file
@ -0,0 +1,6 @@
|
||||
#![feature(precise_capturing)]
|
||||
|
||||
// @is "$.index[*][?(@.name=='hello')].inner.function.decl.output.impl_trait[1].use[0]" \"\'a\"
|
||||
// @is "$.index[*][?(@.name=='hello')].inner.function.decl.output.impl_trait[1].use[1]" \"T\"
|
||||
// @is "$.index[*][?(@.name=='hello')].inner.function.decl.output.impl_trait[1].use[2]" \"N\"
|
||||
pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
|
14
tests/rustdoc/impl-trait-precise-capturing.rs
Normal file
14
tests/rustdoc/impl-trait-precise-capturing.rs
Normal file
@ -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 {}
|
Loading…
Reference in New Issue
Block a user