Skip to content

Commit 2461d0c

Browse files
Remove transmute calls and caching for use paths
1 parent 51eb0c3 commit 2461d0c

File tree

3 files changed

+25
-34
lines changed

3 files changed

+25
-34
lines changed

src/librustdoc/clean/mod.rs

+13-30
Original file line numberDiff line numberDiff line change
@@ -1499,31 +1499,25 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
14991499
fn first_non_private_clean_path<'tcx>(
15001500
cx: &mut DocContext<'tcx>,
15011501
path: &hir::Path<'tcx>,
1502-
mut new_path_segments: Vec<hir::PathSegment<'tcx>>,
1502+
new_path_segments: &'tcx [hir::PathSegment<'tcx>],
15031503
new_path_span: rustc_span::Span,
15041504
) -> Path {
1505-
use std::mem::transmute;
1506-
1505+
let new_hir_path =
1506+
hir::Path { segments: new_path_segments, res: path.res, span: new_path_span };
1507+
let mut new_clean_path = clean_path(&new_hir_path, cx);
15071508
// In here we need to play with the path data one last time to provide it the
15081509
// missing `args` and `res` of the final `Path` we get, which, since it comes
15091510
// from a re-export, doesn't have the generics that were originally there, so
15101511
// we add them by hand.
1511-
if let Some(last) = new_path_segments.last_mut() {
1512-
// `transmute` is needed because we are using a wrong lifetime. Since
1513-
// `segments` will be dropped at the end of this block, it's fine.
1514-
last.args = unsafe { transmute(path.segments.last().as_ref().unwrap().args.clone()) };
1515-
last.res = path.res;
1512+
if let Some(path_last) = path.segments.last().as_ref()
1513+
&& let Some(new_path_last) = new_clean_path.segments[..].last_mut()
1514+
&& let Some(path_last_args) = path_last.args.as_ref()
1515+
&& path_last.args.is_some()
1516+
{
1517+
assert!(new_path_last.args.is_empty());
1518+
new_path_last.args = clean_generic_args(path_last_args, cx);
15161519
}
1517-
// `transmute` is needed because we are using a wrong lifetime. Since
1518-
// `segments` will be dropped at the end of this block, it's fine.
1519-
let path = unsafe {
1520-
hir::Path {
1521-
segments: transmute(new_path_segments.as_slice()),
1522-
res: path.res,
1523-
span: new_path_span,
1524-
}
1525-
};
1526-
clean_path(&path, cx)
1520+
new_clean_path
15271521
}
15281522

15291523
/// 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>(
15351529
hir_id: hir::HirId,
15361530
path: &hir::Path<'tcx>,
15371531
) -> Option<Path> {
1538-
let use_id = path.segments.last().map(|seg| seg.hir_id)?;
15391532
let target_def_id = path.res.opt_def_id()?;
1540-
let saved_path = cx
1541-
.updated_qpath
1542-
.borrow()
1543-
.get(&use_id)
1544-
.map(|saved_path| (saved_path.segments.to_vec(), saved_path.span));
1545-
if let Some((segments, span)) = saved_path {
1546-
return Some(first_non_private_clean_path(cx, path, segments, span));
1547-
}
15481533
let (parent_def_id, ident) = match &path.segments[..] {
15491534
[] => return None,
15501535
// Relative paths are available in the same scope as the owner.
@@ -1611,9 +1596,7 @@ fn first_non_private<'tcx>(
16111596
// 1. We found a public reexport.
16121597
// 2. We didn't find a public reexport so it's the "end type" path.
16131598
if let Some((new_path, _)) = last_path_res {
1614-
cx.updated_qpath.borrow_mut().insert(use_id, new_path.clone());
1615-
let new_path_segments = new_path.segments.to_vec();
1616-
return Some(first_non_private_clean_path(cx, path, new_path_segments, new_path.span));
1599+
return Some(first_non_private_clean_path(cx, path, new_path.segments, new_path.span));
16171600
}
16181601
// If `last_path_res` is `None`, it can mean two things:
16191602
//

src/librustdoc/clean/types.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,17 @@ pub(crate) enum GenericArgs {
22032203
Parenthesized { inputs: Box<[Type]>, output: Option<Box<Type>> },
22042204
}
22052205

2206+
impl GenericArgs {
2207+
pub(crate) fn is_empty(&self) -> bool {
2208+
match self {
2209+
GenericArgs::AngleBracketed { args, bindings } => {
2210+
args.is_empty() && bindings.is_empty()
2211+
}
2212+
GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
2213+
}
2214+
}
2215+
}
2216+
22062217
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
22072218
pub(crate) struct PathSegment {
22082219
pub(crate) name: Symbol,

src/librustdoc/core.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_feature::UnstableFeatures;
88
use rustc_hir::def::Res;
99
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
1010
use rustc_hir::intravisit::{self, Visitor};
11-
use rustc_hir::{HirId, Path, UsePath};
11+
use rustc_hir::{HirId, Path};
1212
use rustc_interface::interface;
1313
use rustc_middle::hir::nested_filter;
1414
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
@@ -63,8 +63,6 @@ pub(crate) struct DocContext<'tcx> {
6363
pub(crate) output_format: OutputFormat,
6464
/// Used by `strip_private`.
6565
pub(crate) show_coverage: bool,
66-
/// Used by `first_non_private` to prevent computing the same path more than once.
67-
pub(crate) updated_qpath: RefCell<FxHashMap<HirId, UsePath<'tcx>>>,
6866
}
6967

7068
impl<'tcx> DocContext<'tcx> {
@@ -354,7 +352,6 @@ pub(crate) fn run_global_ctxt(
354352
output_format,
355353
render_options,
356354
show_coverage,
357-
updated_qpath: Default::default(),
358355
};
359356

360357
for cnum in tcx.crates(()) {

0 commit comments

Comments
 (0)