about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-06-19 19:30:44 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-06-19 19:30:44 +0000
commitd169ee3457b284150fabc04a84ea1d873595b5cc (patch)
tree47bfcc3785cb66b40990578f1d63c24fe79e23c4
parent43064b005d06c5db9426a6d479e9f9124122b483 (diff)
downloadrust-d169ee3457b284150fabc04a84ea1d873595b5cc.tar.gz
rust-d169ee3457b284150fabc04a84ea1d873595b5cc.zip
Recurse into function signatures in assert_assignable
Fixes #1311
-rw-r--r--build_system/tests.rs13
-rw-r--r--config.txt1
-rw-r--r--example/issue-59326.rs27
-rw-r--r--src/value_and_place.rs35
4 files changed, 75 insertions, 1 deletions
diff --git a/build_system/tests.rs b/build_system/tests.rs
index 5a255f8cf96..60bf43a15d0 100644
--- a/build_system/tests.rs
+++ b/build_system/tests.rs
@@ -21,6 +21,7 @@ struct TestCase {
 enum TestCaseCmd {
     Custom { func: &'static dyn Fn(&TestRunner<'_>) },
     BuildLib { source: &'static str, crate_types: &'static str },
+    BuildBin { source: &'static str },
     BuildBinAndRun { source: &'static str, args: &'static [&'static str] },
     JitBin { source: &'static str, args: &'static str },
 }
@@ -39,6 +40,10 @@ impl TestCase {
         Self { config, cmd: TestCaseCmd::BuildLib { source, crate_types } }
     }
 
+    const fn build_bin(config: &'static str, source: &'static str) -> Self {
+        Self { config, cmd: TestCaseCmd::BuildBin { source } }
+    }
+
     const fn build_bin_and_run(
         config: &'static str,
         source: &'static str,
@@ -92,6 +97,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
     TestCase::build_bin_and_run("aot.float-minmax-pass", "example/float-minmax-pass.rs", &[]),
     TestCase::build_bin_and_run("aot.mod_bench", "example/mod_bench.rs", &[]),
     TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
+    TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"),
 ];
 
 // FIXME(rust-random/rand#1293): Newer rand versions fail to test on Windows. Update once this is
@@ -405,6 +411,13 @@ impl<'a> TestRunner<'a> {
                         ]);
                     }
                 }
+                TestCaseCmd::BuildBin { source } => {
+                    if self.use_unstable_features {
+                        self.run_rustc([source]);
+                    } else {
+                        self.run_rustc([source, "--cfg", "no_unstable_features"]);
+                    }
+                }
                 TestCaseCmd::BuildBinAndRun { source, args } => {
                     if self.use_unstable_features {
                         self.run_rustc([source]);
diff --git a/config.txt b/config.txt
index d6e3924a24d..fa1c9f4259c 100644
--- a/config.txt
+++ b/config.txt
@@ -41,6 +41,7 @@ aot.track-caller-attribute
 aot.float-minmax-pass
 aot.mod_bench
 aot.issue-72793
+aot.issue-59326
 
 testsuite.extended_sysroot
 test.rust-random/rand
diff --git a/example/issue-59326.rs b/example/issue-59326.rs
new file mode 100644
index 00000000000..70b7c94e15c
--- /dev/null
+++ b/example/issue-59326.rs
@@ -0,0 +1,27 @@
+// Based on https://github.com/rust-lang/rust/blob/689511047a75a30825e367d4fd45c74604d0b15e/tests/ui/issues/issue-59326.rs#L1
+// check-pass
+trait Service {
+    type S;
+}
+
+trait Framing {
+    type F;
+}
+
+impl Framing for () {
+    type F = ();
+}
+
+trait HttpService<F: Framing>: Service<S = F::F> {}
+
+type BoxService = Box<dyn HttpService<(), S = ()>>;
+
+fn build_server<F: FnOnce() -> BoxService>(_: F) {}
+
+fn make_server<F: Framing>() -> Box<dyn HttpService<F, S = F::F>> {
+    unimplemented!()
+}
+
+fn main() {
+    build_server(|| make_server())
+}
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index 133c989b686..89d32f006b7 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -2,6 +2,8 @@
 
 use crate::prelude::*;
 
+use rustc_middle::ty::FnSig;
+
 use cranelift_codegen::entity::EntityRef;
 use cranelift_codegen::ir::immediates::Offset32;
 
@@ -815,11 +817,42 @@ pub(crate) fn assert_assignable<'tcx>(
                 ParamEnv::reveal_all(),
                 from_ty.fn_sig(fx.tcx),
             );
+            let FnSig {
+                inputs_and_output: types_from,
+                c_variadic: c_variadic_from,
+                unsafety: unsafety_from,
+                abi: abi_from,
+            } = from_sig;
             let to_sig = fx
                 .tcx
                 .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_ty.fn_sig(fx.tcx));
+            let FnSig {
+                inputs_and_output: types_to,
+                c_variadic: c_variadic_to,
+                unsafety: unsafety_to,
+                abi: abi_to,
+            } = to_sig;
+            let mut types_from = types_from.iter();
+            let mut types_to = types_to.iter();
+            loop {
+                match (types_from.next(), types_to.next()) {
+                    (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
+                    (None, None) => break,
+                    (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
+                }
+            }
+            assert_eq!(
+                c_variadic_from, c_variadic_to,
+                "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
+                from_sig, to_sig, fx,
+            );
+            assert_eq!(
+                unsafety_from, unsafety_to,
+                "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
+                from_sig, to_sig, fx,
+            );
             assert_eq!(
-                from_sig, to_sig,
+                abi_from, abi_to,
                 "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
                 from_sig, to_sig, fx,
             );