about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-07-25 13:17:53 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-07-25 13:17:53 +0000
commitfd2669d1e91027c4ce31f9a3690ce6dab7d8619a (patch)
tree1cdd98003f065243a5ade19c6359aa30f7c52488
parent7ef2ba8f7b2b3076d906567bb107b0437c45be48 (diff)
downloadrust-fd2669d1e91027c4ce31f9a3690ce6dab7d8619a.tar.gz
rust-fd2669d1e91027c4ce31f9a3690ce6dab7d8619a.zip
Fix -Zpolymorphize
-rwxr-xr-xscripts/test_rustc_tests.sh3
-rw-r--r--src/abi/pass_mode.rs2
-rw-r--r--src/constant.rs3
-rw-r--r--src/main_shim.rs3
-rw-r--r--src/value_and_place.rs51
5 files changed, 49 insertions, 13 deletions
diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh
index 90293a04cb5..944787612d8 100755
--- a/scripts/test_rustc_tests.sh
+++ b/scripts/test_rustc_tests.sh
@@ -99,9 +99,6 @@ rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
 # ============
 rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
 
-rm -r src/test/ui/polymorphization/ # polymorphization not yet supported
-rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same
-
 rm src/test/incremental/spike-neg1.rs # errors out for some reason
 rm src/test/incremental/spike-neg2.rs # same
 rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs
index 33c5f3283be..6c10baa53d4 100644
--- a/src/abi/pass_mode.rs
+++ b/src/abi/pass_mode.rs
@@ -216,7 +216,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
     arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
     is_owned: bool,
 ) -> SmallVec<[Value; 2]> {
-    assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
+    assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty, 16);
     match arg_abi.mode {
         PassMode::Ignore => smallvec![],
         PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
diff --git a/src/constant.rs b/src/constant.rs
index 9a8139053f1..c83dab951bc 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -432,7 +432,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
             let data_id = match reloc_target_alloc {
                 GlobalAlloc::Function(instance) => {
                     assert_eq!(addend, 0);
-                    let func_id = crate::abi::import_function(tcx, module, instance);
+                    let func_id =
+                        crate::abi::import_function(tcx, module, instance.polymorphize(tcx));
                     let local_func_id = module.declare_func_in_data(func_id, &mut data_ctx);
                     data_ctx.write_function_addr(offset.bytes() as u32, local_func_id);
                     continue;
diff --git a/src/main_shim.rs b/src/main_shim.rs
index 2f71a70a449..c67b6e98b32 100644
--- a/src/main_shim.rs
+++ b/src/main_shim.rs
@@ -109,7 +109,8 @@ pub(crate) fn maybe_create_entry_wrapper(
                     tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
                 )
                 .unwrap()
-                .unwrap();
+                .unwrap()
+                .polymorphize(tcx);
 
                 let report_name = tcx.symbol_name(report).name;
                 let report_sig = get_function_sig(tcx, m.isa().triple(), report);
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index d82de1d3d8d..6674099e9a2 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -426,7 +426,7 @@ impl<'tcx> CPlace<'tcx> {
     }
 
     pub(crate) fn write_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>) {
-        assert_assignable(fx, from.layout().ty, self.layout().ty);
+        assert_assignable(fx, from.layout().ty, self.layout().ty, 16);
 
         self.write_cvalue_maybe_transmute(fx, from, "write_cvalue");
     }
@@ -788,18 +788,25 @@ pub(crate) fn assert_assignable<'tcx>(
     fx: &FunctionCx<'_, '_, 'tcx>,
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
+    limit: usize,
 ) {
+    if limit == 0 {
+        // assert_assignable exists solely to catch bugs in cg_clif. it isn't necessary for
+        // soundness. don't attempt to check deep types to avoid exponential behavior in certain
+        // cases.
+        return;
+    }
     match (from_ty.kind(), to_ty.kind()) {
         (ty::Ref(_, a, _), ty::Ref(_, b, _))
         | (
             ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }),
             ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }),
         ) => {
-            assert_assignable(fx, *a, *b);
+            assert_assignable(fx, *a, *b, limit - 1);
         }
         (ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
         | (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
-            assert_assignable(fx, *a, *b);
+            assert_assignable(fx, *a, *b, limit - 1);
         }
         (ty::FnPtr(_), ty::FnPtr(_)) => {
             let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
@@ -829,6 +836,17 @@ pub(crate) fn assert_assignable<'tcx>(
             }
             // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
         }
+        (&ty::Tuple(types_a), &ty::Tuple(types_b)) => {
+            let mut types_a = types_a.iter();
+            let mut types_b = types_b.iter();
+            loop {
+                match (types_a.next(), types_b.next()) {
+                    (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
+                    (None, None) => return,
+                    (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
+                }
+            }
+        }
         (&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
             if adt_def_a.did() == adt_def_b.did() =>
         {
@@ -836,18 +854,37 @@ pub(crate) fn assert_assignable<'tcx>(
             let mut types_b = substs_b.types();
             loop {
                 match (types_a.next(), types_b.next()) {
-                    (Some(a), Some(b)) => assert_assignable(fx, a, b),
+                    (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
                     (None, None) => return,
                     (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
                 }
             }
         }
-        (ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b),
+        (ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
+        (&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
+            if def_id_a == def_id_b =>
+        {
+            let mut types_a = substs_a.types();
+            let mut types_b = substs_b.types();
+            loop {
+                match (types_a.next(), types_b.next()) {
+                    (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
+                    (None, None) => return,
+                    (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
+                }
+            }
+        }
+        (ty::Param(_), _) | (_, ty::Param(_)) if fx.tcx.sess.opts.unstable_opts.polymorphize => {
+            // No way to check if it is correct or not with polymorphization enabled
+        }
         _ => {
             assert_eq!(
-                from_ty, to_ty,
+                from_ty,
+                to_ty,
                 "Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
-                from_ty, to_ty, fx,
+                from_ty.kind(),
+                to_ty.kind(),
+                fx,
             );
         }
     }