about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-11-05 11:31:28 +0530
committerGitHub <noreply@github.com>2022-11-05 11:31:28 +0530
commit3450aa38d0af7264bb5eb5450880ab82e87b051f (patch)
treeb48c1242d65132964c520f681de9d0b1a5425273
parentaebf7c4a0e68f0211b22ed3c7cec94779e2d83d6 (diff)
parent3aef6c6a54e85ac5cc5e004669404d71be22aafb (diff)
downloadrust-3450aa38d0af7264bb5eb5450880ab82e87b051f.tar.gz
rust-3450aa38d0af7264bb5eb5450880ab82e87b051f.zip
Rollup merge of #103621 - fee1-dead-contrib:iat-fix-use, r=cjgillot
Correctly resolve Inherent Associated Types

I don't know if this is the best way to do this, but at least it is one way.
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs14
-rw-r--r--src/librustdoc/clean/mod.rs3
-rw-r--r--src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs5
-rw-r--r--src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr15
-rw-r--r--src/test/ui/assoc-inherent.rs20
-rw-r--r--src/test/ui/assoc-inherent.stderr17
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs10
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr10
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-use.rs14
-rw-r--r--src/test/ui/resolve/resolve-self-in-impl.stderr30
10 files changed, 66 insertions, 72 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 7747ae14a24..9ad1d2bc542 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1910,6 +1910,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     }
                 }
             }
+
+            // see if we can satisfy using an inherent associated type
+            for impl_ in tcx.inherent_impls(adt_def.did()) {
+                let assoc_ty = tcx.associated_items(impl_).find_by_name_and_kind(
+                    tcx,
+                    assoc_ident,
+                    ty::AssocKind::Type,
+                    *impl_,
+                );
+                if let Some(assoc_ty) = assoc_ty {
+                    let ty = tcx.type_of(assoc_ty.def_id);
+                    return Ok((ty, DefKind::AssocTy, assoc_ty.def_id));
+                }
+            }
         }
 
         // Find the type of the associated item, and the trait where the associated
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8d38f2df0d8..16e2d9a3cfc 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1381,7 +1381,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
                 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),
+                // Otherwise, this is an inherent associated type.
+                _ => return clean_middle_ty(ty, cx, None),
             };
             let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
             register_res(cx, trait_.res);
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
index e58bba64058..94ea0e93bf6 100644
--- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
+++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
@@ -1,3 +1,4 @@
+// check-pass
 // This test ensures that rustdoc does not panic on inherented associated types
 // that are referred to without fully-qualified syntax.
 
@@ -9,8 +10,4 @@ pub struct Struct;
 impl Struct {
     pub type AssocTy = usize;
     pub const AssocConst: Self::AssocTy = 42;
-    //~^ ERROR ambiguous associated type
-    //~| HELP use fully-qualified syntax
-    //~| 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
deleted file mode 100644
index b963b722f66..00000000000
--- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-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`.
diff --git a/src/test/ui/assoc-inherent.rs b/src/test/ui/assoc-inherent.rs
deleted file mode 100644
index c579c962ffc..00000000000
--- a/src/test/ui/assoc-inherent.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Test that inherent associated types work with
-// inherent_associated_types feature gate.
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-struct Foo;
-
-impl Foo {
-    type Bar = isize;
-}
-
-impl Foo {
-    type Baz; //~ ERROR associated type in `impl` without body
-}
-
-fn main() {
-    let x : Foo::Bar; //~ERROR ambiguous associated type
-    x = 0isize;
-}
diff --git a/src/test/ui/assoc-inherent.stderr b/src/test/ui/assoc-inherent.stderr
deleted file mode 100644
index b703453fa03..00000000000
--- a/src/test/ui/assoc-inherent.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: associated type in `impl` without body
-  --> $DIR/assoc-inherent.rs:14:5
-   |
-LL |     type Baz;
-   |     ^^^^^^^^-
-   |             |
-   |             help: provide a definition for the type: `= <type>;`
-
-error[E0223]: ambiguous associated type
-  --> $DIR/assoc-inherent.rs:18:13
-   |
-LL |     let x : Foo::Bar;
-   |             ^^^^^^^^ help: use fully-qualified syntax: `<Foo as Trait>::Bar`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0223`.
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs
new file mode 100644
index 00000000000..71f65b92eae
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs
@@ -0,0 +1,10 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+    type Baz; //~ ERROR associated type in `impl` without body
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr
new file mode 100644
index 00000000000..387a5658da3
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr
@@ -0,0 +1,10 @@
+error: associated type in `impl` without body
+  --> $DIR/assoc-inherent-no-body.rs:7:5
+   |
+LL |     type Baz;
+   |     ^^^^^^^^-
+   |             |
+   |             help: provide a definition for the type: `= <type>;`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-use.rs b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs
new file mode 100644
index 00000000000..7ae425e2aaa
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs
@@ -0,0 +1,14 @@
+// check-pass
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+    type Bar = isize;
+}
+
+fn main() {
+    let x: Foo::Bar;
+    x = 0isize;
+}
diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr
index 9f9ed68898f..b3042d41346 100644
--- a/src/test/ui/resolve/resolve-self-in-impl.stderr
+++ b/src/test/ui/resolve/resolve-self-in-impl.stderr
@@ -1,40 +1,40 @@
 error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:14:13
+  --> $DIR/resolve-self-in-impl.rs:16:6
    |
-LL | impl Tr for Self {}
-   |             ^^^^
+LL | impl Self {}
+   |      ^^^^
    |
    = note: replace `Self` with a different type
 
 error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:15:15
+  --> $DIR/resolve-self-in-impl.rs:17:8
    |
-LL | impl Tr for S<Self> {}
-   |               ^^^^
+LL | impl S<Self> {}
+   |        ^^^^
    |
    = note: replace `Self` with a different type
 
 error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:16:6
+  --> $DIR/resolve-self-in-impl.rs:18:7
    |
-LL | impl Self {}
-   |      ^^^^
+LL | impl (Self, Self) {}
+   |       ^^^^  ^^^^
    |
    = note: replace `Self` with a different type
 
 error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:17:8
+  --> $DIR/resolve-self-in-impl.rs:14:13
    |
-LL | impl S<Self> {}
-   |        ^^^^
+LL | impl Tr for Self {}
+   |             ^^^^
    |
    = note: replace `Self` with a different type
 
 error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:18:7
+  --> $DIR/resolve-self-in-impl.rs:15:15
    |
-LL | impl (Self, Self) {}
-   |       ^^^^  ^^^^
+LL | impl Tr for S<Self> {}
+   |               ^^^^
    |
    = note: replace `Self` with a different type