fix #90187
This commit is contained in:
parent
ff88b59e58
commit
0dd2703f8a
7 changed files with 30 additions and 15 deletions
|
@ -338,6 +338,7 @@ impl ExternalCrate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates where an external crate can be found.
|
/// Indicates where an external crate can be found.
|
||||||
|
#[derive(Debug)]
|
||||||
crate enum ExternalLocation {
|
crate enum ExternalLocation {
|
||||||
/// Remote URL root of the external crate
|
/// Remote URL root of the external crate
|
||||||
Remote(String),
|
Remote(String),
|
||||||
|
|
|
@ -25,7 +25,7 @@ use crate::html::render::IndexItem;
|
||||||
/// to be a fairly large and expensive structure to clone. Instead this adheres
|
/// to be a fairly large and expensive structure to clone. Instead this adheres
|
||||||
/// to `Send` so it may be stored in an `Arc` instance and shared among the various
|
/// to `Send` so it may be stored in an `Arc` instance and shared among the various
|
||||||
/// rendering threads.
|
/// rendering threads.
|
||||||
#[derive(Default)]
|
#[derive(Default, Debug)]
|
||||||
crate struct Cache {
|
crate struct Cache {
|
||||||
/// Maps a type ID to all known implementations for that type. This is only
|
/// Maps a type ID to all known implementations for that type. This is only
|
||||||
/// recognized for intra-crate [`clean::Type::Path`]s, and is used to print
|
/// recognized for intra-crate [`clean::Type::Path`]s, and is used to print
|
||||||
|
|
|
@ -248,12 +248,14 @@ fn add_generics_and_bounds_as_types<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
recurse: usize,
|
recurse: usize,
|
||||||
res: &mut Vec<TypeWithKind>,
|
res: &mut Vec<TypeWithKind>,
|
||||||
|
cache: &Cache,
|
||||||
) {
|
) {
|
||||||
fn insert_ty(
|
fn insert_ty(
|
||||||
res: &mut Vec<TypeWithKind>,
|
res: &mut Vec<TypeWithKind>,
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
mut generics: Vec<TypeWithKind>,
|
mut generics: Vec<TypeWithKind>,
|
||||||
|
cache: &Cache,
|
||||||
) {
|
) {
|
||||||
let is_full_generic = ty.is_full_generic();
|
let is_full_generic = ty.is_full_generic();
|
||||||
|
|
||||||
|
@ -347,6 +349,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
&mut ty_generics,
|
&mut ty_generics,
|
||||||
|
cache,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -354,7 +357,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
insert_ty(res, tcx, arg.clone(), ty_generics);
|
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
|
||||||
}
|
}
|
||||||
// Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`...
|
// Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`...
|
||||||
if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
|
if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
|
||||||
|
@ -368,10 +371,11 @@ fn add_generics_and_bounds_as_types<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
&mut ty_generics,
|
&mut ty_generics,
|
||||||
|
cache,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
insert_ty(res, tcx, arg.clone(), ty_generics);
|
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
|
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
|
||||||
|
@ -382,10 +386,17 @@ fn add_generics_and_bounds_as_types<'tcx>(
|
||||||
let mut ty_generics = Vec::new();
|
let mut ty_generics = Vec::new();
|
||||||
if let Some(arg_generics) = arg.generics() {
|
if let Some(arg_generics) = arg.generics() {
|
||||||
for gen in arg_generics.iter() {
|
for gen in arg_generics.iter() {
|
||||||
add_generics_and_bounds_as_types(generics, gen, tcx, recurse + 1, &mut ty_generics);
|
add_generics_and_bounds_as_types(
|
||||||
|
generics,
|
||||||
|
gen,
|
||||||
|
tcx,
|
||||||
|
recurse + 1,
|
||||||
|
&mut ty_generics,
|
||||||
|
cache,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
insert_ty(res, tcx, arg.clone(), ty_generics);
|
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +418,7 @@ fn get_fn_inputs_and_outputs<'tcx>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
add_generics_and_bounds_as_types(generics, &arg.type_, tcx, 0, &mut args);
|
add_generics_and_bounds_as_types(generics, &arg.type_, tcx, 0, &mut args, cache);
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
all_types.extend(args);
|
all_types.extend(args);
|
||||||
} else {
|
} else {
|
||||||
|
@ -420,7 +431,7 @@ fn get_fn_inputs_and_outputs<'tcx>(
|
||||||
let mut ret_types = Vec::new();
|
let mut ret_types = Vec::new();
|
||||||
match decl.output {
|
match decl.output {
|
||||||
FnRetTy::Return(ref return_type) => {
|
FnRetTy::Return(ref return_type) => {
|
||||||
add_generics_and_bounds_as_types(generics, return_type, tcx, 0, &mut ret_types);
|
add_generics_and_bounds_as_types(generics, return_type, tcx, 0, &mut ret_types, cache);
|
||||||
if ret_types.is_empty() {
|
if ret_types.is_empty() {
|
||||||
if let Some(kind) = return_type.def_id(cache).map(|did| tcx.def_kind(did).into()) {
|
if let Some(kind) = return_type.def_id(cache).map(|did| tcx.def_kind(did).into()) {
|
||||||
ret_types.push(TypeWithKind::from((get_index_type(return_type, vec![]), kind)));
|
ret_types.push(TypeWithKind::from((get_index_type(return_type, vec![]), kind)));
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
use super::Pass;
|
use super::Pass;
|
||||||
use crate::clean::*;
|
use crate::clean::*;
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
|
use crate::formats::cache::Cache;
|
||||||
use crate::visit::DocVisitor;
|
use crate::visit::DocVisitor;
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
@ -57,14 +58,14 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut cleaner = BadImplStripper { prims, items: crate_items };
|
let mut cleaner = BadImplStripper { prims, items: crate_items, cache: &cx.cache };
|
||||||
let mut type_did_to_deref_target: FxHashMap<DefId, &Type> = FxHashMap::default();
|
let mut type_did_to_deref_target: FxHashMap<DefId, &Type> = FxHashMap::default();
|
||||||
|
|
||||||
// Follow all `Deref` targets of included items and recursively add them as valid
|
// Follow all `Deref` targets of included items and recursively add them as valid
|
||||||
fn add_deref_target(
|
fn add_deref_target(
|
||||||
cx: &DocContext<'_>,
|
cx: &DocContext<'_>,
|
||||||
map: &FxHashMap<DefId, &Type>,
|
map: &FxHashMap<DefId, &Type>,
|
||||||
cleaner: &mut BadImplStripper,
|
cleaner: &mut BadImplStripper<'_>,
|
||||||
type_did: DefId,
|
type_did: DefId,
|
||||||
) {
|
) {
|
||||||
if let Some(target) = map.get(&type_did) {
|
if let Some(target) = map.get(&type_did) {
|
||||||
|
@ -204,19 +205,20 @@ impl DocVisitor for ItemCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BadImplStripper {
|
struct BadImplStripper<'a> {
|
||||||
prims: FxHashSet<PrimitiveType>,
|
prims: FxHashSet<PrimitiveType>,
|
||||||
items: FxHashSet<ItemId>,
|
items: FxHashSet<ItemId>,
|
||||||
|
crate cache: &'a Cache,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BadImplStripper {
|
impl<'a> BadImplStripper<'a> {
|
||||||
fn keep_impl(&self, ty: &Type, is_deref: bool) -> bool {
|
fn keep_impl(&self, ty: &Type, is_deref: bool) -> bool {
|
||||||
if let Generic(_) = ty {
|
if let Generic(_) = ty {
|
||||||
// keep impls made on generics
|
// keep impls made on generics
|
||||||
true
|
true
|
||||||
} else if let Some(prim) = ty.primitive_type() {
|
} else if let Some(prim) = ty.primitive_type() {
|
||||||
self.prims.contains(&prim)
|
self.prims.contains(&prim)
|
||||||
} else if let Some(did) = ty.def_id(&cx.cache) {
|
} else if let Some(did) = ty.def_id(self.cache) {
|
||||||
is_deref || self.keep_impl_with_def_id(did.into())
|
is_deref || self.keep_impl_with_def_id(did.into())
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
@ -15,7 +15,7 @@ crate const STRIP_HIDDEN: Pass = Pass {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Strip items marked `#[doc(hidden)]`
|
/// Strip items marked `#[doc(hidden)]`
|
||||||
crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
|
crate fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
||||||
let mut retained = ItemIdSet::default();
|
let mut retained = ItemIdSet::default();
|
||||||
|
|
||||||
// strip all #[doc(hidden)] items
|
// strip all #[doc(hidden)] items
|
||||||
|
@ -25,7 +25,7 @@ crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Cra
|
||||||
};
|
};
|
||||||
|
|
||||||
// strip all impls referencing stripped items
|
// strip all impls referencing stripped items
|
||||||
let mut stripper = ImplStripper { retained: &retained };
|
let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache };
|
||||||
stripper.fold_crate(krate)
|
stripper.fold_crate(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,6 @@ crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip all impls referencing private items
|
// strip all impls referencing private items
|
||||||
let mut stripper = ImplStripper { retained: &retained };
|
let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache };
|
||||||
stripper.fold_crate(krate)
|
stripper.fold_crate(krate)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::mem;
|
||||||
|
|
||||||
use crate::clean::{self, Item, ItemIdSet};
|
use crate::clean::{self, Item, ItemIdSet};
|
||||||
use crate::fold::{strip_item, DocFolder};
|
use crate::fold::{strip_item, DocFolder};
|
||||||
|
use crate::formats::cache::Cache;
|
||||||
|
|
||||||
crate struct Stripper<'a> {
|
crate struct Stripper<'a> {
|
||||||
crate retained: &'a mut ItemIdSet,
|
crate retained: &'a mut ItemIdSet,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue