about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-26 01:49:00 +0200
committerGitHub <noreply@github.com>2024-08-26 01:49:00 +0200
commit621f2726fb20f6bed17ae183eeae8ca239af8d08 (patch)
tree672b007b2ddb71a21b88223e336c8dfb4cda6ce3
parentc6db1ca3c93ad69692a4c4b5542f26fda4bf3aec (diff)
parenta97b41f1880f3aef9f4669ba56cf2e4d830825bc (diff)
downloadrust-621f2726fb20f6bed17ae183eeae8ca239af8d08.tar.gz
rust-621f2726fb20f6bed17ae183eeae8ca239af8d08.zip
Rollup merge of #129288 - compiler-errors:unsafe-fn-coercion, r=lcnr
Use subtyping for `UnsafeFnPointer` coercion, too

I overlooked this in #129059, which changed MIR typechecking to use subtyping for other fn pointer coercions.

Fixes #129285
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs14
2 files changed, 16 insertions, 2 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6983cda6ddf..3b3898ccd4d 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2043,9 +2043,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
                         let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(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 },
                         ) {
diff --git a/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs b/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs
new file mode 100644
index 00000000000..19723bee4d4
--- /dev/null
+++ b/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+fn higher_ranked_fndef(ctx: &mut ()) {}
+
+fn test(higher_ranked_fnptr: fn(&mut ())) {
+    fn as_unsafe<T>(_: unsafe fn(T)) {}
+
+    // Make sure that we can cast higher-ranked fn items and pointers to
+    // a non-higher-ranked target.
+    as_unsafe(higher_ranked_fndef);
+    as_unsafe(higher_ranked_fnptr);
+}
+
+fn main() {}