1
Fork 0

rustdoc: use ThinVec for cleaned generics

This commit is contained in:
Michael Howell 2022-10-11 10:00:01 -07:00
parent edf0182213
commit 03968a802c
14 changed files with 67 additions and 71 deletions

View file

@ -4887,9 +4887,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "thin-vec" name = "thin-vec"
version = "0.2.8" version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "104c2cb3180b6fb6d5b2278768e9b88b578d32ba751ea6e8d026688a40d7ed87" checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b"
[[package]] [[package]]
name = "thiserror" name = "thiserror"

View file

@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" } rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View file

@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View file

@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View file

@ -25,7 +25,7 @@ smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dang
stable_deref_trait = "1.0.0" stable_deref_trait = "1.0.0"
stacker = "0.1.14" stacker = "0.1.14"
tempfile = "3.2" tempfile = "3.2"
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"
[dependencies.parking_lot] [dependencies.parking_lot]

View file

@ -32,7 +32,7 @@ rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
rustc_type_ir = { path = "../rustc_type_ir" } rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"
[features] [features]

View file

@ -21,7 +21,7 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" } rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"
[features] [features]

View file

@ -22,7 +22,7 @@ rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
rustc_type_ir = { path = "../rustc_type_ir" } rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"
[features] [features]

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
indexmap = "1.9.1" indexmap = "1.9.1"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
[dev-dependencies] [dev-dependencies]
rustc_macros = { path = "../rustc_macros" } rustc_macros = { path = "../rustc_macros" }

View file

@ -20,7 +20,7 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
smallvec = "1.8.1" smallvec = "1.8.1"
tempfile = "3" tempfile = "3"
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"
tracing-tree = "0.2.0" tracing-tree = "0.2.0"

View file

