Skip to content

Commit 4aa1fea

Browse files
committed
beta-targetted revert of PR rust-lang#80653, to address issue rust-lang#82465.
adapted from 513756bb55a0dbc6e74d0043afd1727bd3c73aae
1 parent 9a1dfd2 commit 4aa1fea

File tree

7 files changed

+46
-184
lines changed

7 files changed

+46
-184
lines changed

src/librustdoc/html/render/context.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use std::path::PathBuf;
55
use std::rc::Rc;
66
use std::sync::mpsc::channel;
77

8-
use rustc_data_structures::fx::FxHashMap;
9-
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
8+
use rustc_hir::def_id::{LOCAL_CRATE};
109
use rustc_middle::ty::TyCtxt;
1110
use rustc_session::Session;
1211
use rustc_span::edition::Edition;
@@ -53,9 +52,6 @@ crate struct Context<'tcx> {
5352
pub(super) render_redirect_pages: bool,
5453
/// The map used to ensure all generated 'id=' attributes are unique.
5554
pub(super) id_map: RefCell<IdMap>,
56-
/// Tracks section IDs for `Deref` targets so they match in both the main
57-
/// body and the sidebar.
58-
pub(super) deref_id_map: RefCell<FxHashMap<DefId, String>>,
5955
/// Shared mutable state.
6056
///
6157
/// Issue for improving the situation: [#82381][]
@@ -76,7 +72,7 @@ crate struct Context<'tcx> {
7672

7773
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
7874
#[cfg(target_arch = "x86_64")]
79-
rustc_data_structures::static_assert_size!(Context<'_>, 152);
75+
rustc_data_structures::static_assert_size!(Context<'_>, 112);
8076

8177
impl<'tcx> Context<'tcx> {
8278
pub(super) fn path(&self, filename: &str) -> PathBuf {
@@ -416,7 +412,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
416412
dst,
417413
render_redirect_pages: false,
418414
id_map: RefCell::new(id_map),
419-
deref_id_map: RefCell::new(FxHashMap::default()),
420415
shared: Rc::new(scx),
421416
cache: Rc::new(cache),
422417
};
@@ -439,7 +434,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
439434
dst: self.dst.clone(),
440435
render_redirect_pages: self.render_redirect_pages,
441436
id_map: RefCell::new(id_map),
442-
deref_id_map: RefCell::new(FxHashMap::default()),
443437
shared: Rc::clone(&self.shared),
444438
cache: Rc::clone(&self.cache),
445439
}

src/librustdoc/html/render/mod.rs

+6-24
Original file line numberDiff line numberDiff line change
@@ -1159,21 +1159,12 @@ fn render_assoc_items(
11591159
RenderMode::Normal
11601160
}
11611161
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
1162-
let id = cx.derive_id(small_url_encode(format!(
1163-
"deref-methods-{:#}",
1164-
type_.print(cx.cache())
1165-
)));
1166-
debug!("Adding {} to deref id map", type_.print(cx.cache()));
1167-
cx.deref_id_map
1168-
.borrow_mut()
1169-
.insert(type_.def_id_full(cx.cache()).unwrap(), id.clone());
11701162
write!(
11711163
w,
1172-
"<h2 id=\"{id}\" class=\"small-section-header\">\
1164+
"<h2 id=\"deref-methods\" class=\"small-section-header\">\
11731165
Methods from {trait_}&lt;Target = {type_}&gt;\
1174-
<a href=\"#{id}\" class=\"anchor\"></a>\
1166+
<a href=\"#deref-methods\" class=\"anchor\"></a>\
11751167
</h2>",
1176-
id = id,
11771168
trait_ = trait_.print(cx.cache()),
11781169
type_ = type_.print(cx.cache()),
11791170
);
@@ -1198,6 +1189,9 @@ fn render_assoc_items(
11981189
);
11991190
}
12001191
}
1192+
if let AssocItemRender::DerefFor { .. } = what {
1193+
return;
1194+
}
12011195
if !traits.is_empty() {
12021196
let deref_impl = traits
12031197
.iter()
@@ -1208,13 +1202,6 @@ fn render_assoc_items(
12081202
});
12091203
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
12101204
}
1211-
1212-
// If we were already one level into rendering deref methods, we don't want to render
1213-
// anything after recursing into any further deref methods above.
1214-
if let AssocItemRender::DerefFor { .. } = what {
1215-
return;
1216-
}
1217-
12181205
let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
12191206
traits.iter().partition(|t| t.inner_impl().synthetic);
12201207
let (blanket_impl, concrete): (Vec<&&Impl>, _) =
@@ -2020,14 +2007,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
20202007
.flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c))
20212008
.collect::<Vec<_>>();
20222009
if !ret.is_empty() {
2023-
let deref_id_map = cx.deref_id_map.borrow();
2024-
let id = deref_id_map
2025-
.get(&real_target.def_id_full(cx.cache()).unwrap())
2026-
.expect("Deref section without derived id");
20272010
write!(
20282011
out,
2029-
"<a class=\"sidebar-title\" href=\"#{}\">Methods from {}&lt;Target={}&gt;</a>",
2030-
id,
2012+
"<a class=\"sidebar-title\" href=\"#deref-methods\">Methods from {}&lt;Target={}&gt;</a>",
20312013
Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(c))),
20322014
Escape(&format!("{:#}", real_target.print(c))),
20332015
);

