about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2023-07-03 18:46:14 +0200
committerGitHub <noreply@github.com>2023-07-03 18:46:14 +0200
commit157bab670fca27c52213f122157e0bc074044bcf (patch)
tree23de9958432176db96306216ca5b6da1d899207f
parentef21fd57c545bf2fdc69f431d2ff73c841b361f1 (diff)
parent838f85d6f7f5d6c5bff1dad5ef9116c5749a122b (diff)
downloadrust-157bab670fca27c52213f122157e0bc074044bcf.tar.gz
rust-157bab670fca27c52213f122157e0bc074044bcf.zip
Rollup merge of #113286 - fmease:iat-dont-select-if-not-enabled, r=compiler-errors
Don't perform selection if inherent associated types are not enabled

Fixes #113265.

As discussed
r? `@compiler-errors`
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs14
-rw-r--r--tests/ui/associated-inherent-types/assoc-inherent-unstable.rs3
-rw-r--r--tests/ui/associated-inherent-types/assoc-inherent-unstable.stderr2
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs4
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr40
-rw-r--r--tests/ui/associated-inherent-types/dont-select-if-disabled.rs17
-rw-r--r--tests/ui/associated-inherent-types/dont-select-if-disabled.stderr24
-rw-r--r--tests/ui/associated-inherent-types/issue-109071.no_gate.stderr10
-rw-r--r--tests/ui/associated-inherent-types/issue-109071.rs1
-rw-r--r--tests/ui/resolve/resolve-self-in-impl.stderr30
10 files changed, 99 insertions, 46 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 2f5bcf8d647..9b5ff3240ed 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1893,6 +1893,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     ) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed> {
         let tcx = self.tcx();
 
+        // Don't attempt to look up inherent associated types when the feature is not enabled.
+        // Theoretically it'd be fine to do so since we feature-gate their definition site.
+        // However, due to current limitations of the implementation (caused by us performing
+        // selection in AstConv), IATs can lead to cycle errors (#108491, #110106) which mask the
+        // feature-gate error, needlessly confusing users that use IATs by accident (#113265).
+        if !tcx.features().inherent_associated_types {
+            return Ok(None);
+        }
+
         let candidates: Vec<_> = tcx
             .inherent_impls(adt_did)
             .iter()
@@ -1903,11 +1912,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             return Ok(None);
         }
 
-        if !tcx.features().inherent_associated_types {
-            tcx.sess
-                .delay_span_bug(span, "found inherent assoc type without the feature being gated");
-        }
-
         //
         // Select applicable inherent associated type candidates modulo regions.
         //
diff --git a/tests/ui/associated-inherent-types/assoc-inherent-unstable.rs b/tests/ui/associated-inherent-types/assoc-inherent-unstable.rs
index 34b4e47bf46..152bb7a60a7 100644
--- a/tests/ui/associated-inherent-types/assoc-inherent-unstable.rs
+++ b/tests/ui/associated-inherent-types/assoc-inherent-unstable.rs
@@ -1,6 +1,9 @@
 // aux-crate:aux=assoc-inherent-unstable.rs
 // edition: 2021
 
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
 type Data = aux::Owner::Data; //~ ERROR use of unstable library feature 'data'
 
 fn main() {}
diff --git a/tests/ui/associated-inherent-types/assoc-inherent-unstable.stderr b/tests/ui/associated-inherent-types/assoc-inherent-unstable.stderr
index c0be8bfd79b..415ee0193c9 100644
--- a/tests/ui/associated-inherent-types/assoc-inherent-unstable.stderr
+++ b/tests/ui/associated-inherent-types/assoc-inherent-unstable.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'data'
-  --> $DIR/assoc-inherent-unstable.rs:4:13
+  --> $DIR/assoc-inherent-unstable.rs:7:13
    |
 LL | type Data = aux::Owner::Data;
    |             ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs
index f41574403d8..33c73c3db89 100644
--- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs
@@ -1,5 +1,7 @@
 // known-bug: #108491
 
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
 // FIXME(inherent_associated_types): This should pass.
 
 struct Foo {
@@ -8,3 +10,5 @@ struct Foo {
 impl Foo {
     pub type Bar = usize;
 }
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
index f313c494671..23269e1afab 100644
--- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
@@ -1,49 +1,43 @@
-error[E0601]: `main` function not found in crate `cycle_iat_inside_of_adt`
-  --> $DIR/cycle-iat-inside-of-adt.rs:10:2
-   |
-LL | }
-   |  ^ consider adding a `main` function to `$DIR/cycle-iat-inside-of-adt.rs`
-
 error[E0391]: cycle detected when computing predicates of `Foo`
-  --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+  --> $DIR/cycle-iat-inside-of-adt.rs:7:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
    |
 note: ...which requires computing predicates of `Foo`...
-  --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+  --> $DIR/cycle-iat-inside-of-adt.rs:7:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
 note: ...which requires computing inferred outlives predicates of `Foo`...
-  --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+  --> $DIR/cycle-iat-inside-of-adt.rs:7:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
    = note: ...which requires computing the inferred outlives predicates for items in this crate...
 note: ...which requires computing type of `Foo::bar`...
-  --> $DIR/cycle-iat-inside-of-adt.rs:6:5
+  --> $DIR/cycle-iat-inside-of-adt.rs:8:5
    |
 LL |     bar: Self::Bar,
    |     ^^^^^^^^^^^^^^
 note: ...which requires computing normalized predicates of `Foo`...
-  --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+  --> $DIR/cycle-iat-inside-of-adt.rs:7:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
    = note: ...which again requires computing predicates of `Foo`, completing the cycle
 note: cycle used when collecting item types in top-level module
-  --> $DIR/cycle-iat-inside-of-adt.rs:5:1
-   |
-LL | / struct Foo {
-LL | |     bar: Self::Bar,
-LL | | }
-LL | | impl Foo {
-LL | |     pub type Bar = usize;
-LL | | }
-   | |_^
+  --> $DIR/cycle-iat-inside-of-adt.rs:3:1
+   |
+LL | / #![feature(inherent_associated_types)]
+LL | | #![allow(incomplete_features)]
+LL | | // FIXME(inherent_associated_types): This should pass.
+LL | |
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0391, E0601.
-For more information about an error, try `rustc --explain E0391`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-inherent-types/dont-select-if-disabled.rs b/tests/ui/associated-inherent-types/dont-select-if-disabled.rs
new file mode 100644
index 00000000000..472be4fbfbc
--- /dev/null
+++ b/tests/ui/associated-inherent-types/dont-select-if-disabled.rs
@@ -0,0 +1,17 @@
+// Regression test for #113265.
+
+// Don't perform selection if the feature is not enabled to prevent cycle errors
+// that exist due to current limitations of the implementation from masking the
+// feature-gate error. See the aforementioned issue.
+// This does lead to rustc not mentioning inherent associated types at usage-sites of
+// IATs that were defined in an external crate but that's acceptable for now.
+
+// FIXME(inherent_associated_types): Revisit this decision once the implementation is smarter.
+
+// The following program would currently lead to a cycle if IATs were enabled.
+
+struct S(S::P); //~ ERROR ambiguous associated type
+
+impl S { type P = (); } //~ ERROR inherent associated types are unstable
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/dont-select-if-disabled.stderr b/tests/ui/associated-inherent-types/dont-select-if-disabled.stderr
new file mode 100644
index 00000000000..87a3f35c968
--- /dev/null
+++ b/tests/ui/associated-inherent-types/dont-select-if-disabled.stderr
@@ -0,0 +1,24 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/dont-select-if-disabled.rs:13:10
+   |
+LL | struct S(S::P);
+   |          ^^^^
+   |
+help: if there were a trait named `Example` with associated type `P` implemented for `S`, you could use the fully-qualified path
+   |
+LL | struct S(<S as Example>::P);
+   |          ~~~~~~~~~~~~~~~~~
+
+error[E0658]: inherent associated types are unstable
+  --> $DIR/dont-select-if-disabled.rs:15:10
+   |
+LL | impl S { type P = (); }
+   |          ^^^^^^^^^^^^
+   |
+   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+   = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0223, E0658.
+For more information about an error, try `rustc --explain E0223`.
diff --git a/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr b/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
index 8b6a8206569..6f206f2b89c 100644
--- a/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
+++ b/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
@@ -29,7 +29,13 @@ LL |     type Item = &[T];
    = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
    = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
 
-error: aborting due to 3 previous errors
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109071.rs:15:22
+   |
+LL |     fn T() -> Option<Self::Item> {}
+   |                      ^^^^^^^^^^ help: use the fully-qualified path: `<Windows<T> as IntoIterator>::Item`
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0107, E0637, E0658.
+Some errors have detailed explanations: E0107, E0223, E0637, E0658.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/associated-inherent-types/issue-109071.rs b/tests/ui/associated-inherent-types/issue-109071.rs
index 73b969d5940..951c708e3f9 100644
--- a/tests/ui/associated-inherent-types/issue-109071.rs
+++ b/tests/ui/associated-inherent-types/issue-109071.rs
@@ -13,6 +13,7 @@ impl<T> Windows { //~ ERROR: missing generics for struct `Windows`
 
 impl<T> Windows<T> {
     fn T() -> Option<Self::Item> {}
+    //[no_gate]~^ ERROR: ambiguous associated type
 }
 
 fn main() {}
diff --git a/tests/ui/resolve/resolve-self-in-impl.stderr b/tests/ui/resolve/resolve-self-in-impl.stderr
index b3042d41346..9f9ed68898f 100644
--- a/tests/ui/resolve/resolve-self-in-impl.stderr
+++ b/tests/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:16:6
+  --> $DIR/resolve-self-in-impl.rs:14:13
    |
-LL | impl 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:17:8
+  --> $DIR/resolve-self-in-impl.rs:15:15
    |
-LL | impl S<Self> {}
-   |        ^^^^
+LL | impl Tr for 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:18:7
+  --> $DIR/resolve-self-in-impl.rs:16:6
    |
-LL | impl (Self, 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:14:13
+  --> $DIR/resolve-self-in-impl.rs:17:8
    |
-LL | impl Tr for 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:15:15
+  --> $DIR/resolve-self-in-impl.rs:18:7
    |
-LL | impl Tr for S<Self> {}
-   |               ^^^^
+LL | impl (Self, Self) {}
+   |       ^^^^  ^^^^
    |
    = note: replace `Self` with a different type