about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-06-26 16:13:52 +0000
committerbors <bors@rust-lang.org>2021-06-26 16:13:52 +0000
commit3ddb78a34608848a60f6ca5b6ccfde8340302372 (patch)
tree0a83949d4e595cd47c6e09c51f5ce8e13af51dda
parentf2571a2dd68ff1d84b5df07cb38831627df6aaff (diff)
parentf14bdb506a89afaf634b68a4292ad9cf6014f60c (diff)
downloadrust-3ddb78a34608848a60f6ca5b6ccfde8340302372.tar.gz
rust-3ddb78a34608848a60f6ca5b6ccfde8340302372.zip
Auto merge of #86449 - Stupremee:render-self-cast-in-type-bound, r=GuillaumeGomez
rustdoc: Render `<Self as X>::Y` type casts properly across crate bounds

My last PR that introduced the type casting did not work for cross-crate re-exported traits, which is fixed in this PR.

Fully resolves #85454
-rw-r--r--src/librustdoc/clean/mod.rs21
-rw-r--r--src/test/rustdoc/auxiliary/issue-85454.rs17
-rw-r--r--src/test/rustdoc/issue-85454.rs14
3 files changed, 48 insertions, 4 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index fea09b383c0..6abe1c7cd61 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -20,7 +20,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
 use rustc_middle::middle::resolve_lifetime as rl;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
-use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtKind, DefIdTree, Lift, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_mir::const_eval::{is_const_fn, is_unstable_const_fn};
 use rustc_span::hygiene::{AstPass, MacroKind};
@@ -438,8 +438,23 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
         let (name, kind) = match self.kind {
             ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime),
             ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
-                let default =
-                    if has_default { Some(cx.tcx.type_of(self.def_id).clean(cx)) } else { None };
+                let default = if has_default {
+                    let mut default = cx.tcx.type_of(self.def_id).clean(cx);
+
+                    // We need to reassign the `self_def_id`, if there's a parent (which is the
+                    // `Self` type), so we can properly render `<Self as X>` casts, because the
+                    // information about which type `Self` is, is only present here, but not in
+                    // the cleaning process of the type itself. To resolve this and have the
+                    // `self_def_id` set, we override it here.
+                    // See https://github.com/rust-lang/rust/issues/85454
+                    if let QPath { ref mut self_def_id, .. } = default {
+                        *self_def_id = cx.tcx.parent(self.def_id);
+                    }
+
+                    Some(default)
+                } else {
+                    None
+                };
                 (
                     self.name,
                     GenericParamDefKind::Type {
diff --git a/src/test/rustdoc/auxiliary/issue-85454.rs b/src/test/rustdoc/auxiliary/issue-85454.rs
new file mode 100644
index 00000000000..45664dfc382
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/issue-85454.rs
@@ -0,0 +1,17 @@
+// @has issue_85454/trait.FromResidual.html
+// @has - '//pre[@class="rust trait"]' 'pub trait FromResidual<R = <Self as Try>::Residual> { fn from_residual(residual: R) -> Self; }'
+pub trait FromResidual<R = <Self as Try>::Residual> {
+    fn from_residual(residual: R) -> Self;
+}
+
+pub trait Try: FromResidual {
+    type Output;
+    type Residual;
+    fn from_output(output: Self::Output) -> Self;
+    fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+}
+
+pub enum ControlFlow<B, C = ()> {
+    Continue(C),
+    Break(B),
+}
diff --git a/src/test/rustdoc/issue-85454.rs b/src/test/rustdoc/issue-85454.rs
index 45664dfc382..3351b5c8350 100644
--- a/src/test/rustdoc/issue-85454.rs
+++ b/src/test/rustdoc/issue-85454.rs
@@ -1,4 +1,10 @@
-// @has issue_85454/trait.FromResidual.html
+// aux-build:issue-85454.rs
+// build-aux-docs
+#![crate_name = "foo"]
+
+extern crate issue_85454;
+
+// @has foo/trait.FromResidual.html
 // @has - '//pre[@class="rust trait"]' 'pub trait FromResidual<R = <Self as Try>::Residual> { fn from_residual(residual: R) -> Self; }'
 pub trait FromResidual<R = <Self as Try>::Residual> {
     fn from_residual(residual: R) -> Self;
@@ -15,3 +21,9 @@ pub enum ControlFlow<B, C = ()> {
     Continue(C),
     Break(B),
 }
+
+pub mod reexport {
+    // @has foo/reexport/trait.FromResidual.html
+    // @has - '//pre[@class="rust trait"]' 'pub trait FromResidual<R = <Self as Try>::Residual> { fn from_residual(residual: R) -> Self; }'
+    pub use issue_85454::*;
+}