about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <liehr.exchange@gmx.net>2022-10-19 17:27:08 +0200
committerLeón Orell Valerian Liehr <liehr.exchange@gmx.net>2022-10-19 17:27:08 +0200
commitf543770de26849fee46d7974ba9212e402c22151 (patch)
tree0ed4f6e42426b1db87892ea02d88e4e96796770b
parente94827e5b09b5b098ea10d0c57a84892fc73b5a7 (diff)
downloadrust-f543770de26849fee46d7974ba9212e402c22151.tar.gz
rust-f543770de26849fee46d7974ba9212e402c22151.zip
rustdoc: Do not filter out `Self: Sized` bounds
-rw-r--r--src/librustdoc/clean/mod.rs41
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs14
-rw-r--r--src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html1
-rw-r--r--src/test/rustdoc/inline_cross/issue-24183.rs18
4 files changed, 56 insertions, 18 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5f674ed7441..70f8c708776 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::<Vec<_>>();
 
-    // 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 00000000000..e7a13acc6f8
--- /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 00000000000..6955a961499
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html
@@ -0,0 +1 @@
+<h4 class="code-header">fn <a href="#method.touch" class="fnname">touch</a>(&amp;self)</h4>
\ 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 00000000000..d11b6955f3c
--- /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;