]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #90927 - terrarier2111:fix-float-ice, r=jackh726
authorMatthias Krüger <matthias.krueger@famsik.de>
Sat, 20 Nov 2021 21:33:49 +0000 (22:33 +0100)
committerGitHub <noreply@github.com>
Sat, 20 Nov 2021 21:33:49 +0000 (22:33 +0100)
Fix float ICE

This fixes https://github.com/rust-lang/rust/issues/90728

library/alloc/src/rc.rs
library/alloc/src/sync.rs
src/librustdoc/clean/types.rs
src/librustdoc/clean/utils.rs
src/librustdoc/core.rs
src/librustdoc/formats/cache.rs

index 03e33a1ff2bc3b77f1223b8056497f8e40763b29..c4e5e44fec0b2df34fd417e65acebdcab582b15d 100644 (file)
@@ -341,12 +341,12 @@ fn inner(&self) -> &RcBox<T> {
         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)) }
     }
 }
 
@@ -367,9 +367,11 @@ pub fn new(value: T) -> Rc<T> {
         // 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
@@ -420,16 +422,16 @@ pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
         // 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.
@@ -521,10 +523,12 @@ pub fn try_new(value: T) -> Result<Rc<T>, AllocError> {
         // 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
@@ -746,7 +750,7 @@ impl<T> Rc<mem::MaybeUninit<T>> {
     #[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()) }
     }
 }
 
@@ -1214,9 +1218,11 @@ impl Rc<dyn Any> {
     /// ```
     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)
         }
@@ -1489,8 +1495,10 @@ impl<T: ?Sized> Clone for Rc<T> {
     /// ```
     #[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)
+        }
     }
 }
 
@@ -2245,11 +2253,14 @@ pub unsafe fn from_raw(ptr: *const T) -> Self {
     #[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))
+            }
         }
     }
 
index b738337a2ddd19805fc0d623f6570077f6991a22..733a898b285ac54c205547197d6ec0c9a1a577a2 100644 (file)
@@ -252,7 +252,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 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 }
     }
 
@@ -348,7 +348,7 @@ pub fn new(data: T) -> Arc<T> {
             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
@@ -397,7 +397,7 @@ pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
 
         // 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);
 
@@ -415,9 +415,9 @@ pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
             // 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.
@@ -529,7 +529,7 @@ pub fn try_new(data: T) -> Result<Arc<T>, AllocError> {
             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
@@ -743,7 +743,7 @@ impl<T> Arc<mem::MaybeUninit<T>> {
     #[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()) }
     }
 }
 
@@ -1341,7 +1341,7 @@ fn clone(&self) -> Arc<T> {
             abort();
         }
 
-        Self::from_inner(self.ptr)
+        unsafe { Self::from_inner(self.ptr) }
     }
 }
 
@@ -1668,9 +1668,11 @@ pub fn downcast<T>(self) -> Result<Arc<T>, Self>
         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)
         }
@@ -1899,7 +1901,7 @@ pub fn upgrade(&self) -> Option<Arc<T>> {
             // 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,
             }
         }
index 41ebf270ba63015e3f39a92078e0e967bff7cd23..bb5597b5758d2657432ef613465a5ac4414d00dc 100644 (file)
@@ -117,7 +117,6 @@ fn from(id: DefId) -> Self {
 #[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>>>,
@@ -126,7 +125,7 @@ fn from(id: DefId) -> Self {
 
 // `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 {
index 2fa7efcc6509b143e69b5192d06cf4bf8d507669..9860b21e0a971e6fe93ca23cf3023bbda2e0bb15 100644 (file)
@@ -7,6 +7,7 @@
 };
 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(
index a331f4cf3e6e7c6e48e015ad67409019d07a6b65..c58310947d2825e934acdbb9148a10c41f968482 100644 (file)
@@ -508,14 +508,12 @@ fn report_deprecated_attr(name: &str, diag: &rustc_errors::Handler, sp: Span) {
         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>,
index 05d8b643f502b5e6fa2ecd3d9d37420838ba0c42..db2b836de86e459b8b318425e5bb952418304094 100644 (file)
@@ -6,8 +6,8 @@
 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;
@@ -136,46 +136,47 @@ impl Cache {
 
     /// 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());
                 }
             }
         }