diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b36f0df78f129..fb7965873529f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2064,9 +2064,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), } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 1c14599918419..6bab87e5de546 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -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 }; } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index f5e02940c82e6..9d744237b577a 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -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::>(), polarity: ty::ImplPolarity::Positive, kind: ImplKind::Blanket(Box::new(clean_middle_ty( diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cfd9875e1c8fa..89eaf561e6a58 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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)`. diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4d029407afa49..2fcf61d004908 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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; } diff --git a/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs new file mode 100644 index 0000000000000..c72f011152d83 --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs @@ -0,0 +1,35 @@ +#![feature(return_position_impl_trait_in_trait)] + +pub trait Trait { + fn create() -> impl Iterator { + 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 { // concrete return type + 0..1 + } +} + +impl Trait for Advanced { + fn create() -> impl Iterator { // opaque return type + std::iter::repeat(0) + } +} + +// Regression test for issue #113929: + +pub trait Def { + fn def() -> impl Default {} +} + +impl Def for () {} diff --git a/tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs new file mode 100644 index 0000000000000..8e9ef90201533 --- /dev/null +++ b/tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs @@ -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' +// 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' +// @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' +// @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' +// @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() -> impl Default' +pub use rpitit::Def;