Skip to content

Commit

Permalink
rustdoc-json: Better representation of lifetime bounds in where clauses.
Browse files Browse the repository at this point in the history
As suggested [on zulip][1], there's no need to use `GenericBound` here,
as the only bound a lifetime can have is that it outlives other
lifetimes.

While we're making breaking changes here, I also renamed it from using
"region" to "lifetime", as this is more user-aligned. See [this
comment][2] for details.

[1]: https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/.60ItemEnum.3A.3AOpaqueTy.60/near/448871430
[2]: rust-lang#100961 (comment)
  • Loading branch information
aDotInTheVoid committed Jul 3, 2024
1 parent c872a14 commit 7e8aac5
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,7 @@ impl GenericBound {
}
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub(crate) struct Lifetime(pub Symbol);

impl Lifetime {
Expand Down
11 changes: 9 additions & 2 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_ast::ast;
use rustc_attr::DeprecatedSince;
use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId};
use rustc_metadata::rendered_const;
use rustc_middle::bug;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::{Pos, Symbol};
Expand Down Expand Up @@ -512,9 +513,15 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
})
.collect(),
},
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
RegionPredicate { lifetime, bounds } => WherePredicate::LifetimePredicate {
lifetime: convert_lifetime(lifetime),
bounds: bounds.into_tcx(tcx),
outlives: bounds
.iter()
.map(|bound| match bound {
clean::GenericBound::Outlives(lt) => convert_lifetime(*lt),
_ => bug!("found non-outlives-bound on lifetime predicate"),
})
.collect(),
},
EqPredicate { lhs, rhs } => {
WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) }
Expand Down
6 changes: 3 additions & 3 deletions src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// rustdoc format-version.
pub const FORMAT_VERSION: u32 = 30;
pub const FORMAT_VERSION: u32 = 31;

/// 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
Expand Down Expand Up @@ -511,9 +511,9 @@ pub enum WherePredicate {
/// ```
generic_params: Vec<GenericParamDef>,
},
RegionPredicate {
LifetimePredicate {
lifetime: String,
bounds: Vec<GenericBound>,
outlives: Vec<String>,
},
EqPredicate {
lhs: Type,
Expand Down
4 changes: 2 additions & 2 deletions src/tools/jsondoclint/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ impl<'a> Validator<'a> {
bounds.iter().for_each(|b| self.check_generic_bound(b));
generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
}
WherePredicate::RegionPredicate { lifetime: _, bounds } => {
bounds.iter().for_each(|b| self.check_generic_bound(b));
WherePredicate::LifetimePredicate { lifetime: _, outlives: _ } => {
// nop, all strings.
}
WherePredicate::EqPredicate { lhs, rhs } => {
self.check_type(lhs);
Expand Down
8 changes: 8 additions & 0 deletions tests/rustdoc-json/lifetime/outlives_in_param.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// ignore-tidy-linelength

// @count '$.index[*][?(@.name=="outlives")].inner.function.generics.params[*]' 2
// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].name' \"\'a\"
// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].kind.lifetime.outlives' []
// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[1].name' '"T"'
// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[1].kind.type.bounds' '[{"outlives": "'\''a"}]'
pub fn outlives<'a, T: 'a>() {}
24 changes: 24 additions & 0 deletions tests/rustdoc-json/lifetime/outlives_in_where.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// ignore-tidy-linelength

// @is '$.index[*][?(@.name=="on_lifetimes")].inner.function.generics.where_predicates' '[{"lifetime_predicate": {"lifetime": "'\''all", "outlives": ["'\''a", "'\''b", "'\''c"]}}]'
pub fn on_lifetimes<'a, 'b, 'c, 'all>()
where
'all: 'a + 'b + 'c,
{
}

// @count '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[*]' 2
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[0].name' \"\'a\"
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[0].kind.lifetime.outlives' []
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].name' '"T"'
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' []
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' []
// @count '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[*]' 1
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.type.generic' '"T"'
// @count '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]' 1
// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].outlives' \"\'a\"
pub fn on_trait<'a, T>()
where
T: 'a,
{
}

0 comments on commit 7e8aac5

Please sign in to comment.