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`.
This commit is contained in:
Lukas Markeffsky 2024-09-25 22:15:23 +02:00
parent 0399709cdc
commit b1745c3919
8 changed files with 19 additions and 21 deletions

View File

@ -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);
}

View File

@ -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<RefCell<FxHashMap<DefId, Trait>>>,
pub(crate) external_traits: Box<FxHashMap<DefId, Trait>>,
}
impl Crate {

View File

@ -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>(

View File

@ -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<RefCell<FxHashMap<DefId, clean::Trait>>>,
pub(crate) external_traits: FxHashMap<DefId, clean::Trait>,
/// 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());

View File

@ -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

View File

@ -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

View File

@ -219,6 +219,8 @@ fn add_deref_target(
panic!("collect-trait-impls can't run");
};
krate.external_traits.extend(cx.external_traits.drain());
krate
}

View File

@ -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));
}
}
}