Fix crash with TAIT in the call codegen code

The new logic is closer to what cg_llvm does.

Fixes #1240
This commit is contained in:
bjorn3 2022-12-02 12:44:14 +00:00
parent f73b0b1349
commit 04eaaa043d
4 changed files with 46 additions and 12 deletions

View File

@ -219,6 +219,16 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
]); ]);
runner.run_out_command("mod_bench", []); runner.run_out_command("mod_bench", []);
}), }),
TestCase::new("aot.issue-72793", &|runner| {
runner.run_rustc([
"example/issue-72793.rs",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("issue-72793", []);
}),
]; ];
pub(crate) static RAND_REPO: GitRepo = pub(crate) static RAND_REPO: GitRepo =

View File

@ -40,6 +40,7 @@ aot.subslice-patterns-const-eval
aot.track-caller-attribute aot.track-caller-attribute
aot.float-minmax-pass aot.float-minmax-pass
aot.mod_bench aot.mod_bench
aot.issue-72793
testsuite.extended_sysroot testsuite.extended_sysroot
test.rust-random/rand test.rust-random/rand

24
example/issue-72793.rs Normal file
View File

@ -0,0 +1,24 @@
// Adapted from rustc ui test suite (ui/type-alias-impl-trait/issue-72793.rs)
#![feature(type_alias_impl_trait)]
trait T { type Item; }
type Alias<'a> = impl T<Item = &'a ()>;
struct S;
impl<'a> T for &'a S {
type Item = &'a ();
}
fn filter_positive<'a>() -> Alias<'a> {
&S
}
fn with_positive(fun: impl Fn(Alias<'_>)) {
fun(filter_positive());
}
fn main() {
with_positive(|_| ());
}

View File

@ -341,14 +341,13 @@ pub(crate) fn codegen_terminator_call<'tcx>(
destination: Place<'tcx>, destination: Place<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
) { ) {
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); let func = codegen_operand(fx, func);
let fn_sig = let fn_sig = func.layout().ty.fn_sig(fx.tcx);
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
let ret_place = codegen_place(fx, destination); let ret_place = codegen_place(fx, destination);
// Handle special calls like intrinsics and empty drop glue. // Handle special calls like intrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() { let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
let instance = ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs) let instance = ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
.unwrap() .unwrap()
.unwrap() .unwrap()
@ -391,17 +390,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
None None
}; };
let extra_args = &args[fn_sig.inputs().len()..]; let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
let extra_args = fx let extra_args = fx
.tcx .tcx
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))); .mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
let fn_abi = if let Some(instance) = instance { let fn_abi = if let Some(instance) = instance {
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args) RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
} else { } else {
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args) RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
}; };
let is_cold = if fn_sig.abi == Abi::RustCold { let is_cold = if fn_sig.abi() == Abi::RustCold {
true true
} else { } else {
instance instance
@ -418,7 +417,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
} }
// Unpack arguments tuple for closures // Unpack arguments tuple for closures
let mut args = if fn_sig.abi == Abi::RustCall { let mut args = if fn_sig.abi() == Abi::RustCall {
assert_eq!(args.len(), 2, "rust-call abi requires two arguments"); assert_eq!(args.len(), 2, "rust-call abi requires two arguments");
let self_arg = codegen_call_argument_operand(fx, &args[0]); let self_arg = codegen_call_argument_operand(fx, &args[0]);
let pack_arg = codegen_call_argument_operand(fx, &args[1]); let pack_arg = codegen_call_argument_operand(fx, &args[1]);
@ -486,7 +485,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
fx.add_comment(nop_inst, "indirect call"); fx.add_comment(nop_inst, "indirect call");
} }
let func = codegen_operand(fx, func).load_scalar(fx); let func = func.load_scalar(fx);
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig); let sig = fx.bcx.import_signature(sig);
@ -517,11 +516,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}; };
// FIXME find a cleaner way to support varargs // FIXME find a cleaner way to support varargs
if fn_sig.c_variadic { if fn_sig.c_variadic() {
if !matches!(fn_sig.abi, Abi::C { .. }) { if !matches!(fn_sig.abi(), Abi::C { .. }) {
fx.tcx.sess.span_fatal( fx.tcx.sess.span_fatal(
source_info.span, source_info.span,
&format!("Variadic call for non-C abi {:?}", fn_sig.abi), &format!("Variadic call for non-C abi {:?}", fn_sig.abi()),
); );
} }
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();