From bc7d958ab2768d022a3ed6af96a222543b13e1a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Jul 2023 11:38:31 +0200 Subject: [PATCH] Remove needs for transmute --- src/librustdoc/clean/mod.rs | 37 ++++++++++++++++------------------- src/librustdoc/clean/types.rs | 11 +++++++++++ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b5c257d8d3d..9aaef40aa6b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1500,13 +1500,11 @@ fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool { /// or `doc(hidden)`). If it's not possible, it'll return the "end type". /// /// If the path is not a re-export or is public, it'll return `None`. -fn first_non_private( - cx: &mut DocContext<'_>, +fn first_non_private<'tcx>( + cx: &mut DocContext<'tcx>, hir_id: hir::HirId, - path: &hir::Path<'_>, + path: &hir::Path<'tcx>, ) -> Option { - use std::mem::transmute; - let (parent_def_id, mut ident) = match &path.segments[..] { [] => return None, // Relative paths are available in the same scope as the owner. @@ -1577,26 +1575,25 @@ fn first_non_private( // 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 { + 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. - let mut segments = new_path.segments.to_vec(); - if let Some(last) = 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 segments = unsafe { transmute(segments.as_slice()) }; - let new_path = hir::Path { segments, res: path.res, span: new_path.span }; - return Some(clean_path(&new_path, cx)); + return Some(new_clean_path); } // 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> }, } +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,