Skip to content

Commit 04eaaa0

Browse files
committed
Fix crash with TAIT in the call codegen code
The new logic is closer to what cg_llvm does. Fixes rust-lang#1240
1 parent f73b0b1 commit 04eaaa0

File tree

4 files changed

+46
-12
lines changed

4 files changed

+46
-12
lines changed

build_system/tests.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,16 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
219219
]);
220220
runner.run_out_command("mod_bench", []);
221221
}),
222+
TestCase::new("aot.issue-72793", &|runner| {
223+
runner.run_rustc([
224+
"example/issue-72793.rs",
225+
"--crate-type",
226+
"bin",
227+
"--target",
228+
&runner.target_compiler.triple,
229+
]);
230+
runner.run_out_command("issue-72793", []);
231+
}),
222232
];
223233

224234
pub(crate) static RAND_REPO: GitRepo =

config.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ aot.subslice-patterns-const-eval
4040
aot.track-caller-attribute
4141
aot.float-minmax-pass
4242
aot.mod_bench
43+
aot.issue-72793
4344

4445
testsuite.extended_sysroot
4546
test.rust-random/rand

example/issue-72793.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Adapted from rustc ui test suite (ui/type-alias-impl-trait/issue-72793.rs)
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
trait T { type Item; }
6+
7+
type Alias<'a> = impl T<Item = &'a ()>;
8+
9+
struct S;
10+
impl<'a> T for &'a S {
11+
type Item = &'a ();
12+
}
13+
14+
fn filter_positive<'a>() -> Alias<'a> {
15+
&S
16+
}
17+
18+
fn with_positive(fun: impl Fn(Alias<'_>)) {
19+
fun(filter_positive());
20+
}
21+
22+
fn main() {
23+
with_positive(|_| ());
24+
}

src/abi/mod.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,13 @@ pub(crate) fn codegen_terminator_call<'tcx>(
341341
destination: Place<'tcx>,
342342
target: Option<BasicBlock>,
343343
) {
344-
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
345-
let fn_sig =
346-
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
344+
let func = codegen_operand(fx, func);
345+
let fn_sig = func.layout().ty.fn_sig(fx.tcx);
347346

348347
let ret_place = codegen_place(fx, destination);
349348

350349
// Handle special calls like intrinsics and empty drop glue.
351-
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
350+
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
352351
let instance = ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
353352
.unwrap()
354353
.unwrap()
@@ -391,17 +390,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
391390
None
392391
};
393392

394-
let extra_args = &args[fn_sig.inputs().len()..];
393+
let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
395394
let extra_args = fx
396395
.tcx
397396
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
398397
let fn_abi = if let Some(instance) = instance {
399398
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
400399
} else {
401-
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
400+
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
402401
};
403402

404-
let is_cold = if fn_sig.abi == Abi::RustCold {
403+
let is_cold = if fn_sig.abi() == Abi::RustCold {
405404
true
406405
} else {
407406
instance
@@ -418,7 +417,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
418417
}
419418

420419
// Unpack arguments tuple for closures
421-
let mut args = if fn_sig.abi == Abi::RustCall {
420+
let mut args = if fn_sig.abi() == Abi::RustCall {
422421
assert_eq!(args.len(), 2, "rust-call abi requires two arguments");
423422
let self_arg = codegen_call_argument_operand(fx, &args[0]);
424423
let pack_arg = codegen_call_argument_operand(fx, &args[1]);
@@ -486,7 +485,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
486485
fx.add_comment(nop_inst, "indirect call");
487486
}
488487

489-
let func = codegen_operand(fx, func).load_scalar(fx);
488+
let func = func.load_scalar(fx);
490489
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
491490
let sig = fx.bcx.import_signature(sig);
492491

@@ -517,11 +516,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
517516
};
518517

519518
// FIXME find a cleaner way to support varargs
520-
if fn_sig.c_variadic {
521-
if !matches!(fn_sig.abi, Abi::C { .. }) {
519+
if fn_sig.c_variadic() {
520+
if !matches!(fn_sig.abi(), Abi::C { .. }) {
522521
fx.tcx.sess.span_fatal(
523522
source_info.span,
524-
&format!("Variadic call for non-C abi {:?}", fn_sig.abi),
523+
&format!("Variadic call for non-C abi {:?}", fn_sig.abi()),
525524
);
526525
}
527526
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();

0 commit comments

Comments
 (0)