about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-12-02 12:44:14 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-12-02 12:44:14 +0000
commit04eaaa043d15b3c99e46819464669eb52d37320c (patch)
tree538f554928b1ee95a1023b8c9604e933934eedc2
parentf73b0b1349cb5190f7b1e3e4378acc1a434e1687 (diff)
downloadrust-04eaaa043d15b3c99e46819464669eb52d37320c.tar.gz
rust-04eaaa043d15b3c99e46819464669eb52d37320c.zip
Fix crash with TAIT in the call codegen code
The new logic is closer to what cg_llvm does.

Fixes #1240
-rw-r--r--build_system/tests.rs10
-rw-r--r--config.txt1
-rw-r--r--example/issue-72793.rs24
-rw-r--r--src/abi/mod.rs23
4 files changed, 46 insertions, 12 deletions
diff --git a/build_system/tests.rs b/build_system/tests.rs
index bd31d5e6bbf..99a8e5b3220 100644
--- a/build_system/tests.rs
+++ b/build_system/tests.rs
@@ -219,6 +219,16 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
         ]);
         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 =
diff --git a/config.txt b/config.txt
index 0d539191b12..258b67e9314 100644
--- a/config.txt
+++ b/config.txt
@@ -40,6 +40,7 @@ aot.subslice-patterns-const-eval
 aot.track-caller-attribute
 aot.float-minmax-pass
 aot.mod_bench
+aot.issue-72793
 
 testsuite.extended_sysroot
 test.rust-random/rand
diff --git a/example/issue-72793.rs b/example/issue-72793.rs
new file mode 100644
index 00000000000..b1bb9b8e1e7
--- /dev/null
+++ b/example/issue-72793.rs
@@ -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(|_| ());
+}
diff --git a/src/abi/mod.rs b/src/abi/mod.rs
index 1e22537c2ba..d62966b162f 100644
--- a/src/abi/mod.rs
+++ b/src/abi/mod.rs
@@ -341,14 +341,13 @@ pub(crate) fn codegen_terminator_call<'tcx>(
     destination: Place<'tcx>,
     target: Option<BasicBlock>,
 ) {
-    let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
-    let fn_sig =
-        fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
+    let func = codegen_operand(fx, func);
+    let fn_sig = func.layout().ty.fn_sig(fx.tcx);
 
     let ret_place = codegen_place(fx, destination);
 
     // 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)
             .unwrap()
             .unwrap()
@@ -391,17 +390,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
         None
     };
 
-    let extra_args = &args[fn_sig.inputs().len()..];
+    let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
     let extra_args = 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 {
         RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
     } 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
     } else {
         instance
@@ -418,7 +417,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
     }
 
     // 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");
         let self_arg = codegen_call_argument_operand(fx, &args[0]);
         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");
             }
 
-            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 = fx.bcx.import_signature(sig);
 
@@ -517,11 +516,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
         };
 
         // FIXME find a cleaner way to support varargs
-        if fn_sig.c_variadic {
-            if !matches!(fn_sig.abi, Abi::C { .. }) {
+        if fn_sig.c_variadic() {
+            if !matches!(fn_sig.abi(), Abi::C { .. }) {
                 fx.tcx.sess.span_fatal(
                     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();