src/librustdoc/passes/collect_trait_impls.rs

+36-65
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::clean::*;
33
use crate::core::DocContext;
44
use crate::fold::DocFolder;
55

6-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6+
use rustc_data_structures::fx::{FxHashSet};
77
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
88
use rustc_middle::ty::DefIdTree;
99
use rustc_span::symbol::sym;
@@ -53,6 +53,39 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
5353
}
5454
}
5555

56+
let mut cleaner = BadImplStripper { prims, items: crate_items };
57+
58+
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
59+
for it in &new_items {
60+
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
61+
if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
62+
let target = items
63+
.iter()
64+
.find_map(|item| match *item.kind {
65+
TypedefItem(ref t, true) => Some(&t.type_),
66+
_ => None,
67+
})
68+
.expect("Deref impl without Target type");
69+
70+
if let Some(prim) = target.primitive_type() {
71+
cleaner.prims.insert(prim);
72+
} else if let Some(did) = target.def_id() {
73+
cleaner.items.insert(did);
74+
}
75+
}
76+
}
77+
}
78+
79+
new_items.retain(|it| {
80+
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
81+
cleaner.keep_impl(for_)
82+
|| trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
83+
|| blanket_impl.is_some()
84+
} else {
85+
true
86+
}
87+
});
88+
5689
// `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
5790
// doesn't work with it anyway, so pull them from the HIR map instead
5891
let mut extra_attrs = Vec::new();
@@ -84,53 +117,6 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
84117
}
85118
}
86119

87-
let mut cleaner = BadImplStripper { prims, items: crate_items };
88-
89-
let mut type_did_to_deref_target: FxHashMap<DefId, &Type> = FxHashMap::default();
90-
// Gather all type to `Deref` target edges.
91-
for it in &new_items {
92-
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
93-
if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
94-
let target = items.iter().find_map(|item| match *item.kind {
95-
TypedefItem(ref t, true) => Some(&t.type_),
96-
_ => None,
97-
});
98-
if let (Some(for_did), Some(target)) = (for_.def_id(), target) {
99-
type_did_to_deref_target.insert(for_did, target);
100-
}
101-
}
102-
}
103-
}
104-
// Follow all `Deref` targets of included items and recursively add them as valid
105-
fn add_deref_target(
106-
map: &FxHashMap<DefId, &Type>,
107-
cleaner: &mut BadImplStripper,
108-
type_did: &DefId,
109-
) {
110-
if let Some(target) = map.get(type_did) {
111-
debug!("add_deref_target: type {:?}, target {:?}", type_did, target);
112-
if let Some(target_prim) = target.primitive_type() {
113-
cleaner.prims.insert(target_prim);
114-
} else if let Some(target_did) = target.def_id() {
115-
// `impl Deref<Target = S> for S`
116-
if target_did == *type_did {
117-
// Avoid infinite cycles
118-
return;
119-
}
120-
cleaner.items.insert(target_did);
121-
add_deref_target(map, cleaner, &target_did);
122-
}
123-
}
124-
}
125-
for type_did in type_did_to_deref_target.keys() {
126-
// Since only the `DefId` portion of the `Type` instances is known to be same for both the
127-
// `Deref` target type and the impl for type positions, this map of types is keyed by
128-
// `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
129-
if cleaner.keep_impl_with_def_id(type_did) {
130-
add_deref_target(&type_did_to_deref_target, &mut cleaner, type_did);
131-
}
132-
}
133-
134120
let items = if let Some(ref mut it) = krate.module {
135121
if let ModuleItem(Module { ref mut items, .. }) = *it.kind {
136122
items
@@ -142,18 +128,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
142128
};
143129

144130
items.extend(synth_impls);
145-
for it in new_items.drain(..) {
146-
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
147-
if !(cleaner.keep_impl(for_)
148-
|| trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
149-
|| blanket_impl.is_some())
150-
{
151-
continue;
152-
}
153-
}
154-
155-
items.push(it);
156-
}
131+
items.extend(new_items);
157132

158133
krate
159134
}
@@ -208,13 +183,9 @@ impl BadImplStripper {
208183
} else if let Some(prim) = ty.primitive_type() {
209184
self.prims.contains(&prim)
210185
} else if let Some(did) = ty.def_id() {
211-
self.keep_impl_with_def_id(&did)
186+
self.items.contains(&did)
212187
} else {
213188
false
214189
}
215190
}
216-
217-
fn keep_impl_with_def_id(&self, did: &DefId) -> bool {
218-
self.items.contains(did)
219-
}
220191
}

src/test/rustdoc-ui/deref-recursive-cycle.rs

-17
This file was deleted.

src/test/rustdoc/deref-recursive-pathbuf.rs

-26
This file was deleted.

src/test/rustdoc/deref-recursive.rs

-42
This file was deleted.

src/test/rustdoc/deref-typedef.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
#![crate_name = "foo"]
44

55
// @has 'foo/struct.Bar.html'
6-
// @has '-' '//*[@id="deref-methods-FooJ"]' 'Methods from Deref<Target = FooJ>'
6+
// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooJ>'
77
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)'
88
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
99
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
1010
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
11-
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-FooJ"]' 'Methods from Deref<Target=FooJ>'
11+
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods"]' 'Methods from Deref<Target=FooJ>'
1212
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
1313
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
1414
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'

0 commit comments

Comments
 (0)