about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-05-27 11:49:05 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-19 08:29:17 +0000
commitba4510ece85018408627b2d3ceef1a3b7889cb71 (patch)
tree5766c04537c56734d570554029184200be936fa4
parent9889a6f5d3f07eb2c8480060f46d5c0e710bba8e (diff)
downloadrust-ba4510ece85018408627b2d3ceef1a3b7889cb71.tar.gz
rust-ba4510ece85018408627b2d3ceef1a3b7889cb71.zip
Allow constraining opaque types during subtyping in the trait system
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--tests/ui/impl-trait/lazy_subtyping_of_opaques.rs67
-rw-r--r--tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr31
5 files changed, 38 insertions, 88 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 510e9a06dfb..4d6ddd7ba66 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -878,9 +878,9 @@ impl<'tcx> InferCtxt<'tcx> {
 
         self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
             if a_is_expected {
-                Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
+                Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
             } else {
-                Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
+                Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
             }
         })
     }
diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs
index 65331894725..8fd1f35645a 100644
--- a/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs
+++ b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs
@@ -2,58 +2,23 @@
 //! No hidden types are being constrained in the subtyping predicate, but type and
 //! lifetime variables get subtyped in the generic parameter list of the opaque.
 
-use std::iter;
-
-mod either {
-    pub enum Either<L, R> {
-        Left(L),
-        Right(R),
-    }
-
-    impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> {
-        type Item = L::Item;
-        fn next(&mut self) -> Option<Self::Item> {
-            todo!()
-        }
-    }
-    pub use self::Either::{Left, Right};
-}
-
-pub enum BabeConsensusLogRef<'a> {
-    NextEpochData(BabeNextEpochRef<'a>),
-    NextConfigData,
-}
-
-impl<'a> BabeConsensusLogRef<'a> {
-    pub fn scale_encoding(
-        &self,
-    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
-        //~^ ERROR is not satisfied
-        //~| ERROR is not satisfied
-        //~| ERROR is not satisfied
-        match self {
-            BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left(
-                digest.scale_encoding().map(either::Left).map(either::Left),
-            )),
-            BabeConsensusLogRef::NextConfigData => either::Right(
-                // The Opaque type from ``scale_encoding` gets used opaquely here, while the `R`
-                // generic parameter of `Either` contains type variables that get subtyped and the
-                // opaque type contains lifetime variables that get subtyped.
-                iter::once(either::Right(either::Left([1])))
-                    .chain(std::iter::once([1]).map(either::Right).map(either::Right)),
-            ),
-        }
-    }
-}
-
-pub struct BabeNextEpochRef<'a>(&'a ());
-
-impl<'a> BabeNextEpochRef<'a> {
-    pub fn scale_encoding(
-        &self,
-    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
-        std::iter::once([1])
+//@ check-pass
+
+fn foo() -> impl Default + Copy {
+    if false {
+        let x = Default::default();
+        // add `Subtype(?x, ?y)` obligation
+        let y = x;
+
+        // Make a tuple `(?x, ?y)` and equate it with `(impl Default, u32)`.
+        // For us to try and prove a `Subtype(impl Default, u32)` obligation,
+        // we have to instantiate both `?x` and `?y` without any
+        // `select_where_possible` calls inbetween.
+        let mut tup = &mut (x, y);
+        let assign_tup = &mut (foo(), 1u32);
+        tup = assign_tup;
     }
+    1u32
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr
deleted file mode 100644
index 2f8c957c2c7..00000000000
--- a/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0277]: the trait bound `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied
-  --> $DIR/lazy_subtyping_of_opaques.rs:30:10
-   |
-LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>`
-
-error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied
-  --> $DIR/lazy_subtyping_of_opaques.rs:30:31
-   |
-LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
-
-error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied
-  --> $DIR/lazy_subtyping_of_opaques.rs:30:31
-   |
-LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
index 72a90287e37..1bc352041a5 100644
--- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
+++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
@@ -7,9 +7,10 @@
 type Tait = impl FnOnce() -> ();
 
 fn reify_as_tait() -> Thunk<Tait> {
+    //~^ ERROR: expected a `FnOnce()` closure, found `()`
     Thunk::new(|cont| cont)
     //~^ ERROR: mismatched types
-    //~| ERROR: mismatched types
+    //~| ERROR: expected a `FnOnce()` closure, found `()`
 }
 
 struct Thunk<F>(F);
diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
index 5a35dc27446..7bc2fa1b09e 100644
--- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
+++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
@@ -1,26 +1,31 @@
-error[E0308]: mismatched types
-  --> $DIR/lazy_subtyping_of_opaques.rs:10:23
+error[E0277]: expected a `FnOnce()` closure, found `()`
+  --> $DIR/lazy_subtyping_of_opaques.rs:11:23
    |
-LL | type Tait = impl FnOnce() -> ();
-   |             ------------------- the found opaque type
-...
 LL |     Thunk::new(|cont| cont)
-   |                       ^^^^ expected `()`, found opaque type
+   |                       ^^^^ expected an `FnOnce()` closure, found `()`
    |
-   = note: expected unit type `()`
-            found opaque type `Tait`
+   = help: the trait `FnOnce()` is not implemented for `()`
+   = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
 
-error[E0308]: mismatched types
-  --> $DIR/lazy_subtyping_of_opaques.rs:10:5
+error[E0277]: expected a `FnOnce()` closure, found `()`
+  --> $DIR/lazy_subtyping_of_opaques.rs:9:23
    |
 LL | fn reify_as_tait() -> Thunk<Tait> {
-   |                       ----------- expected `Thunk<_>` because of return type
+   |                       ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()`
+   |
+   = help: the trait `FnOnce()` is not implemented for `()`
+   = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
+
+error[E0308]: mismatched types
+  --> $DIR/lazy_subtyping_of_opaques.rs:11:5
+   |
 LL |     Thunk::new(|cont| cont)
    |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()`
    |
    = note: expected struct `Thunk<_>`
            found unit type `()`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.