Skip to content

Commit f442bce

Browse files
alexcrichtonmcpherrinm
authored andcommitted
rustdoc: Ensure external impls are inlined once
If the type associated with the impl is `pub use`'d or referenced twice in a downstream crate, the impl will attempt to be inlined twice. Closes rust-lang#14584
1 parent 3861794 commit f442bce

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

src/librustdoc/clean/inline.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ fn build_impls(cx: &core::DocContext,
207207
match tcx.inherent_impls.borrow().find(&did) {
208208
None => {}
209209
Some(i) => {
210-
impls.extend(i.borrow().iter().map(|&did| { build_impl(tcx, did) }));
210+
impls.extend(i.borrow().iter().map(|&did| { build_impl(cx, tcx, did) }));
211211
}
212212
}
213213

@@ -223,30 +223,37 @@ fn build_impls(cx: &core::DocContext,
223223
csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
224224
did.krate,
225225
|def, _, _| {
226-
populate_impls(tcx, def, &mut impls)
226+
populate_impls(cx, tcx, def, &mut impls)
227227
});
228228

229-
fn populate_impls(tcx: &ty::ctxt,
229+
fn populate_impls(cx: &core::DocContext,
230+
tcx: &ty::ctxt,
230231
def: decoder::DefLike,
231-
impls: &mut Vec<clean::Item>) {
232+
impls: &mut Vec<Option<clean::Item>>) {
232233
match def {
233-
decoder::DlImpl(did) => impls.push(build_impl(tcx, did)),
234+
decoder::DlImpl(did) => impls.push(build_impl(cx, tcx, did)),
234235
decoder::DlDef(ast::DefMod(did)) => {
235236
csearch::each_child_of_item(&tcx.sess.cstore,
236237
did,
237238
|def, _, _| {
238-
populate_impls(tcx, def, impls)
239+
populate_impls(cx, tcx, def, impls)
239240
})
240241
}
241242
_ => {}
242243
}
243244
}
244245
}
245246

246-
impls
247+
impls.move_iter().filter_map(|a| a).collect()
247248
}
248249

249-
fn build_impl(tcx: &ty::ctxt, did: ast::DefId) -> clean::Item {
250+
fn build_impl(cx: &core::DocContext,
251+
tcx: &ty::ctxt,
252+
did: ast::DefId) -> Option<clean::Item> {
253+
if !cx.inlined.borrow_mut().get_mut_ref().insert(did) {
254+
return None
255+
}
256+
250257
let associated_trait = csearch::get_impl_trait(tcx, did);
251258
let attrs = load_attrs(tcx, did);
252259
let ty = ty::lookup_item_type(tcx, did);
@@ -275,7 +282,7 @@ fn build_impl(tcx: &ty::ctxt, did: ast::DefId) -> clean::Item {
275282
};
276283
Some(item)
277284
}).collect();
278-
clean::Item {
285+
Some(clean::Item {
279286
inner: clean::ImplItem(clean::Impl {
280287
derived: clean::detect_derived(attrs.as_slice()),
281288
trait_: associated_trait.clean().map(|bound| {
@@ -293,7 +300,7 @@ fn build_impl(tcx: &ty::ctxt, did: ast::DefId) -> clean::Item {
293300
attrs: attrs,
294301
visibility: Some(ast::Inherited),
295302
def_id: did,
296-
}
303+
})
297304
}
298305

299306
fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,

0 commit comments

Comments
 (0)