From 03968a802c50decefd663692906397b44a95d8f6 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 11 Oct 2022 10:00:01 -0700 Subject: [PATCH] rustdoc: use ThinVec for cleaned generics --- Cargo.lock | 4 +- compiler/rustc_ast/Cargo.toml | 2 +- compiler/rustc_ast_lowering/Cargo.toml | 2 +- compiler/rustc_builtin_macros/Cargo.toml | 2 +- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_middle/Cargo.toml | 2 +- compiler/rustc_query_impl/Cargo.toml | 2 +- compiler/rustc_query_system/Cargo.toml | 2 +- compiler/rustc_serialize/Cargo.toml | 2 +- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/clean/auto_trait.rs | 11 +-- src/librustdoc/clean/mod.rs | 96 +++++++++++------------ src/librustdoc/clean/simplify.rs | 5 +- src/librustdoc/clean/types.rs | 4 +- 14 files changed, 67 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33b1299976f..1a91898be4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4887,9 +4887,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thin-vec" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "104c2cb3180b6fb6d5b2278768e9b88b578d32ba751ea6e8d026688a40d7ed87" +checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b" [[package]] name = "thiserror" diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index fcbf9681825..9253b7e6891 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index ce1c8d4997d..6a59b9e6151 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 6469d0d7b88..467fa932a15 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 9daa21ef6b1..5152d5ab046 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -25,7 +25,7 @@ smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dang stable_deref_trait = "1.0.0" stacker = "0.1.14" tempfile = "3.2" -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [dependencies.parking_lot] diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index de916ea8c49..8e7d0cf2ab1 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -32,7 +32,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [features] diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index e7f12caaf33..b2111a1262a 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -21,7 +21,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [features] diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index faddad74171..028756b5a0a 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -22,7 +22,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [features] diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 3b0b3144f2c..db0ef73544f 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] indexmap = "1.9.1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" [dev-dependencies] rustc_macros = { path = "../rustc_macros" } diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 7bc35c7d551..0da69202e67 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -20,7 +20,7 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } smallvec = "1.8.1" tempfile = "3" -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" tracing-tree = "0.2.0" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 00bdbe41ee4..84e77e69ecf 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable}; use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; +use thin_vec::ThinVec; use std::fmt::Debug; @@ -110,7 +111,7 @@ where ); let params = raw_generics.params; - Generics { params, where_predicates: Vec::new() } + Generics { params, where_predicates: ThinVec::new() } } AutoTraitResult::ExplicitImpl => return None, }; @@ -183,7 +184,7 @@ where fn handle_lifetimes<'cx>( regions: &RegionConstraintData<'cx>, names_map: &FxHashMap, - ) -> Vec { + ) -> ThinVec { // Our goal is to 'flatten' the list of constraints by eliminating // all intermediate RegionVids. At the end, all constraints should // be between Regions (aka region variables). This gives us the information @@ -429,7 +430,7 @@ where &mut self, item_def_id: DefId, param_env: ty::ParamEnv<'tcx>, - mut existing_predicates: Vec, + mut existing_predicates: ThinVec, vid_to_region: FxHashMap>, ) -> Generics { debug!( @@ -663,7 +664,7 @@ where /// both for visual consistency between 'rustdoc' runs, and to /// make writing tests much easier #[inline] - fn sort_where_predicates(&self, predicates: &mut Vec) { + fn sort_where_predicates(&self, predicates: &mut [WherePredicate]) { // We should never have identical bounds - and if we do, // they're visually identical as well. Therefore, using // an unstable sort is fine. @@ -710,7 +711,7 @@ where /// approach is probably somewhat slower, but the small number of items /// involved (impls rarely have more than a few bounds) means that it /// shouldn't matter in practice. - fn unstable_debug_sort(&self, vec: &mut Vec) { + fn unstable_debug_sort(&self, vec: &mut [T]) { vec.sort_by_cached_key(|x| format!("{:?}", x)) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1ce0d1e4ffd..32aa49d4a59 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -601,7 +601,7 @@ pub(crate) fn clean_generics<'tcx>( }) .collect::>(); - 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)) { let p = clean_generic_param(cx, Some(gens), p); params.push(p); @@ -675,7 +675,7 @@ fn clean_ty_generics<'tcx>( } ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)), }) - .collect::>(); + .collect::>(); // param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)] let mut impl_trait_proj = @@ -1211,56 +1211,47 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( tcx.generics_of(assoc_item.def_id), ty::GenericPredicates { parent: None, predicates }, ); - // Move bounds that are (likely) directly attached to the associated type - // from the where clause to the associated type. - // There is no guarantee that this is what the user actually wrote but we have - // no way of knowing. - let mut bounds = generics - .where_predicates - .drain_filter(|pred| match *pred { - WherePredicate::BoundPredicate { - ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), - .. - } => { - if assoc.name != my_name { - return false; - } - if trait_.def_id() != assoc_item.container_id(tcx) { - return false; - } - match *self_type { - Generic(ref s) if *s == kw::SelfUpper => {} - _ => return false, - } - match &assoc.args { - GenericArgs::AngleBracketed { args, bindings } => { - if !bindings.is_empty() - || generics - .params - .iter() - .zip(args.iter()) - .any(|(param, arg)| !param_eq_arg(param, arg)) - { - 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. + // Filter out the bounds that are (likely?) directly attached to the associated type, + // as opposed to being located in the where clause. + let mut bounds: Vec = Vec::new(); + generics.where_predicates.retain_mut(|pred| match *pred { + WherePredicate::BoundPredicate { + ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), + bounds: ref mut pred_bounds, + .. + } => { + if assoc.name != my_name { + return true; + } + if trait_.def_id() != assoc_item.container_id(tcx) { + return true; + } + match *self_type { + Generic(ref s) if *s == kw::SelfUpper => {} + _ => return true, + } + match &assoc.args { + GenericArgs::AngleBracketed { args, bindings } => { + if !bindings.is_empty() + || generics + .params + .iter() + .zip(args.iter()) + .any(|(param, arg)| !param_eq_arg(param, arg)) + { + return true; } } - 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, - }) - .flat_map(|pred| { - if let WherePredicate::BoundPredicate { bounds, .. } = pred { - bounds - } else { - unreachable!() - } - }) - .collect::>(); + bounds.extend(mem::replace(pred_bounds, Vec::new())); + false + } + _ => true, + }); // 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 // (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. // There is no guarantee that this is what the user actually wrote but we have // no way of knowing. - let mut where_predicates = Vec::new(); + let mut where_predicates = ThinVec::new(); for mut pred in generics.where_predicates { if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred && let Some(GenericParamDef { @@ -1317,7 +1308,10 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( cx, 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, }), Vec::new(), diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 1bcb9fcd5a4..1c184f9b269 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -14,13 +14,14 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use rustc_middle::ty; +use thin_vec::ThinVec; use crate::clean; use crate::clean::GenericArgs as PP; use crate::clean::WherePredicate as WP; use crate::core::DocContext; -pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { +pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec { // First, partition the where clause into its separate components. // // 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) -> Vec { }); // 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( lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }), ); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 439311f0640..e4a8b5c9d18 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1462,8 +1462,8 @@ impl GenericParamDef { // maybe use a Generic enum and use Vec? #[derive(Clone, Debug, Default)] pub(crate) struct Generics { - pub(crate) params: Vec, - pub(crate) where_predicates: Vec, + pub(crate) params: ThinVec, + pub(crate) where_predicates: ThinVec, } impl Generics {