rustdoc: use ThinVec for cleaned generics
This commit is contained in:
parent
edf0182213
commit
03968a802c
14 changed files with 67 additions and 71 deletions
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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 }),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue