about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-02-02 15:03:44 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-02-02 15:40:12 +0000
commitbe153f0976705f8d7ca45540a4965bb156b2cc34 (patch)
treed6575d4f5d10c48daff632ee98c02c6b7f0dfad8
parent7f608eb9edb38ff271ff5be50dbbbb424cbf348f (diff)
downloadrust-be153f0976705f8d7ca45540a4965bb156b2cc34.tar.gz
rust-be153f0976705f8d7ca45540a4965bb156b2cc34.zip
Only prevent TAITs from defining each other, RPIT and async are fine, they only ever have one defining site, and it is ordered correctly around expected and actual type in type comparisons
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs9
-rw-r--r--src/test/ui/impl-trait/example-calendar.rs3
-rw-r--r--src/test/ui/impl-trait/example-calendar.stderr19
3 files changed, 10 insertions, 21 deletions
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 35104c71bfc..46420fbe0c3 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -82,7 +82,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
                 ty::Opaque(def_id, substs) => {
                     if let ty::Opaque(did2, _) = *b.kind() {
-                        if self.opaque_type_origin(did2, cause.span).is_some() {
+                        // We could accept this, but there are various ways to handle this situation, and we don't
+                        // want to make a decision on it right now. Likely this case is so super rare anyway, that
+                        // no one encounters it in practice.
+                        // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
+                        // where it is of no concern, so we only check for TAITs.
+                        if let Some(OpaqueTyOrigin::TyAlias) =
+                            self.opaque_type_origin(did2, cause.span)
+                        {
                             self.tcx
                                 .sess
                                 .struct_span_err(
diff --git a/src/test/ui/impl-trait/example-calendar.rs b/src/test/ui/impl-trait/example-calendar.rs
index 26618eec1d7..45dcb74a6e0 100644
--- a/src/test/ui/impl-trait/example-calendar.rs
+++ b/src/test/ui/impl-trait/example-calendar.rs
@@ -1,3 +1,4 @@
+// run-pass
 // ignore-compare-mode-chalk
 
 #![feature(fn_traits,
@@ -589,7 +590,7 @@ fn test_format_month() {
 fn format_months(it: impl Iterator<Item = impl DateIterator>)
                 -> impl Iterator<Item=impl Iterator<Item=String>>
 {
-    it.map(format_month) //~ ERROR opaque type's hidden type cannot be another opaque type
+    it.map(format_month)
 }
 
 /// Takes an iterator of iterators of strings; the sub-iterators are consumed
diff --git a/src/test/ui/impl-trait/example-calendar.stderr b/src/test/ui/impl-trait/example-calendar.stderr
deleted file mode 100644
index 3894285947f..00000000000
--- a/src/test/ui/impl-trait/example-calendar.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/example-calendar.rs:592:5
-   |
-LL |     it.map(format_month)
-   |     ^^^^^^^^^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
-   |
-note: opaque type whose hidden type is being assigned
-  --> $DIR/example-calendar.rs:560:43
-   |
-LL | fn format_month(it: impl DateIterator) -> impl Iterator<Item=String> {
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: opaque type being used as hidden type
-  --> $DIR/example-calendar.rs:590:39
-   |
-LL |                 -> impl Iterator<Item=impl Iterator<Item=String>>
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-