unsafe { self.ptr.as_ref() }
}
- fn from_inner(ptr: NonNull<RcBox<T>>) -> Self {
+ unsafe fn from_inner(ptr: NonNull<RcBox<T>>) -> Self {
Self { ptr, phantom: PhantomData }
}
unsafe fn from_ptr(ptr: *mut RcBox<T>) -> Self {
- Self::from_inner(unsafe { NonNull::new_unchecked(ptr) })
+ unsafe { Self::from_inner(NonNull::new_unchecked(ptr)) }
}
}
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
- Self::from_inner(
- Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
- )
+ unsafe {
+ Self::from_inner(
+ Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
+ )
+ }
}
/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
// otherwise.
let data = data_fn(&weak);
- unsafe {
+ let strong = unsafe {
let inner = init_ptr.as_ptr();
ptr::write(ptr::addr_of_mut!((*inner).value), data);
let prev_value = (*inner).strong.get();
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
(*inner).strong.set(1);
- }
- let strong = Rc::from_inner(init_ptr);
+ Rc::from_inner(init_ptr)
+ };
// Strong references should collectively own a shared weak reference,
// so don't run the destructor for our old weak reference.
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
- Ok(Self::from_inner(
- Box::leak(Box::try_new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })?)
- .into(),
- ))
+ unsafe {
+ Ok(Self::from_inner(
+ Box::leak(Box::try_new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })?)
+ .into(),
+ ))
+ }
}
/// Constructs a new `Rc` with uninitialized contents, returning an error if the allocation fails
#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub unsafe fn assume_init(self) -> Rc<T> {
- Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+ unsafe { Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast()) }
}
}
/// ```
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
if (*self).is::<T>() {
- let ptr = self.ptr.cast::<RcBox<T>>();
- forget(self);
- Ok(Rc::from_inner(ptr))
+ unsafe {
+ let ptr = self.ptr.cast::<RcBox<T>>();
+ forget(self);
+ Ok(Rc::from_inner(ptr))
+ }
} else {
Err(self)
}
/// ```
#[inline]
fn clone(&self) -> Rc<T> {
- self.inner().inc_strong();
- Self::from_inner(self.ptr)
+ unsafe {
+ self.inner().inc_strong();
+ Self::from_inner(self.ptr)
+ }
}
}
#[stable(feature = "rc_weak", since = "1.4.0")]
pub fn upgrade(&self) -> Option<Rc<T>> {
let inner = self.inner()?;
+
if inner.strong() == 0 {
None
} else {
- inner.inc_strong();
- Some(Rc::from_inner(self.ptr))
+ unsafe {
+ inner.inc_strong();
+ Some(Rc::from_inner(self.ptr))
+ }
}
}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
impl<T: ?Sized> Arc<T> {
- fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
+ unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
Self { ptr, phantom: PhantomData }
}
weak: atomic::AtomicUsize::new(1),
data,
};
- Self::from_inner(Box::leak(x).into())
+ unsafe { Self::from_inner(Box::leak(x).into()) }
}
/// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
// Now we can properly initialize the inner value and turn our weak
// reference into a strong reference.
- unsafe {
+ let strong = unsafe {
let inner = init_ptr.as_ptr();
ptr::write(ptr::addr_of_mut!((*inner).data), data);
// possible with safe code alone.
let prev_value = (*inner).strong.fetch_add(1, Release);
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
- }
- let strong = Arc::from_inner(init_ptr);
+ Arc::from_inner(init_ptr)
+ };
// Strong references should collectively own a shared weak reference,
// so don't run the destructor for our old weak reference.
weak: atomic::AtomicUsize::new(1),
data,
})?;
- Ok(Self::from_inner(Box::leak(x).into()))
+ unsafe { Ok(Self::from_inner(Box::leak(x).into())) }
}
/// Constructs a new `Arc` with uninitialized contents, returning an error
#[must_use = "`self` will be dropped if the result is not used"]
#[inline]
pub unsafe fn assume_init(self) -> Arc<T> {
- Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+ unsafe { Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast()) }
}
}
abort();
}
- Self::from_inner(self.ptr)
+ unsafe { Self::from_inner(self.ptr) }
}
}
T: Any + Send + Sync + 'static,
{
if (*self).is::<T>() {
- let ptr = self.ptr.cast::<ArcInner<T>>();
- mem::forget(self);
- Ok(Arc::from_inner(ptr))
+ unsafe {
+ let ptr = self.ptr.cast::<ArcInner<T>>();
+ mem::forget(self);
+ Ok(Arc::from_inner(ptr))
+ }
} else {
Err(self)
}
// value can be initialized after `Weak` references have already been created. In that case, we
// expect to observe the fully initialized value.
match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) {
- Ok(_) => return Some(Arc::from_inner(self.ptr)), // null checked above
+ Ok(_) => return Some(unsafe { Arc::from_inner(self.ptr) }), // null checked above
Err(old) => n = old,
}
}
#[derive(Clone, Debug)]
crate struct Crate {
crate module: Item,
- crate externs: Vec<ExternalCrate>,
crate primitives: ThinVec<(DefId, PrimitiveType)>,
/// Only here so that they can be filtered through the rustdoc passes.
crate external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>,
// `Crate` is frequently moved by-value. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Crate, 104);
+rustc_data_structures::static_assert_size!(Crate, 80);
impl Crate {
crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
+use crate::visit_lib::LibEmbargoVisitor;
use rustc_ast as ast;
use rustc_ast::tokenstream::TokenTree;
mod tests;
crate fn krate(cx: &mut DocContext<'_>) -> Crate {
- use crate::visit_lib::LibEmbargoVisitor;
-
let module = crate::visit_ast::RustdocVisitor::new(cx).visit();
- let mut externs = Vec::new();
for &cnum in cx.tcx.crates(()) {
- externs.push(ExternalCrate { crate_num: cnum });
// Analyze doc-reachability for extern items
LibEmbargoVisitor::new(cx).visit_lib(cnum);
}
}));
}
- Crate {
- module,
- externs,
- primitives,
- external_traits: cx.external_traits.clone(),
- collapsed: false,
- }
+ Crate { module, primitives, external_traits: cx.external_traits.clone(), collapsed: false }
}
fn external_generic_args(
rustc_errors::FatalError.raise();
}
- let render_options = ctxt.render_options;
- let mut cache = ctxt.cache;
- krate = tcx.sess.time("create_format_cache", || cache.populate(krate, tcx, &render_options));
+ krate = tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate));
// The main crate doc comments are always collapsed.
krate.collapsed = true;
- (krate, render_options, cache)
+ (krate, ctxt.render_options, ctxt.cache)
}
/// Due to <https://github.com/rust-lang/rust/pull/73566>,
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
-use crate::clean::{self, ItemId, PrimitiveType};
-use crate::config::RenderOptions;
+use crate::clean::{self, ExternalCrate, ItemId, PrimitiveType};
+use crate::core::DocContext;
use crate::fold::DocFolder;
use crate::formats::item_type::ItemType;
use crate::formats::Impl;
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
/// in `krate` due to the data being moved into the `Cache`.
- crate fn populate(
- &mut self,
- mut krate: clean::Crate,
- tcx: TyCtxt<'_>,
- render_options: &RenderOptions,
- ) -> clean::Crate {
+ crate fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate {
+ let tcx = cx.tcx;
+
// Crawl the crate to build various caches used for the output
- debug!(?self.crate_version);
- self.traits = krate.external_traits.take();
- let RenderOptions { extern_html_root_takes_precedence, output: dst, .. } = render_options;
+ debug!(?cx.cache.crate_version);
+ cx.cache.traits = krate.external_traits.take();
// 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
- for &e in &krate.externs {
+ for &crate_num in cx.tcx.crates(()) {
+ let e = ExternalCrate { crate_num };
+
let name = e.name(tcx);
+ let render_options = &cx.render_options;
let extern_url =
render_options.extern_html_root_urls.get(&*name.as_str()).map(|u| &**u);
- let location = e.location(extern_url, *extern_html_root_takes_precedence, dst, tcx);
- self.extern_locations.insert(e.crate_num, location);
- self.external_paths.insert(e.def_id(), (vec![name.to_string()], ItemType::Module));
+ let extern_url_takes_precedence = render_options.extern_html_root_takes_precedence;
+ let dst = &render_options.output;
+ let location = e.location(extern_url, extern_url_takes_precedence, dst, tcx);
+ cx.cache.extern_locations.insert(e.crate_num, location);
+ cx.cache.external_paths.insert(e.def_id(), (vec![name.to_string()], ItemType::Module));
}
// FIXME: avoid this clone (requires implementing Default manually)
- self.primitive_locations = PrimitiveType::primitive_locations(tcx).clone();
- for (prim, &def_id) in &self.primitive_locations {
+ cx.cache.primitive_locations = PrimitiveType::primitive_locations(tcx).clone();
+ for (prim, &def_id) in &cx.cache.primitive_locations {
let crate_name = tcx.crate_name(def_id.krate);
// Recall that we only allow primitive modules to be at the root-level of the crate.
// If that restriction is ever lifted, this will have to include the relative paths instead.
- self.external_paths.insert(
+ cx.cache.external_paths.insert(
def_id,
(vec![crate_name.to_string(), prim.as_sym().to_string()], ItemType::Primitive),
);
}
- krate = CacheBuilder { tcx, cache: self }.fold_crate(krate);
+ krate = CacheBuilder { tcx, cache: &mut cx.cache }.fold_crate(krate);
- for (trait_did, dids, impl_) in self.orphan_trait_impls.drain(..) {
- if self.traits.contains_key(&trait_did) {
+ for (trait_did, dids, impl_) in cx.cache.orphan_trait_impls.drain(..) {
+ if cx.cache.traits.contains_key(&trait_did) {
for did in dids {
- self.impls.entry(did).or_default().push(impl_.clone());
+ cx.cache.impls.entry(did).or_default().push(impl_.clone());
}
}
}