Recurse into function signatures in assert_assignable

Fixes #1311
This commit is contained in:
bjorn3 2023-06-19 19:30:44 +00:00
parent 43064b005d
commit d169ee3457
4 changed files with 75 additions and 1 deletions

View File

@ -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]);

View File

@ -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

27
example/issue-59326.rs Normal file
View File

@ -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())
}

View File

@ -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!(
from_sig, to_sig,
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!(
abi_from, abi_to,
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
from_sig, to_sig, fx,
);