From b1745c3919b57d841c15fe0bfb0dd926ab59bafa Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Wed, 25 Sep 2024 22:15:23 +0200 Subject: [PATCH] de-rc external traits Don't keep the `external_traits` as shared mutable data between the `DocContext` and `clean::Crate`. Instead, move the data over when necessary. This allows us to get rid of a borrowck hack in the `DocVisitor`. --- src/librustdoc/clean/inline.rs | 5 ++--- src/librustdoc/clean/types.rs | 4 +--- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/core.rs | 6 ++---- src/librustdoc/fold.rs | 11 +++++++---- src/librustdoc/formats/cache.rs | 3 ++- src/librustdoc/passes/collect_trait_impls.rs | 2 ++ src/librustdoc/visit.rs | 7 ++----- 8 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index b7d6b3dda72..d3c4ef4dc90 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -837,8 +837,7 @@ pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { } { - if cx.external_traits.borrow().contains_key(&did) || cx.active_extern_traits.contains(&did) - { + if cx.external_traits.contains_key(&did) || cx.active_extern_traits.contains(&did) { return; } } @@ -850,6 +849,6 @@ pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { debug!("record_extern_trait: {did:?}"); let trait_ = build_external_trait(cx, did); - cx.external_traits.borrow_mut().insert(did, trait_); + cx.external_traits.insert(did, trait_); cx.active_extern_traits.remove(&did); } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bc6b5a7d3e3..69a414ae989 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,8 +1,6 @@ use std::borrow::Cow; -use std::cell::RefCell; use std::hash::Hash; use std::path::PathBuf; -use std::rc::Rc; use std::sync::{Arc, OnceLock as OnceCell}; use std::{fmt, iter}; @@ -115,7 +113,7 @@ fn from(id: DefId) -> Self { pub(crate) struct Crate { pub(crate) module: Item, /// Only here so that they can be filtered through the rustdoc passes. - pub(crate) external_traits: Rc>>, + pub(crate) external_traits: Box>, } impl Crate { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b91c1725d0c..fdf628b50fb 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -74,7 +74,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { })); } - Crate { module, external_traits: cx.external_traits.clone() } + Crate { module, external_traits: Box::new(mem::take(&mut cx.external_traits)) } } pub(crate) fn clean_middle_generic_args<'tcx>( diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8e46d93c28e..4c48c075a94 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -1,5 +1,3 @@ -use std::cell::RefCell; -use std::rc::Rc; use std::sync::atomic::AtomicBool; use std::sync::{Arc, LazyLock}; use std::{io, mem}; @@ -41,7 +39,7 @@ pub(crate) struct DocContext<'tcx> { /// Most of this logic is copied from rustc_lint::late. pub(crate) param_env: ParamEnv<'tcx>, /// Later on moved through `clean::Crate` into `cache` - pub(crate) external_traits: Rc>>, + pub(crate) external_traits: FxHashMap, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. pub(crate) active_extern_traits: DefIdSet, @@ -359,7 +357,7 @@ pub(crate) fn run_global_ctxt( // Note that in case of `#![no_core]`, the trait is not available. if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() { let sized_trait = build_external_trait(&mut ctxt, sized_trait_did); - ctxt.external_traits.borrow_mut().insert(sized_trait_did, sized_trait); + ctxt.external_traits.insert(sized_trait_did, sized_trait); } debug!("crate: {:?}", tcx.hir().krate()); diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index c25a4ddb6f3..95e495205ae 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -1,3 +1,5 @@ +use std::mem; + use crate::clean::*; pub(crate) fn strip_item(mut item: Item) -> Item { @@ -116,10 +118,11 @@ fn fold_mod(&mut self, m: Module) -> Module { fn fold_crate(&mut self, mut c: Crate) -> Crate { c.module = self.fold_item(c.module).unwrap(); - let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) }; - for (k, mut v) in external_traits { - v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect(); - c.external_traits.borrow_mut().insert(k, v); + for trait_ in c.external_traits.values_mut() { + trait_.items = mem::take(&mut trait_.items) + .into_iter() + .filter_map(|i| self.fold_item(i)) + .collect(); } c diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 8597d2e2b63..db1a0bd0af9 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -153,7 +153,8 @@ pub(crate) fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clea // Crawl the crate to build various caches used for the output debug!(?cx.cache.crate_version); - cx.cache.traits = krate.external_traits.take(); + assert!(cx.external_traits.is_empty()); + cx.cache.traits = mem::take(&mut krate.external_traits); // Cache where all our extern crates are located // FIXME: this part is specific to HTML so it'd be nice to remove it from the common code diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index a9edc485d5e..949ba548387 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -219,6 +219,8 @@ fn add_deref_target( panic!("collect-trait-impls can't run"); }; + krate.external_traits.extend(cx.external_traits.drain()); + krate } diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index 7fb0a32cc94..f1de0fe9a34 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -61,11 +61,8 @@ fn visit_mod(&mut self, m: &Module) { fn visit_crate(&mut self, c: &Crate) { self.visit_item(&c.module); - // FIXME: make this a simple by-ref for loop once external_traits is cleaned up - let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) }; - for (k, v) in external_traits { - v.items.iter().for_each(|i| self.visit_item(i)); - c.external_traits.borrow_mut().insert(k, v); + for trait_ in c.external_traits.values() { + trait_.items.iter().for_each(|i| self.visit_item(i)); } } }