Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit dc45ff1

Browse files
rustdoc: split build_impl into build_{local,external}_impl
1 parent f16d1fc commit dc45ff1

File tree

2 files changed

+139
-96
lines changed

2 files changed

+139
-96
lines changed

‎src/librustdoc/clean/inline.rs‎

Lines changed: 131 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -433,19 +433,97 @@ pub(crate) fn merge_attrs(
433433
}
434434
}
435435

436+
/// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl` defined in the current crate.
437+
pub(crate) fn build_local_impl(
438+
cx: &mut DocContext<'_>,
439+
did: DefId,
440+
attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
441+
ret: &mut Vec<clean::Item>,
442+
) {
443+
if !cx.inlined.insert(did.into()) {
444+
return;
445+
}
446+
debug_assert!(did.is_local(), "build_local_impl called on external impl");
447+
let tcx = cx.tcx;
448+
let _prof_timer = tcx.sess.prof.generic_activity("build_local_impl");
449+
450+
let associated_trait = tcx.impl_trait_ref(did).map(ty::EarlyBinder::skip_binder);
451+
452+
let impl_item = match did.as_local() {
453+
Some(did) => match &tcx.hir_expect_item(did).kind {
454+
hir::ItemKind::Impl(impl_) => impl_,
455+
_ => panic!("`DefID` passed to `build_impl` is not an `impl"),
456+
},
457+
None => unreachable!("build_local_impl called on external impl"),
458+
};
459+
460+
let for_ = clean_ty(impl_item.self_ty, cx);
461+
462+
let document_hidden = cx.render_options.document_hidden;
463+
let (trait_items, generics) = (
464+
impl_item
465+
.items
466+
.iter()
467+
.map(|&item| tcx.hir_impl_item(item))
468+
.filter(|item| {
469+
// Filter out impl items whose corresponding trait item has `doc(hidden)`
470+
// not to document such impl items.
471+
// For inherent impls, we don't do any filtering, because that's already done in strip_hidden.rs.
472+
473+
// When `--document-hidden-items` is passed, we don't
474+
// do any filtering, too.
475+
if document_hidden {
476+
return true;
477+
}
478+
if let Some(associated_trait) = associated_trait {
479+
let assoc_tag = match item.kind {
480+
hir::ImplItemKind::Const(..) => ty::AssocTag::Const,
481+
hir::ImplItemKind::Fn(..) => ty::AssocTag::Fn,
482+
hir::ImplItemKind::Type(..) => ty::AssocTag::Type,
483+
};
484+
let trait_item = tcx
485+
.associated_items(associated_trait.def_id)
486+
.find_by_ident_and_kind(tcx, item.ident, assoc_tag, associated_trait.def_id)
487+
.unwrap(); // SAFETY: For all impl items there exists trait item that has the same name.
488+
!tcx.is_doc_hidden(trait_item.def_id)
489+
} else {
490+
true
491+
}
492+
})
493+
.map(|item| clean_impl_item(item, cx))
494+
.collect::<Vec<_>>(),
495+
clean_generics(impl_item.generics, cx),
496+
);
497+
build_impl_finalize(cx, did, attrs, ret, associated_trait, for_, trait_items, generics)
498+
}
499+
436500
/// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl`.
437501
pub(crate) fn build_impl(
438502
cx: &mut DocContext<'_>,
439503
did: DefId,
440504
attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
441505
ret: &mut Vec<clean::Item>,
506+
) {
507+
if did.is_local() {
508+
build_local_impl(cx, did, attrs, ret);
509+
} else {
510+
build_external_impl(cx, did, attrs, ret);
511+
}
512+
}
513+
514+
/// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl` defined in an external crate.
515+
pub(crate) fn build_external_impl(
516+
cx: &mut DocContext<'_>,
517+
did: DefId,
518+
attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
519+
ret: &mut Vec<clean::Item>,
442520
) {
443521
if !cx.inlined.insert(did.into()) {
444522
return;
445523
}
446524

447525
let tcx = cx.tcx;
448-
let _prof_timer = tcx.sess.prof.generic_activity("build_impl");
526+
let _prof_timer = tcx.sess.prof.generic_activity("build_external_impl");
449527

450528
let associated_trait = tcx.impl_trait_ref(did).map(ty::EarlyBinder::skip_binder);
451529

@@ -462,30 +540,18 @@ pub(crate) fn build_impl(
462540

463541
// Only inline impl if the implemented trait is
464542
// reachable in rustdoc generated documentation
465-
if !did.is_local()
466-
&& let Some(traitref) = associated_trait
543+
if let Some(traitref) = associated_trait
467544
&& !is_directly_public(cx, traitref.def_id)
468545
{
469546
return;
470547
}
471548

472-
let impl_item = match did.as_local() {
473-
Some(did) => match &tcx.hir_expect_item(did).kind {
474-
hir::ItemKind::Impl(impl_) => Some(impl_),
475-
_ => panic!("`DefID` passed to `build_impl` is not an `impl"),
476-
},
477-
None => None,
478-
};
479-
480-
let for_ = match &impl_item {
481-
Some(impl_) => clean_ty(impl_.self_ty, cx),
482-
None => clean_middle_ty(
483-
ty::Binder::dummy(tcx.type_of(did).instantiate_identity()),
484-
cx,
485-
Some(did),
486-
None,
487-
),
488-
};
549+
let for_ = clean_middle_ty(
550+
ty::Binder::dummy(tcx.type_of(did).instantiate_identity()),
551+
cx,
552+
Some(did),
553+
None,
554+
);
489555

490556
// Only inline impl if the implementing type is
491557
// reachable in rustdoc generated documentation
@@ -496,82 +562,57 @@ pub(crate) fn build_impl(
496562
return;
497563
}
498564

565+
debug_assert!(!did.is_local(), "build_external_impl called on local impl");
566+
567+
let document_hidden = cx.render_options.document_hidden;
568+
let (trait_items, generics) = (
569+
tcx.associated_items(did)
570+
.in_definition_order()
571+
.filter(|item| !item.is_impl_trait_in_trait())
572+
.filter(|item| {
573+
// If this is a trait impl, filter out associated items whose corresponding item
574+
// in the associated trait is marked `doc(hidden)`.
575+
// If this is an inherent impl, filter out private associated items.
576+
if let Some(associated_trait) = associated_trait {
577+
let trait_item = tcx
578+
.associated_items(associated_trait.def_id)
579+
.find_by_ident_and_kind(
580+
tcx,
581+
item.ident(tcx),
582+
item.as_tag(),
583+
associated_trait.def_id,
584+
)
585+
.unwrap(); // corresponding associated item has to exist
586+
document_hidden || !tcx.is_doc_hidden(trait_item.def_id)
587+
} else {
588+
item.visibility(tcx).is_public()
589+
}
590+
})
591+
.map(|item| clean_middle_assoc_item(item, cx))
592+
.collect::<Vec<_>>(),
593+
clean::enter_impl_trait(cx, |cx| clean_ty_generics(cx, did)),
594+
);
595+
build_impl_finalize(cx, did, attrs, ret, associated_trait, for_, trait_items, generics)
596+
}
597+
598+
fn build_impl_finalize<'tcx>(
599+
cx: &mut DocContext<'tcx>,
600+
did: DefId,
601+
attrs: Option<(&[rustc_hir::Attribute], Option<LocalDefId>)>,
602+
ret: &mut Vec<Item>,
603+
associated_trait: Option<ty::TraitRef<'tcx>>,
604+
for_: Type,
605+
trait_items: Vec<Item>,
606+
generics: clean::Generics,
607+
) {
608+
let tcx = cx.tcx;
499609
let document_hidden = cx.render_options.document_hidden;
500-
let (trait_items, generics) = match impl_item {
501-
Some(impl_) => (
502-
impl_
503-
.items
504-
.iter()
505-
.map(|&item| tcx.hir_impl_item(item))
506-
.filter(|item| {
507-
// Filter out impl items whose corresponding trait item has `doc(hidden)`
508-
// not to document such impl items.
509-
// For inherent impls, we don't do any filtering, because that's already done in strip_hidden.rs.
510-
511-
// When `--document-hidden-items` is passed, we don't
512-
// do any filtering, too.
513-
if document_hidden {
514-
return true;
515-
}
516-
if let Some(associated_trait) = associated_trait {
517-
let assoc_tag = match item.kind {
518-
hir::ImplItemKind::Const(..) => ty::AssocTag::Const,
519-
hir::ImplItemKind::Fn(..) => ty::AssocTag::Fn,
520-
hir::ImplItemKind::Type(..) => ty::AssocTag::Type,
521-
};
522-
let trait_item = tcx
523-
.associated_items(associated_trait.def_id)
524-
.find_by_ident_and_kind(
525-
tcx,
526-
item.ident,
527-
assoc_tag,
528-
associated_trait.def_id,
529-
)
530-
.unwrap(); // SAFETY: For all impl items there exists trait item that has the same name.
531-
!tcx.is_doc_hidden(trait_item.def_id)
532-
} else {
533-
true
534-
}
535-
})
536-
.map(|item| clean_impl_item(item, cx))
537-
.collect::<Vec<_>>(),
538-
clean_generics(impl_.generics, cx),
539-
),
540-
None => (
541-
tcx.associated_items(did)
542-
.in_definition_order()
543-
.filter(|item| !item.is_impl_trait_in_trait())
544-
.filter(|item| {
545-
// If this is a trait impl, filter out associated items whose corresponding item
546-
// in the associated trait is marked `doc(hidden)`.
547-
// If this is an inherent impl, filter out private associated items.
548-
if let Some(associated_trait) = associated_trait {
549-
let trait_item = tcx
550-
.associated_items(associated_trait.def_id)
551-
.find_by_ident_and_kind(
552-
tcx,
553-
item.ident(tcx),
554-
item.as_tag(),
555-
associated_trait.def_id,
556-
)
557-
.unwrap(); // corresponding associated item has to exist
558-
document_hidden || !tcx.is_doc_hidden(trait_item.def_id)
559-
} else {
560-
item.visibility(tcx).is_public()
561-
}
562-
})
563-
.map(|item| clean_middle_assoc_item(item, cx))
564-
.collect::<Vec<_>>(),
565-
clean::enter_impl_trait(cx, |cx| clean_ty_generics(cx, did)),
566-
),
567-
};
568610
let polarity = tcx.impl_polarity(did);
569611
let trait_ = associated_trait
570612
.map(|t| clean_trait_ref_with_constraints(cx, ty::Binder::dummy(t), ThinVec::new()));
571613
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
572614
super::build_deref_target_impls(cx, &trait_items, ret);
573615
}
574-
575616
if !document_hidden {
576617
// Return if the trait itself or any types of the generic parameters are doc(hidden).
577618
let mut stack: Vec<&Type> = vec![&for_];
@@ -597,16 +638,13 @@ pub(crate) fn build_impl(
597638
}
598639
}
599640
}
600-
601641
if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
602642
cx.with_param_env(did, |cx| {
603643
record_extern_trait(cx, did);
604644
});
605645
}
606-
607646
let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs);
608647
trace!("merged_attrs={merged_attrs:?}");
609-
610648
trace!(
611649
"build_impl: impl {:?} for {:?}",
612650
trait_.as_ref().map(|t| t.def_id()),
@@ -620,7 +658,7 @@ pub(crate) fn build_impl(
620658
generics,
621659
trait_,
622660
for_,
623-
items: trait_items,
661+
items: trait_items.to_vec(),
624662
polarity,
625663
kind: if utils::has_doc_flag(tcx, did, sym::fake_variadic) {
626664
ImplKind::FakeVariadic

‎src/librustdoc/passes/collect_trait_impls.rs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
5252
for &cnum in tcx.crates(()) {
5353
for &impl_def_id in tcx.trait_impls_in_crate(cnum) {
5454
cx.with_param_env(impl_def_id, |cx| {
55-
inline::build_impl(cx, impl_def_id, None, &mut new_items_external);
55+
inline::build_external_impl(cx, impl_def_id, None, &mut new_items_external);
5656
});
5757
}
5858
}
@@ -79,7 +79,12 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
7979
parent = tcx.opt_parent(did);
8080
}
8181
cx.with_param_env(impl_def_id, |cx| {
82-
inline::build_impl(cx, impl_def_id, Some((&attr_buf, None)), &mut new_items_local);
82+
inline::build_local_impl(
83+
cx,
84+
impl_def_id,
85+
Some((&attr_buf, None)),
86+
&mut new_items_local,
87+
);
8388
});
8489
attr_buf.clear();
8590
}
@@ -90,7 +95,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
9095
// Try to inline primitive impls from other crates.
9196
if !def_id.is_local() {
9297
cx.with_param_env(def_id, |cx| {
93-
inline::build_impl(cx, def_id, None, &mut new_items_external);
98+
inline::build_external_impl(cx, def_id, None, &mut new_items_external);
9499
});
95100
}
96101
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /