rustdoc: handle cross-crate RPITITs correctly
This commit is contained in:
parent
c3c5a5c5f7
commit
5924043b86
@ -2081,9 +2081,9 @@ rustc_queries! {
|
||||
}
|
||||
}
|
||||
|
||||
query is_impossible_method(key: (DefId, DefId)) -> bool {
|
||||
query is_impossible_associated_item(key: (DefId, DefId)) -> bool {
|
||||
desc { |tcx|
|
||||
"checking if `{}` is impossible to call within `{}`",
|
||||
"checking if `{}` is impossible to reference within `{}`",
|
||||
tcx.def_path_str(key.1),
|
||||
tcx.def_path_str(key.0),
|
||||
}
|
||||
|
@ -474,11 +474,14 @@ fn subst_and_check_impossible_predicates<'tcx>(
|
||||
result
|
||||
}
|
||||
|
||||
/// Checks whether a trait's method is impossible to call on a given impl.
|
||||
/// Checks whether a trait's associated item is impossible to reference on a given impl.
|
||||
///
|
||||
/// This only considers predicates that reference the impl's generics, and not
|
||||
/// those that reference the method's generics.
|
||||
fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefId, DefId)) -> bool {
|
||||
fn is_impossible_associated_item(
|
||||
tcx: TyCtxt<'_>,
|
||||
(impl_def_id, trait_item_def_id): (DefId, DefId),
|
||||
) -> bool {
|
||||
struct ReferencesOnlyParentGenerics<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
generics: &'tcx ty::Generics,
|
||||
@ -556,7 +559,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
specializes: specialize::specializes,
|
||||
subst_and_check_impossible_predicates,
|
||||
check_tys_might_be_eq: misc::check_tys_might_be_eq,
|
||||
is_impossible_method,
|
||||
is_impossible_associated_item,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
@ -121,7 +121,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
.tcx
|
||||
.associated_items(impl_def_id)
|
||||
.in_definition_order()
|
||||
.map(|x| clean_middle_assoc_item(x, cx))
|
||||
.filter(|item| !item.is_impl_trait_in_trait())
|
||||
.map(|item| clean_middle_assoc_item(item, cx))
|
||||
.collect::<Vec<_>>(),
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
kind: ImplKind::Blanket(Box::new(clean_middle_ty(
|
||||
|
@ -216,6 +216,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
|
||||
.tcx
|
||||
.associated_items(did)
|
||||
.in_definition_order()
|
||||
.filter(|item| !item.is_impl_trait_in_trait())
|
||||
.map(|item| clean_middle_assoc_item(item, cx))
|
||||
.collect();
|
||||
|
||||
@ -459,6 +460,7 @@ pub(crate) fn build_impl(
|
||||
None => (
|
||||
tcx.associated_items(did)
|
||||
.in_definition_order()
|
||||
.filter(|item| !item.is_impl_trait_in_trait())
|
||||
.filter(|item| {
|
||||
// If this is a trait impl, filter out associated items whose corresponding item
|
||||
// in the associated trait is marked `doc(hidden)`.
|
||||
|
@ -1678,11 +1678,11 @@ fn render_impl(
|
||||
rendering_params: ImplRenderingParameters,
|
||||
) {
|
||||
for trait_item in &t.items {
|
||||
// Skip over any default trait items that are impossible to call
|
||||
// Skip over any default trait items that are impossible to reference
|
||||
// (e.g. if it has a `Self: Sized` bound on an unsized type).
|
||||
if let Some(impl_def_id) = parent.item_id.as_def_id()
|
||||
&& let Some(trait_item_def_id) = trait_item.item_id.as_def_id()
|
||||
&& cx.tcx().is_impossible_method((impl_def_id, trait_item_def_id))
|
||||
&& cx.tcx().is_impossible_associated_item((impl_def_id, trait_item_def_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
pub trait Trait {
|
||||
fn create() -> impl Iterator<Item = u64> {
|
||||
std::iter::empty()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Basic;
|
||||
pub struct Intermediate;
|
||||
pub struct Advanced;
|
||||
|
||||
impl Trait for Basic {
|
||||
// method provided by the trait
|
||||
}
|
||||
|
||||
impl Trait for Intermediate {
|
||||
fn create() -> std::ops::Range<u64> { // concrete return type
|
||||
0..1
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for Advanced {
|
||||
fn create() -> impl Iterator<Item = u64> { // opaque return type
|
||||
std::iter::repeat(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for issue #113929:
|
||||
|
||||
pub trait Def {
|
||||
fn def<T>() -> impl Default {}
|
||||
}
|
||||
|
||||
impl Def for () {}
|
35
tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs
Normal file
35
tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs
Normal file
@ -0,0 +1,35 @@
|
||||
#![crate_name = "user"]
|
||||
// aux-crate:rpitit=ret-pos-impl-trait-in-trait.rs
|
||||
// edition:2021
|
||||
|
||||
// Test that we can correctly render cross-crate RPITITs.
|
||||
// In particular, check that we don't render the internal associated type generated by
|
||||
// their desugaring. We count the number of associated items and ensure that it is exactly one.
|
||||
// This is more robust than checking for the absence of the associated type.
|
||||
|
||||
// @has user/trait.Trait.html
|
||||
// @has - '//*[@id="method.create"]' 'fn create() -> impl Iterator<Item = u64>'
|
||||
// The class "method" is used for all three kinds of associated items at the time of writing.
|
||||
// @count - '//*[@id="main-content"]//section[@class="method"]' 1
|
||||
pub use rpitit::Trait;
|
||||
|
||||
// @has user/struct.Basic.html
|
||||
// @has - '//*[@id="method.create"]' 'fn create() -> impl Iterator<Item = u64>'
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]' 1
|
||||
pub use rpitit::Basic;
|
||||
|
||||
// @has user/struct.Intermediate.html
|
||||
// @has - '//*[@id="method.create"]' 'fn create() -> Range<u64>'
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]' 1
|
||||
pub use rpitit::Intermediate;
|
||||
|
||||
// @has user/struct.Advanced.html
|
||||
// @has - '//*[@id="method.create"]' 'fn create() -> impl Iterator<Item = u64>'
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]' 1
|
||||
pub use rpitit::Advanced;
|
||||
|
||||
// Regression test for issue #113929:
|
||||
|
||||
// @has user/trait.Def.html
|
||||
// @has - '//*[@id="method.def"]' 'fn def<T>() -> impl Default'
|
||||
pub use rpitit::Def;
|
Loading…
x
Reference in New Issue
Block a user