about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-05-27 10:44:35 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-19 08:28:31 +0000
commit4a86ef6f4c6069e94e8ea6ebb2b62206dce31cbf (patch)
tree0fc72d76af8853ad89462938bad08156deaa2805
parentcbadf786bc482baf467f601d03a074000c422914 (diff)
downloadrust-4a86ef6f4c6069e94e8ea6ebb2b62206dce31cbf.tar.gz
rust-4a86ef6f4c6069e94e8ea6ebb2b62206dce31cbf.zip
Allow constraining opaque types during auto trait casting
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs2
-rw-r--r--tests/ui/impl-trait/trait_upcasting.rs4
-rw-r--r--tests/ui/impl-trait/trait_upcasting.stderr29
-rw-r--r--tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs18
-rw-r--r--tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr9
5 files changed, 30 insertions, 32 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 84c744be381..f883cd71893 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -1161,7 +1161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let InferOk { mut obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .sup(DefineOpaqueTypes::No, target, source_trait)
+                    .sup(DefineOpaqueTypes::Yes, target, source_trait)
                     .map_err(|_| Unimplemented)?;
 
                 // Register one obligation for 'a: 'b.
diff --git a/tests/ui/impl-trait/trait_upcasting.rs b/tests/ui/impl-trait/trait_upcasting.rs
index cb3c17e87b4..ce811004fae 100644
--- a/tests/ui/impl-trait/trait_upcasting.rs
+++ b/tests/ui/impl-trait/trait_upcasting.rs
@@ -1,5 +1,7 @@
 //! Test that we allow unsizing `Trait<Concrete>` to `Trait<Opaque>` and vice versa
 
+//@ check-pass
+
 trait Trait<T> {}
 
 impl<T, U> Trait<T> for U {}
@@ -8,7 +10,6 @@ fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
     if false {
         let x = hello();
         let _: &'static dyn Trait<()> = x;
-        //~^ ERROR: mismatched types
     }
     todo!()
 }
@@ -18,7 +19,6 @@ fn bye() -> &'static dyn Trait<impl Sized> {
         let mut x = bye();
         let y: &'static (dyn Trait<()> + Send) = &();
         x = y;
-        //~^ ERROR: mismatched types
     }
     todo!()
 }
diff --git a/tests/ui/impl-trait/trait_upcasting.stderr b/tests/ui/impl-trait/trait_upcasting.stderr
deleted file mode 100644
index 2c1aa4bbf80..00000000000
--- a/tests/ui/impl-trait/trait_upcasting.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/trait_upcasting.rs:10:41
-   |
-LL | fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
-   |                                   ---------- the found opaque type
-...
-LL |         let _: &'static dyn Trait<()> = x;
-   |                ----------------------   ^ expected trait `Trait<()>`, found trait `Trait<impl Sized> + Send`
-   |                |
-   |                expected due to this
-   |
-   = note: expected reference `&'static (dyn Trait<()> + 'static)`
-              found reference `&dyn Trait<impl Sized> + Send`
-
-error[E0308]: mismatched types
-  --> $DIR/trait_upcasting.rs:20:13
-   |
-LL | fn bye() -> &'static dyn Trait<impl Sized> {
-   |                                ---------- the expected opaque type
-...
-LL |         x = y;
-   |             ^ expected trait `Trait<impl Sized>`, found trait `Trait<()> + Send`
-   |
-   = note: expected reference `&dyn Trait<impl Sized>`
-              found reference `&'static (dyn Trait<()> + Send + 'static)`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs
new file mode 100644
index 00000000000..bed88db1acc
--- /dev/null
+++ b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.rs
@@ -0,0 +1,18 @@
+//! Show an uninformative diagnostic that we could possibly improve in the future
+
+trait Trait<T> {}
+
+impl<T, U> Trait<T> for U {}
+
+fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
+    //~^ ERROR: type annotations needed
+    if false {
+        let x = hello();
+        let _: &'static dyn Trait<()> = &x;
+        //^ Note the extra `&`, paired with the blanket impl causing
+        // `impl Sized` to never get a hidden type registered.
+    }
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr
new file mode 100644
index 00000000000..92da47b08e9
--- /dev/null
+++ b/tests/ui/impl-trait/trait_upcasting_reference_mismatch.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/trait_upcasting_reference_mismatch.rs:7:35
+   |
+LL | fn hello() -> &'static (dyn Trait<impl Sized> + Send) {
+   |                                   ^^^^^^^^^^ cannot infer type
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.