@ -3,6 +3,7 @@ use rustc_hir as hir;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable};
use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult};
use thin_vec::ThinVec;
use std::fmt::Debug; use std::fmt::Debug;
@ -110,7 +111,7 @@ where
); );
let params = raw_generics.params; let params = raw_generics.params;
Generics { params, where_predicates: Vec::new() } Generics { params, where_predicates: ThinVec::new() }
} }
AutoTraitResult::ExplicitImpl => return None, AutoTraitResult::ExplicitImpl => return None,
}; };
@ -183,7 +184,7 @@ where
fn handle_lifetimes<'cx>( fn handle_lifetimes<'cx>(
regions: &RegionConstraintData<'cx>, regions: &RegionConstraintData<'cx>,
names_map: &FxHashMap<Symbol, Lifetime>, names_map: &FxHashMap<Symbol, Lifetime>,
) -> Vec<WherePredicate> { ) -> ThinVec<WherePredicate> {
// Our goal is to 'flatten' the list of constraints by eliminating // Our goal is to 'flatten' the list of constraints by eliminating
// all intermediate RegionVids. At the end, all constraints should // all intermediate RegionVids. At the end, all constraints should
// be between Regions (aka region variables). This gives us the information // be between Regions (aka region variables). This gives us the information
@ -429,7 +430,7 @@ where
&mut self, &mut self,
item_def_id: DefId, item_def_id: DefId,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
mut existing_predicates: Vec<WherePredicate>, mut existing_predicates: ThinVec<WherePredicate>,
vid_to_region: FxHashMap<ty::RegionVid, ty::Region<'tcx>>, vid_to_region: FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
) -> Generics { ) -> Generics {
debug!( debug!(
@ -663,7 +664,7 @@ where
/// both for visual consistency between 'rustdoc' runs, and to /// both for visual consistency between 'rustdoc' runs, and to
/// make writing tests much easier /// make writing tests much easier
#[inline] #[inline]
fn sort_where_predicates(&self, predicates: &mut Vec<WherePredicate>) { fn sort_where_predicates(&self, predicates: &mut [WherePredicate]) {
// We should never have identical bounds - and if we do, // We should never have identical bounds - and if we do,
// they're visually identical as well. Therefore, using // they're visually identical as well. Therefore, using
// an unstable sort is fine. // an unstable sort is fine.
@ -710,7 +711,7 @@ where
/// approach is probably somewhat slower, but the small number of items /// approach is probably somewhat slower, but the small number of items
/// involved (impls rarely have more than a few bounds) means that it /// involved (impls rarely have more than a few bounds) means that it
/// shouldn't matter in practice. /// shouldn't matter in practice.
fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) { fn unstable_debug_sort<T: Debug>(&self, vec: &mut [T]) {
vec.sort_by_cached_key(|x| format!("{:?}", x)) vec.sort_by_cached_key(|x| format!("{:?}", x))
} }

View file

@ -601,7 +601,7 @@ pub(crate) fn clean_generics<'tcx>(
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut params = Vec::with_capacity(gens.params.len()); let mut params = ThinVec::with_capacity(gens.params.len());
for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
let p = clean_generic_param(cx, Some(gens), p); let p = clean_generic_param(cx, Some(gens), p);
params.push(p); params.push(p);
@ -675,7 +675,7 @@ fn clean_ty_generics<'tcx>(
} }
ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)), ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)),
}) })
.collect::<Vec<GenericParamDef>>(); .collect::<ThinVec<GenericParamDef>>();
// param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)] // param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)]
let mut impl_trait_proj = let mut impl_trait_proj =
@ -1211,56 +1211,47 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
tcx.generics_of(assoc_item.def_id), tcx.generics_of(assoc_item.def_id),
ty::GenericPredicates { parent: None, predicates }, ty::GenericPredicates { parent: None, predicates },
); );
// Move bounds that are (likely) directly attached to the associated type // Filter out the bounds that are (likely?) directly attached to the associated type,
// from the where clause to the associated type. // as opposed to being located in the where clause.
// There is no guarantee that this is what the user actually wrote but we have let mut bounds: Vec<GenericBound> = Vec::new();
// no way of knowing. generics.where_predicates.retain_mut(|pred| match *pred {
let mut bounds = generics WherePredicate::BoundPredicate {
.where_predicates ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }),
.drain_filter(|pred| match *pred { bounds: ref mut pred_bounds,
WherePredicate::BoundPredicate { ..
ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), } => {
.. if assoc.name != my_name {
} => { return true;
if assoc.name != my_name { }
return false; if trait_.def_id() != assoc_item.container_id(tcx) {
} return true;
if trait_.def_id() != assoc_item.container_id(tcx) { }
return false; match *self_type {
} Generic(ref s) if *s == kw::SelfUpper => {}
match *self_type { _ => return true,
Generic(ref s) if *s == kw::SelfUpper => {} }
_ => return false, match &assoc.args {
} GenericArgs::AngleBracketed { args, bindings } => {
match &assoc.args { if !bindings.is_empty()
GenericArgs::AngleBracketed { args, bindings } => { || generics
if !bindings.is_empty() .params
|| generics .iter()
.params .zip(args.iter())
.iter() .any(|(param, arg)| !param_eq_arg(param, arg))
.zip(args.iter()) {
.any(|(param, arg)| !param_eq_arg(param, arg)) return true;
{
return false;
}
}
GenericArgs::Parenthesized { .. } => {
// The only time this happens is if we're inside the rustdoc for Fn(),
// which only has one associated type, which is not a GAT, so whatever.
} }
} }
true GenericArgs::Parenthesized { .. } => {
// The only time this happens is if we're inside the rustdoc for Fn(),
// which only has one associated type, which is not a GAT, so whatever.
}
} }
_ => false, bounds.extend(mem::replace(pred_bounds, Vec::new()));
}) false
.flat_map(|pred| { }
if let WherePredicate::BoundPredicate { bounds, .. } = pred { _ => true,
bounds });
} else {
unreachable!()
}
})
.collect::<Vec<_>>();
// Our Sized/?Sized bound didn't get handled when creating the generics // Our Sized/?Sized bound didn't get handled when creating the generics
// because we didn't actually get our whole set of bounds until just now // because we didn't actually get our whole set of bounds until just now
// (some of them may have come from the trait). If we do have a sized // (some of them may have come from the trait). If we do have a sized
@ -1276,7 +1267,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
// (generic) associated type from the where clause to the respective parameter. // (generic) associated type from the where clause to the respective parameter.
// There is no guarantee that this is what the user actually wrote but we have // There is no guarantee that this is what the user actually wrote but we have
// no way of knowing. // no way of knowing.
let mut where_predicates = Vec::new(); let mut where_predicates = ThinVec::new();
for mut pred in generics.where_predicates { for mut pred in generics.where_predicates {
if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred
&& let Some(GenericParamDef { && let Some(GenericParamDef {
@ -1317,7 +1308,10 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
cx, cx,
Some(assoc_item.def_id), Some(assoc_item.def_id),
), ),
generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, generics: Generics {
params: ThinVec::new(),
where_predicates: ThinVec::new(),
},
item_type: None, item_type: None,
}), }),
Vec::new(), Vec::new(),

View file

@ -14,13 +14,14 @@
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::ty; use rustc_middle::ty;
use thin_vec::ThinVec;
use crate::clean; use crate::clean;
use crate::clean::GenericArgs as PP; use crate::clean::GenericArgs as PP;
use crate::clean::WherePredicate as WP; use crate::clean::WherePredicate as WP;
use crate::core::DocContext; use crate::core::DocContext;
pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> { pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP> {
// First, partition the where clause into its separate components. // First, partition the where clause into its separate components.
// //
// We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to
@ -59,7 +60,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
}); });
// And finally, let's reassemble everything // And finally, let's reassemble everything
let mut clauses = Vec::new(); let mut clauses = ThinVec::with_capacity(lifetimes.len() + tybounds.len() + equalities.len());
clauses.extend( clauses.extend(
lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }), lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
); );

View file

@ -1462,8 +1462,8 @@ impl GenericParamDef {
// maybe use a Generic enum and use Vec<Generic>? // maybe use a Generic enum and use Vec<Generic>?
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub(crate) struct Generics { pub(crate) struct Generics {
pub(crate) params: Vec<GenericParamDef>, pub(crate) params: ThinVec<GenericParamDef>,
pub(crate) where_predicates: Vec<WherePredicate>, pub(crate) where_predicates: ThinVec<WherePredicate>,
} }
impl Generics { impl Generics {