mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 09:44:08 +00:00
Remove a Clean impl for a tuple (3)
This commit is contained in:
parent
63d434a363
commit
927a5e393c
@ -100,9 +100,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
// Instead, we generate `impl !Send for Foo<T>`, which better
|
||||
// expresses the fact that `Foo<T>` never implements `Send`,
|
||||
// regardless of the choice of `T`.
|
||||
let params = (tcx.generics_of(item_def_id), ty::GenericPredicates::default())
|
||||
.clean(self.cx)
|
||||
.params;
|
||||
let raw_generics = clean_ty_generics(
|
||||
self.cx,
|
||||
tcx.generics_of(item_def_id),
|
||||
ty::GenericPredicates::default(),
|
||||
);
|
||||
let params = raw_generics.params;
|
||||
|
||||
Generics { params, where_predicates: Vec::new() }
|
||||
}
|
||||
@ -451,10 +454,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
})
|
||||
.map(|p| p.fold_with(&mut replacer));
|
||||
|
||||
let mut generic_params =
|
||||
(tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id))
|
||||
.clean(self.cx)
|
||||
.params;
|
||||
let raw_generics = clean_ty_generics(
|
||||
self.cx,
|
||||
tcx.generics_of(item_def_id),
|
||||
tcx.explicit_predicates_of(item_def_id),
|
||||
);
|
||||
let mut generic_params = raw_generics.params;
|
||||
|
||||
debug!("param_env_to_generics({:?}): generic_params={:?}", item_def_id, generic_params);
|
||||
|
||||
|
@ -107,11 +107,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
|
||||
kind: box ImplItem(Impl {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
generics: (
|
||||
generics: clean_ty_generics(
|
||||
self.cx,
|
||||
self.cx.tcx.generics_of(impl_def_id),
|
||||
self.cx.tcx.explicit_predicates_of(impl_def_id),
|
||||
)
|
||||
.clean(self.cx),
|
||||
),
|
||||
// FIXME(eddyb) compute both `trait_` and `for_` from
|
||||
// the post-inference `trait_ref`, as it's more accurate.
|
||||
trait_: Some(trait_ref.clean(self.cx)),
|
||||
|
@ -15,13 +15,12 @@ use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
|
||||
use crate::clean::{
|
||||
self, utils, Attributes, AttributesExt, ImplKind, ItemId, NestedAttributesExt, Type,
|
||||
self, clean_ty_generics, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId,
|
||||
NestedAttributesExt, Type, Visibility,
|
||||
};
|
||||
use crate::core::DocContext;
|
||||
use crate::formats::item_type::ItemType;
|
||||
|
||||
use super::{Clean, Visibility};
|
||||
|
||||
type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
|
||||
|
||||
/// Attempt to inline a definition into this AST.
|
||||
@ -208,7 +207,7 @@ crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Tra
|
||||
.collect();
|
||||
|
||||
let predicates = cx.tcx.predicates_of(did);
|
||||
let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
|
||||
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
|
||||
let generics = filter_non_trait_generics(did, generics);
|
||||
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
|
||||
let is_auto = cx.tcx.trait_is_auto(did);
|
||||
@ -230,7 +229,9 @@ fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Functi
|
||||
let predicates = cx.tcx.predicates_of(did);
|
||||
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics need to be cleaned before the decl!
|
||||
((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
|
||||
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
|
||||
let decl = (did, sig).clean(cx);
|
||||
(generics, decl)
|
||||
});
|
||||
clean::Function {
|
||||
decl,
|
||||
@ -243,7 +244,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
|
||||
let predicates = cx.tcx.explicit_predicates_of(did);
|
||||
|
||||
clean::Enum {
|
||||
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
|
||||
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
|
||||
variants_stripped: false,
|
||||
variants: cx.tcx.adt_def(did).variants.iter().map(|v| v.clean(cx)).collect(),
|
||||
}
|
||||
@ -255,7 +256,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
|
||||
|
||||
clean::Struct {
|
||||
struct_type: variant.ctor_kind,
|
||||
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
|
||||
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
|
||||
fields: variant.fields.iter().map(|x| x.clean(cx)).collect(),
|
||||
fields_stripped: false,
|
||||
}
|
||||
@ -265,7 +266,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
|
||||
let predicates = cx.tcx.explicit_predicates_of(did);
|
||||
let variant = cx.tcx.adt_def(did).non_enum_variant();
|
||||
|
||||
let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
|
||||
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
|
||||
let fields = variant.fields.iter().map(|x| x.clean(cx)).collect();
|
||||
clean::Union { generics, fields, fields_stripped: false }
|
||||
}
|
||||
@ -276,7 +277,7 @@ fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
|
||||
|
||||
clean::Typedef {
|
||||
type_,
|
||||
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
|
||||
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
|
||||
item_type: None,
|
||||
}
|
||||
}
|
||||
@ -440,7 +441,9 @@ crate fn build_impl(
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
clean::enter_impl_trait(cx, |cx| (tcx.generics_of(did), predicates).clean(cx)),
|
||||
clean::enter_impl_trait(cx, |cx| {
|
||||
clean_ty_generics(cx, tcx.generics_of(did), predicates)
|
||||
}),
|
||||
),
|
||||
};
|
||||
let polarity = tcx.impl_polarity(did);
|
||||
|
@ -522,170 +522,167 @@ impl Clean<Generics> for hir::Generics<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> Generics {
|
||||
use self::WherePredicate as WP;
|
||||
use std::collections::BTreeMap;
|
||||
fn clean_ty_generics(
|
||||
cx: &mut DocContext<'_>,
|
||||
gens: &ty::Generics,
|
||||
preds: ty::GenericPredicates<'tcx>,
|
||||
) -> Generics {
|
||||
use self::WherePredicate as WP;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let (gens, preds) = *self;
|
||||
// Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
|
||||
// since `Clean for ty::Predicate` would consume them.
|
||||
let mut impl_trait = BTreeMap::<ImplTraitParam, Vec<GenericBound>>::default();
|
||||
|
||||
// Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
|
||||
// since `Clean for ty::Predicate` would consume them.
|
||||
let mut impl_trait = BTreeMap::<ImplTraitParam, Vec<GenericBound>>::default();
|
||||
|
||||
// Bounds in the type_params and lifetimes fields are repeated in the
|
||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||
// them.
|
||||
let stripped_params = gens
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
|
||||
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
||||
if param.name == kw::SelfUpper {
|
||||
assert_eq!(param.index, 0);
|
||||
return None;
|
||||
}
|
||||
if synthetic {
|
||||
impl_trait.insert(param.index.into(), vec![]);
|
||||
return None;
|
||||
}
|
||||
Some(param.clean(cx))
|
||||
// Bounds in the type_params and lifetimes fields are repeated in the
|
||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||
// them.
|
||||
let stripped_params = gens
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
|
||||
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
||||
if param.name == kw::SelfUpper {
|
||||
assert_eq!(param.index, 0);
|
||||
return None;
|
||||
}
|
||||
ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
|
||||
})
|
||||
.collect::<Vec<GenericParamDef>>();
|
||||
if synthetic {
|
||||
impl_trait.insert(param.index.into(), vec![]);
|
||||
return None;
|
||||
}
|
||||
Some(param.clean(cx))
|
||||
}
|
||||
ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
|
||||
})
|
||||
.collect::<Vec<GenericParamDef>>();
|
||||
|
||||
// param index -> [(DefId of trait, associated type name, type)]
|
||||
let mut impl_trait_proj = FxHashMap::<u32, Vec<(DefId, Symbol, Ty<'tcx>)>>::default();
|
||||
// param index -> [(DefId of trait, associated type name, type)]
|
||||
let mut impl_trait_proj = FxHashMap::<u32, Vec<(DefId, Symbol, Ty<'tcx>)>>::default();
|
||||
|
||||
let where_predicates = preds
|
||||
.predicates
|
||||
.iter()
|
||||
.flat_map(|(p, _)| {
|
||||
let mut projection = None;
|
||||
let param_idx = (|| {
|
||||
let bound_p = p.kind();
|
||||
match bound_p.skip_binder() {
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
if let ty::Param(param) = pred.self_ty().kind() {
|
||||
return Some(param.index);
|
||||
}
|
||||
let where_predicates = preds
|
||||
.predicates
|
||||
.iter()
|
||||
.flat_map(|(p, _)| {
|
||||
let mut projection = None;
|
||||
let param_idx = (|| {
|
||||
let bound_p = p.kind();
|
||||
match bound_p.skip_binder() {
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
if let ty::Param(param) = pred.self_ty().kind() {
|
||||
return Some(param.index);
|
||||
}
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
||||
if let ty::Param(param) = ty.kind() {
|
||||
return Some(param.index);
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::Projection(p) => {
|
||||
if let ty::Param(param) = p.projection_ty.self_ty().kind() {
|
||||
projection = Some(bound_p.rebind(p));
|
||||
return Some(param.index);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
None
|
||||
})();
|
||||
|
||||
if let Some(param_idx) = param_idx {
|
||||
if let Some(b) = impl_trait.get_mut(¶m_idx.into()) {
|
||||
let p = p.clean(cx)?;
|
||||
|
||||
b.extend(
|
||||
p.get_bounds()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.cloned()
|
||||
.filter(|b| !b.is_sized_bound(cx)),
|
||||
);
|
||||
|
||||
let proj = projection
|
||||
.map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
|
||||
if let Some(((_, trait_did, name), rhs)) =
|
||||
proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
|
||||
{
|
||||
impl_trait_proj
|
||||
.entry(param_idx)
|
||||
.or_default()
|
||||
.push((trait_did, name, rhs));
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
||||
if let ty::Param(param) = ty.kind() {
|
||||
return Some(param.index);
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
ty::PredicateKind::Projection(p) => {
|
||||
if let ty::Param(param) = p.projection_ty.self_ty().kind() {
|
||||
projection = Some(bound_p.rebind(p));
|
||||
return Some(param.index);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Some(p)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
None
|
||||
})();
|
||||
|
||||
for (param, mut bounds) in impl_trait {
|
||||
// Move trait bounds to the front.
|
||||
bounds.sort_by_key(|b| !matches!(b, GenericBound::TraitBound(..)));
|
||||
if let Some(param_idx) = param_idx {
|
||||
if let Some(b) = impl_trait.get_mut(¶m_idx.into()) {
|
||||
let p = p.clean(cx)?;
|
||||
|
||||
if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
|
||||
if let Some(proj) = impl_trait_proj.remove(&idx) {
|
||||
for (trait_did, name, rhs) in proj {
|
||||
let rhs = rhs.clean(cx);
|
||||
simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs);
|
||||
b.extend(
|
||||
p.get_bounds()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.cloned()
|
||||
.filter(|b| !b.is_sized_bound(cx)),
|
||||
);
|
||||
|
||||
let proj = projection
|
||||
.map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
|
||||
if let Some(((_, trait_did, name), rhs)) =
|
||||
proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
|
||||
{
|
||||
impl_trait_proj.entry(param_idx).or_default().push((trait_did, name, rhs));
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(p)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (param, mut bounds) in impl_trait {
|
||||
// Move trait bounds to the front.
|
||||
bounds.sort_by_key(|b| !matches!(b, GenericBound::TraitBound(..)));
|
||||
|
||||
if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
|
||||
if let Some(proj) = impl_trait_proj.remove(&idx) {
|
||||
for (trait_did, name, rhs) in proj {
|
||||
let rhs = rhs.clean(cx);
|
||||
simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
cx.impl_trait_bounds.insert(param, bounds);
|
||||
}
|
||||
|
||||
// Now that `cx.impl_trait_bounds` is populated, we can process
|
||||
// remaining predicates which could contain `impl Trait`.
|
||||
let mut where_predicates =
|
||||
where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::<Vec<_>>();
|
||||
|
||||
// Type parameters have a Sized bound by default unless removed with
|
||||
// ?Sized. Scan through the predicates and mark any type parameter with
|
||||
// a Sized bound, removing the bounds as we find them.
|
||||
//
|
||||
// Note that associated types also have a sized bound by default, but we
|
||||
// don't actually know the set of associated types right here so that's
|
||||
// handled in cleaning associated types
|
||||
let mut sized_params = FxHashSet::default();
|
||||
where_predicates.retain(|pred| match *pred {
|
||||
WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => {
|
||||
if bounds.iter().any(|b| b.is_sized_bound(cx)) {
|
||||
sized_params.insert(*g);
|
||||
false
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
cx.impl_trait_bounds.insert(param, bounds);
|
||||
}
|
||||
|
||||
// Now that `cx.impl_trait_bounds` is populated, we can process
|
||||
// remaining predicates which could contain `impl Trait`.
|
||||
let mut where_predicates =
|
||||
where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::<Vec<_>>();
|
||||
|
||||
// Type parameters have a Sized bound by default unless removed with
|
||||
// ?Sized. Scan through the predicates and mark any type parameter with
|
||||
// a Sized bound, removing the bounds as we find them.
|
||||
//
|
||||
// Note that associated types also have a sized bound by default, but we
|
||||
// don't actually know the set of associated types right here so that's
|
||||
// handled in cleaning associated types
|
||||
let mut sized_params = FxHashSet::default();
|
||||
where_predicates.retain(|pred| match *pred {
|
||||
WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => {
|
||||
if bounds.iter().any(|b| b.is_sized_bound(cx)) {
|
||||
sized_params.insert(*g);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
_ => true,
|
||||
});
|
||||
|
||||
// Run through the type parameters again and insert a ?Sized
|
||||
// unbound for any we didn't find to be Sized.
|
||||
for tp in &stripped_params {
|
||||
if matches!(tp.kind, types::GenericParamDefKind::Type { .. })
|
||||
&& !sized_params.contains(&tp.name)
|
||||
{
|
||||
where_predicates.push(WP::BoundPredicate {
|
||||
ty: Type::Generic(tp.name),
|
||||
bounds: vec![GenericBound::maybe_sized(cx)],
|
||||
bound_params: Vec::new(),
|
||||
})
|
||||
true
|
||||
}
|
||||
}
|
||||
_ => true,
|
||||
});
|
||||
|
||||
// It would be nice to collect all of the bounds on a type and recombine
|
||||
// them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a`
|
||||
// and instead see `where T: Foo + Bar + Sized + 'a`
|
||||
|
||||
Generics {
|
||||
params: stripped_params,
|
||||
where_predicates: simplify::where_clauses(cx, where_predicates),
|
||||
// Run through the type parameters again and insert a ?Sized
|
||||
// unbound for any we didn't find to be Sized.
|
||||
for tp in &stripped_params {
|
||||
if matches!(tp.kind, types::GenericParamDefKind::Type { .. })
|
||||
&& !sized_params.contains(&tp.name)
|
||||
{
|
||||
where_predicates.push(WP::BoundPredicate {
|
||||
ty: Type::Generic(tp.name),
|
||||
bounds: vec![GenericBound::maybe_sized(cx)],
|
||||
bound_params: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// It would be nice to collect all of the bounds on a type and recombine
|
||||
// them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a`
|
||||
// and instead see `where T: Foo + Bar + Sized + 'a`
|
||||
|
||||
Generics {
|
||||
params: stripped_params,
|
||||
where_predicates: simplify::where_clauses(cx, where_predicates),
|
||||
}
|
||||
}
|
||||
|
||||
fn clean_fn_or_proc_macro(
|
||||
@ -1007,9 +1004,11 @@ impl Clean<Item> for ty::AssocItem {
|
||||
AssocConstItem(ty.clean(cx), default)
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
let generics =
|
||||
(tcx.generics_of(self.def_id), tcx.explicit_predicates_of(self.def_id))
|
||||
.clean(cx);
|
||||
let generics = clean_ty_generics(
|
||||
cx,
|
||||
tcx.generics_of(self.def_id),
|
||||
tcx.explicit_predicates_of(self.def_id),
|
||||
);
|
||||
let sig = tcx.fn_sig(self.def_id);
|
||||
let mut decl = (self.def_id, sig).clean(cx);
|
||||
|
||||
@ -1080,7 +1079,7 @@ impl Clean<Item> for ty::AssocItem {
|
||||
if let ty::TraitContainer(_) = self.container {
|
||||
let bounds = tcx.explicit_item_bounds(self.def_id);
|
||||
let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
|
||||
let generics = (tcx.generics_of(self.def_id), predicates).clean(cx);
|
||||
let generics = clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates);
|
||||
let mut bounds = generics
|
||||
.where_predicates
|
||||
.iter()
|
||||
|
Loading…
Reference in New Issue
Block a user