about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2021-09-02 19:10:21 +0200
committerGitHub <noreply@github.com>2021-09-02 19:10:21 +0200
commit73162aabc7627b904ec5d79e7cb37268df57c0b5 (patch)
treee73d559c98514d0004fa7baba543af6dfb5f0c8b
parentf4193346fe4378dfae003a6fb22b324a7ed0c0e6 (diff)
parent50983ba6df8effdeae993b2d4ed5eefe8c863bbf (diff)
downloadrust-73162aabc7627b904ec5d79e7cb37268df57c0b5.tar.gz
rust-73162aabc7627b904ec5d79e7cb37268df57c0b5.zip
Rollup merge of #88573 - camelid:rustdoc-assoc-panic, r=GuillaumeGomez
rustdoc: Don't panic on ambiguous inherent associated types

Instead, return `Type::Infer` since compilation should fail anyway.
That's how rustdoc handles `hir::TyKind::Err`s, so this just extends
that behavior to `ty::Err`s when analyzing associated types.

For some reason, the error is printed twice with rustdoc (though only
once with rustc). I'm not sure why that is, but it's better than
panicking.

This commit also makes rustdoc fail early in the non-projection,
non-error case, instead of returning a `Res::Err` that would likely
cause rustdoc to panic later on. This change is originally from #88379.

r? `@GuillaumeGomez`
-rw-r--r--src/librustdoc/clean/mod.rs10
-rw-r--r--src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs17
-rw-r--r--src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr15
3 files changed, 38 insertions, 4 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bde821c5d9c..a9baa1c31ae 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1311,10 +1311,11 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
         }
         hir::QPath::TypeRelative(ref qself, ref segment) => {
             let ty = hir_ty_to_ty(cx.tcx, hir_ty);
-            let res = if let ty::Projection(proj) = ty.kind() {
-                Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id)
-            } else {
-                Res::Err
+            let res = match ty.kind() {
+                ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
+                // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
+                ty::Error(_) => return Type::Infer,
+                _ => bug!("clean: expected associated type, found `{:?}`", ty),
             };
             let trait_path = hir::Path { span, res, segments: &[] }.clean(cx);
             Type::QPath {
@@ -1379,6 +1380,7 @@ impl Clean<Type> for hir::Ty<'_> {
                 DynTrait(bounds, lifetime)
             }
             TyKind::BareFn(ref barefn) => BareFunction(Box::new(barefn.clean(cx))),
+            // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
             TyKind::Infer | TyKind::Err => Infer,
             TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind),
         }
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
new file mode 100644
index 00000000000..3ad56aebc21
--- /dev/null
+++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
@@ -0,0 +1,17 @@
+// This test ensures that rustdoc does not panic on inherented associated types
+// that are referred to without fully-qualified syntax.
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+pub struct Struct;
+
+impl Struct {
+    pub type AssocTy = usize;
+    pub const AssocConst: Self::AssocTy = 42;
+    //~^ ERROR ambiguous associated type
+    //~| HELP use fully-qualified syntax
+    // FIXME: for some reason, the error is shown twice with rustdoc but only once with rustc
+    //~| ERROR ambiguous associated type
+    //~| HELP use fully-qualified syntax
+}
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
new file mode 100644
index 00000000000..b963b722f66
--- /dev/null
+++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
@@ -0,0 +1,15 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
+   |
+LL |     pub const AssocConst: Self::AssocTy = 42;
+   |                           ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
+   |
+LL |     pub const AssocConst: Self::AssocTy = 42;
+   |                           ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0223`.