about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-08-12 11:59:04 -0400
committerMichael Goulet <michael@errs.io>2024-08-13 16:23:20 -0400
commit5df13af56fb1e4454a057e62d96f7bf2a331a563 (patch)
treedb6afe70ab3c148a44723400a7039fa3013f68ea
parent850bcbdc2e18b3e80d7c12cfcc72a5a219ad3872 (diff)
downloadrust-5df13af56fb1e4454a057e62d96f7bf2a331a563.tar.gz
rust-5df13af56fb1e4454a057e62d96f7bf2a331a563.zip
Use the right type when coercing fn items to pointers
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs2
-rw-r--r--tests/mir-opt/build_correct_coerce.main.built.after.mir2
-rw-r--r--tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs10
-rw-r--r--tests/ui/impl-trait/recursive-ice-101862.stderr4
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.rs1
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.stderr8
7 files changed, 26 insertions, 9 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index b13773ffe14..7da18154432 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1989,9 +1989,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
                         let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
 
-                        if let Err(terr) = self.eq_types(
-                            *ty,
+                        if let Err(terr) = self.sub_types(
                             ty_fn_ptr_from,
+                            *ty,
                             location.to_locations(),
                             ConstraintCategory::Cast { unsize_to: None },
                         ) {
@@ -2014,9 +2014,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         let ty_fn_ptr_from =
                             Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
 
-                        if let Err(terr) = self.eq_types(
-                            *ty,
+                        if let Err(terr) = self.sub_types(
                             ty_fn_ptr_from,
+                            *ty,
                             location.to_locations(),
                             ConstraintCategory::Cast { unsize_to: None },
                         ) {
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index fcd3798eb48..d2fc5a39b1c 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -137,7 +137,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 at.lub(DefineOpaqueTypes::Yes, b, a)
             } else {
                 at.sup(DefineOpaqueTypes::Yes, b, a)
-                    .map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
+                    .map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
             };
 
             // In the new solver, lazy norm may allow us to shallowly equate
diff --git a/tests/mir-opt/build_correct_coerce.main.built.after.mir b/tests/mir-opt/build_correct_coerce.main.built.after.mir
index 10778bb605e..061174d69bb 100644
--- a/tests/mir-opt/build_correct_coerce.main.built.after.mir
+++ b/tests/mir-opt/build_correct_coerce.main.built.after.mir
@@ -9,7 +9,7 @@ fn main() -> () {
 
     bb0: {
         StorageLive(_1);
-        _1 = foo as for<'a, 'b> fn(&'a (), &'b ()) (PointerCoercion(ReifyFnPointer));
+        _1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer));
         FakeRead(ForLet(None), _1);
         _0 = const ();
         StorageDead(_1);
diff --git a/tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs b/tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs
new file mode 100644
index 00000000000..0cecf6808f2
--- /dev/null
+++ b/tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+
+// Check that we use subtyping when reifying a closure into a function pointer.
+
+fn foo(x: &str) {}
+
+fn main() {
+    let c = |_: &str| {};
+    let x = c as fn(&'static str);
+}
diff --git a/tests/ui/impl-trait/recursive-ice-101862.stderr b/tests/ui/impl-trait/recursive-ice-101862.stderr
index f4148720c33..970373422e8 100644
--- a/tests/ui/impl-trait/recursive-ice-101862.stderr
+++ b/tests/ui/impl-trait/recursive-ice-101862.stderr
@@ -11,13 +11,13 @@ LL |     vec![].append(&mut ice(x.as_ref()));
    = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0792]: expected generic type parameter, found `&str`
-  --> $DIR/recursive-ice-101862.rs:6:5
+  --> $DIR/recursive-ice-101862.rs:6:19
    |
 LL | pub fn ice(x: impl AsRef<str>) -> impl IntoIterator<Item = ()> {
    |               --------------- this generic parameter must be used with a generic type parameter
 LL |
 LL |     vec![].append(&mut ice(x.as_ref()));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs
index a5bd3e7afa8..272e5db3b7a 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.rs
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs
@@ -27,5 +27,6 @@ fn main() {
     //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
+    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
     println!("{x}");
 }
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
index a5c2f215134..e5cf5b6bc3d 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
@@ -44,6 +44,12 @@ LL |     drop(<() as Foo>::copy_me(&x));
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 6 previous errors
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
+  --> $DIR/alias-bound-unsound.rs:24:31
+   |
+LL |     drop(<() as Foo>::copy_me(&x));
+   |                               ^^
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0275`.