diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5f674ed7441ba..70f8c70877627 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -774,31 +774,36 @@ fn clean_ty_generics<'tcx>( let mut where_predicates = where_predicates.into_iter().flat_map(|p| clean_predicate(*p, cx)).collect::>(); - // Type parameters have a Sized bound by default unless removed with - // ?Sized. Scan through the predicates and mark any type parameter with - // a Sized bound, removing the bounds as we find them. + // In the surface language, all type parameters except `Self` have an + // implicit `Sized` bound unless removed with `?Sized`. + // However, in the list of where-predicates below, `Sized` appears like a + // normal bound: It's either present (the type is sized) or + // absent (the type is unsized) but never *maybe* (i.e. `?Sized`). // - // Note that associated types also have a sized bound by default, but we + // This is unsuitable for rendering. + // Thus, as a first step remove all `Sized` bounds that should be implicit. + // + // Note that associated types also have an implicit `Sized` bound but we // don't actually know the set of associated types right here so that's - // handled in cleaning associated types + // handled when cleaning associated types. let mut sized_params = FxHashSet::default(); - where_predicates.retain(|pred| match *pred { - WherePredicate::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => { - if bounds.iter().any(|b| b.is_sized_bound(cx)) { - sized_params.insert(*g); - false - } else { - true - } + where_predicates.retain(|pred| { + if let WherePredicate::BoundPredicate { ty: Generic(g), bounds, .. } = pred + && *g != kw::SelfUpper + && bounds.iter().any(|b| b.is_sized_bound(cx)) + { + sized_params.insert(*g); + false + } else { + true } - _ => true, }); - // Run through the type parameters again and insert a ?Sized - // unbound for any we didn't find to be Sized. + // As a final step, go through the type parameters again and insert a + // `?Sized` bound for each one we didn't find to be `Sized`. for tp in &stripped_params { - if matches!(tp.kind, types::GenericParamDefKind::Type { .. }) - && !sized_params.contains(&tp.name) + if let types::GenericParamDefKind::Type { .. } = tp.kind + && !sized_params.contains(&tp.name) { where_predicates.push(WherePredicate::BoundPredicate { ty: Type::Generic(tp.name), diff --git a/src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs b/src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs new file mode 100644 index 0000000000000..e7a13acc6f864 --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] + +pub trait U/*: ?Sized */ { + fn modified(self) -> Self + where + Self: Sized + { + self + } + + fn touch(&self)/* where Self: ?Sized */{} +} + +pub trait S: Sized {} diff --git a/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html new file mode 100644 index 0000000000000..6955a961499ba --- /dev/null +++ b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html @@ -0,0 +1 @@ +

fn touch(&self)

\ No newline at end of file diff --git a/src/test/rustdoc/inline_cross/issue-24183.rs b/src/test/rustdoc/inline_cross/issue-24183.rs new file mode 100644 index 0000000000000..d11b6955f3c0f --- /dev/null +++ b/src/test/rustdoc/inline_cross/issue-24183.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] +#![crate_name = "usr"] + +// aux-crate:issue_24183=issue-24183.rs +// edition: 2021 + +// @has usr/trait.U.html +// @has - '//*[@class="item-decl"]' "pub trait U {" +// @has - '//*[@id="method.modified"]' \ +// "fn modified(self) -> Self\ +// where \ +// Self: Sized" +// @snapshot method_no_where_self_sized - '//*[@id="method.touch"]/*[@class="code-header"]' +pub use issue_24183::U; + +// @has usr/trait.S.html +// @has - '//*[@class="item-decl"]' 'pub trait S: Sized {' +pub use issue_24183::S;