Skip to content

Commit

Permalink
Rollup merge of rust-lang#108335 - compiler-errors:non_lifetime_binde…
Browse files Browse the repository at this point in the history
…rs-rustdoc, r=GuillaumeGomez

rustdoc + rustdoc-json support for `feature(non_lifetime_binders)`

Makes `for<T> T: Trait` and `for<const N: usize> ..` in where clause operate correctly.

Fixes rust-lang#108158
  • Loading branch information
matthiaskrgr committed Mar 26, 2023
2 parents 48ae1b3 + f81cf4f commit 8df4141
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 29 deletions.
17 changes: 3 additions & 14 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use rustc_span::hygiene::{AstPass, MacroKind};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, ExpnKind};

use std::assert_matches::assert_matches;
use std::collections::hash_map::Entry;
use std::collections::BTreeMap;
use std::default::Default;
Expand Down Expand Up @@ -270,15 +269,7 @@ fn clean_where_predicate<'tcx>(
let bound_params = wbp
.bound_generic_params
.iter()
.map(|param| {
// Higher-ranked params must be lifetimes.
// Higher-ranked lifetimes can't have bounds.
assert_matches!(
param,
hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. }
);
Lifetime(param.name.ident().name)
})
.map(|param| clean_generic_param(cx, None, param))
.collect();
WherePredicate::BoundPredicate {
ty: clean_ty(wbp.bounded_ty, cx),
Expand Down Expand Up @@ -410,7 +401,7 @@ fn clean_projection_predicate<'tcx>(
.collect_referenced_late_bound_regions(&pred)
.into_iter()
.filter_map(|br| match br {
ty::BrNamed(_, name) if br.is_named() => Some(Lifetime(name)),
ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)),
_ => None,
})
.collect();
Expand Down Expand Up @@ -508,7 +499,6 @@ fn clean_generic_param_def<'tcx>(
ty::GenericParamDefKind::Const { has_default } => (
def.name,
GenericParamDefKind::Const {
did: def.def_id,
ty: Box::new(clean_middle_ty(
ty::Binder::dummy(
cx.tcx
Expand Down Expand Up @@ -578,7 +568,6 @@ fn clean_generic_param<'tcx>(
hir::GenericParamKind::Const { ty, default } => (
param.name.ident().name,
GenericParamDefKind::Const {
did: param.def_id.to_def_id(),
ty: Box::new(clean_ty(ty, cx)),
default: default
.map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())),
Expand Down Expand Up @@ -831,7 +820,7 @@ fn clean_ty_generics<'tcx>(
p.get_bound_params()
.into_iter()
.flatten()
.map(|param| GenericParamDef::lifetime(param.0))
.cloned()
.collect(),
));
}
Expand Down
6 changes: 1 addition & 5 deletions src/librustdoc/clean/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP
equalities.retain(|(lhs, rhs, bound_params)| {
let Some((ty, trait_did, name)) = lhs.projection() else { return true; };
let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
let bound_params = bound_params
.into_iter()
.map(|param| clean::GenericParamDef::lifetime(param.0))
.collect();
merge_bounds(cx, bounds, bound_params, trait_did, name, rhs)
merge_bounds(cx, bounds, bound_params.clone(), trait_did, name, rhs)
});

// And finally, let's reassemble everything
Expand Down
8 changes: 4 additions & 4 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,9 +1213,9 @@ impl Lifetime {

#[derive(Clone, Debug)]
pub(crate) enum WherePredicate {
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<GenericParamDef> },
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
EqPredicate { lhs: Box<Type>, rhs: Box<Term>, bound_params: Vec<Lifetime> },
EqPredicate { lhs: Box<Type>, rhs: Box<Term>, bound_params: Vec<GenericParamDef> },
}

impl WherePredicate {
Expand All @@ -1227,7 +1227,7 @@ impl WherePredicate {
}
}

pub(crate) fn get_bound_params(&self) -> Option<&[Lifetime]> {
pub(crate) fn get_bound_params(&self) -> Option<&[GenericParamDef]> {
match self {
Self::BoundPredicate { bound_params, .. } | Self::EqPredicate { bound_params, .. } => {
Some(bound_params)
Expand All @@ -1241,7 +1241,7 @@ impl WherePredicate {
pub(crate) enum GenericParamDefKind {
Lifetime { outlives: Vec<Lifetime> },
Type { did: DefId, bounds: Vec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
Const { did: DefId, ty: Box<Type>, default: Option<Box<String>> },
Const { ty: Box<Type>, default: Option<Box<String>> },
}

impl GenericParamDefKind {
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
write!(
f,
"for<{:#}> {ty_cx:#}: {generic_bounds:#}",
comma_sep(bound_params.iter().map(|lt| lt.print()), true)
comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true)
)
} else {
write!(
f,
"for&lt;{}&gt; {ty_cx}: {generic_bounds}",
comma_sep(bound_params.iter().map(|lt| lt.print()), true)
comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true)
)
}
}
Expand Down
34 changes: 30 additions & 4 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
default: default.map(|x| (*x).into_tcx(tcx)),
synthetic,
},
Const { did: _, ty, default } => GenericParamDefKind::Const {
Const { ty, default } => GenericParamDefKind::Const {
type_: (*ty).into_tcx(tcx),
default: default.map(|x| *x),
},
Expand All @@ -473,9 +473,35 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
bounds: bounds.into_tcx(tcx),
generic_params: bound_params
.into_iter()
.map(|x| GenericParamDef {
name: x.0.to_string(),
kind: GenericParamDefKind::Lifetime { outlives: vec![] },
.map(|x| {
let name = x.name.to_string();
let kind = match x.kind {
clean::GenericParamDefKind::Lifetime { outlives } => {
GenericParamDefKind::Lifetime {
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
}
}
clean::GenericParamDefKind::Type {
did: _,
bounds,
default,
synthetic,
} => GenericParamDefKind::Type {
bounds: bounds
.into_iter()
.map(|bound| bound.into_tcx(tcx))
.collect(),
default: default.map(|ty| (*ty).into_tcx(tcx)),
synthetic,
},
clean::GenericParamDefKind::Const { ty, default } => {
GenericParamDefKind::Const {
type_: (*ty).into_tcx(tcx),
default: default.map(|d| *d),
}
}
};
GenericParamDef { name, kind }
})
.collect(),
},
Expand Down
23 changes: 23 additions & 0 deletions tests/rustdoc-json/non_lifetime_binders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// ignore-tidy-linelength

#![feature(non_lifetime_binders)]
#![allow(incomplete_features)]

#![no_core]
#![feature(lang_items, no_core)]

#[lang = "sized"]
pub trait Sized {}

pub trait Trait {}

pub struct Wrapper<T_, const N_: usize>([T_; N_]);

// @count "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[*]" 3
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\"
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\"
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }'
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[2].name" \"N\"
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[2].kind" '{ "const": { "type": { "kind": "primitive", "inner": "usize" }, "default": null } }'
pub fn foo() where for<'a, T, const N: usize> &'a Wrapper<T, N>: Trait {}
9 changes: 9 additions & 0 deletions tests/rustdoc/non_lifetime_binders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(non_lifetime_binders)]
#![allow(incomplete_features)]

pub trait Trait {}

pub struct Wrapper<T, const N: usize>([T; N]);

// @has non_lifetime_binders/fn.foo.html '//pre' "fn foo()where for<'a, T, const N: usize> &'a Wrapper<T, N>: Trait"
pub fn foo() where for<'a, T, const N: usize> &'a Wrapper<T, N>: Trait {}

0 comments on commit 8df4141

Please sign in to comment.