about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/clean/mod.rs43
-rw-r--r--src/librustdoc/clean/types.rs11
-rw-r--r--src/librustdoc/core.rs5
3 files changed, 25 insertions, 34 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 998380abfac..fd38d1c045e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1499,31 +1499,25 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
 fn first_non_private_clean_path<'tcx>(
     cx: &mut DocContext<'tcx>,
     path: &hir::Path<'tcx>,
-    mut new_path_segments: Vec<hir::PathSegment<'tcx>>,
+    new_path_segments: &'tcx [hir::PathSegment<'tcx>],
     new_path_span: rustc_span::Span,
 ) -> Path {
-    use std::mem::transmute;
-
+    let new_hir_path =
+        hir::Path { segments: new_path_segments, res: path.res, span: new_path_span };
+    let mut new_clean_path = clean_path(&new_hir_path, cx);
     // In here we need to play with the path data one last time to provide it the
     // missing `args` and `res` of the final `Path` we get, which, since it comes
     // from a re-export, doesn't have the generics that were originally there, so
     // we add them by hand.
-    if let Some(last) = new_path_segments.last_mut() {
-        // `transmute` is needed because we are using a wrong lifetime. Since
-        // `segments` will be dropped at the end of this block, it's fine.
-        last.args = unsafe { transmute(path.segments.last().as_ref().unwrap().args.clone()) };
-        last.res = path.res;
+    if let Some(path_last) = path.segments.last().as_ref()
+        && let Some(new_path_last) = new_clean_path.segments[..].last_mut()
+        && let Some(path_last_args) = path_last.args.as_ref()
+        && path_last.args.is_some()
+    {
+        assert!(new_path_last.args.is_empty());
+        new_path_last.args = clean_generic_args(path_last_args, cx);
     }
-    // `transmute` is needed because we are using a wrong lifetime. Since
-    // `segments` will be dropped at the end of this block, it's fine.
-    let path = unsafe {
-        hir::Path {
-            segments: transmute(new_path_segments.as_slice()),
-            res: path.res,
-            span: new_path_span,
-        }
-    };
-    clean_path(&path, cx)
+    new_clean_path
 }
 
 /// The goal of this function is to return the first `Path` which is not private (ie not private
@@ -1535,16 +1529,7 @@ fn first_non_private<'tcx>(
     hir_id: hir::HirId,
     path: &hir::Path<'tcx>,
 ) -> Option<Path> {
-    let use_id = path.segments.last().map(|seg| seg.hir_id)?;
     let target_def_id = path.res.opt_def_id()?;
-    let saved_path = cx
-        .updated_qpath
-        .borrow()
-        .get(&use_id)
-        .map(|saved_path| (saved_path.segments.to_vec(), saved_path.span));
-    if let Some((segments, span)) = saved_path {
-        return Some(first_non_private_clean_path(cx, path, segments, span));
-    }
     let (parent_def_id, ident) = match &path.segments[..] {
         [] => return None,
         // Relative paths are available in the same scope as the owner.
@@ -1611,9 +1596,7 @@ fn first_non_private<'tcx>(
                 // 1. We found a public reexport.
                 // 2. We didn't find a public reexport so it's the "end type" path.
                 if let Some((new_path, _)) = last_path_res {
-                    cx.updated_qpath.borrow_mut().insert(use_id, new_path.clone());
-                    let new_path_segments = new_path.segments.to_vec();
-                    return Some(first_non_private_clean_path(cx, path, new_path_segments, new_path.span));
+                    return Some(first_non_private_clean_path(cx, path, new_path.segments, new_path.span));
                 }
                 // If `last_path_res` is `None`, it can mean two things:
                 //
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index ddef165a054..60e316decf9 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -2203,6 +2203,17 @@ pub(crate) enum GenericArgs {
     Parenthesized { inputs: Box<[Type]>, output: Option<Box<Type>> },
 }
 
+impl GenericArgs {
+    pub(crate) fn is_empty(&self) -> bool {
+        match self {
+            GenericArgs::AngleBracketed { args, bindings } => {
+                args.is_empty() && bindings.is_empty()
+            }
+            GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub(crate) struct PathSegment {
     pub(crate) name: Symbol,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 6cccb403491..7fb069d6e70 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -8,7 +8,7 @@ use rustc_feature::UnstableFeatures;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{HirId, Path, UsePath};
+use rustc_hir::{HirId, Path};
 use rustc_interface::interface;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
@@ -63,8 +63,6 @@ pub(crate) struct DocContext<'tcx> {
     pub(crate) output_format: OutputFormat,
     /// Used by `strip_private`.
     pub(crate) show_coverage: bool,
-    /// Used by `first_non_private` to prevent computing the same path more than once.
-    pub(crate) updated_qpath: RefCell<FxHashMap<HirId, UsePath<'tcx>>>,
 }
 
 impl<'tcx> DocContext<'tcx> {
@@ -354,7 +352,6 @@ pub(crate) fn run_global_ctxt(
         output_format,
         render_options,
         show_coverage,
-        updated_qpath: Default::default(),
     };
 
     for cnum in tcx.crates(()) {