about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2024-06-19 13:04:56 +0200
committerGitHub <noreply@github.com>2024-06-19 13:04:56 +0200
commit25d47fe3885e962b489f04ba5f7cd3364d4e4ada (patch)
tree72f5fb8cd291ccebdb10b2ed0404e55b70b13a1a
parent3c0f019b3c56c1a0e6e0cbed6f8a8b0b245e5665 (diff)
parentba4510ece85018408627b2d3ceef1a3b7889cb71 (diff)
downloadrust-25d47fe3885e962b489f04ba5f7cd3364d4e4ada.tar.gz
rust-25d47fe3885e962b489f04ba5f7cd3364d4e4ada.zip
Rollup merge of #125447 - oli-obk:eq_opaque_pred, r=compiler-errors
Allow constraining opaque types during subtyping in the trait system

Previous attempt: https://github.com/rust-lang/rust/pull/123979

Sometimes we don't immediately perform subtyping, but instead register a subtyping obligation and solve that obligation when its inference variables become resolved. Unlike immediate subtyping, we currently do not allow registering hidden types for opaque types. This PR also allows that.
-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`.