]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_codegen_cranelift/src/value_and_place.rs
Auto merge of #81625 - jonas-schievink:rollup-mshpp2n, r=jonas-schievink
[rust.git] / compiler / rustc_codegen_cranelift / src / value_and_place.rs
index cb40d4ed9a6dffb874b5c90326ccde82b8629c88..765604e0f984ec343bba1fd8398a3b6b6008fc83 100644 (file)
@@ -334,7 +334,9 @@ pub(crate) fn new_stack_slot(
 
         let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
             kind: StackSlotKind::ExplicitSlot,
-            size: u32::try_from(layout.size.bytes()).unwrap(),
+            // FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
+            // specify stack slot alignment.
+            size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16,
             offset: None,
         });
         CPlace {
@@ -450,62 +452,6 @@ pub(crate) fn write_cvalue(
         fx: &mut FunctionCx<'_, 'tcx, impl Module>,
         from: CValue<'tcx>,
     ) {
-        fn assert_assignable<'tcx>(
-            fx: &FunctionCx<'_, 'tcx, impl Module>,
-            from_ty: Ty<'tcx>,
-            to_ty: Ty<'tcx>,
-        ) {
-            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);
-                }
-                (ty::FnPtr(_), ty::FnPtr(_)) => {
-                    let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
-                        ParamEnv::reveal_all(),
-                        from_ty.fn_sig(fx.tcx),
-                    );
-                    let to_sig = fx.tcx.normalize_erasing_late_bound_regions(
-                        ParamEnv::reveal_all(),
-                        to_ty.fn_sig(fx.tcx),
-                    );
-                    assert_eq!(
-                        from_sig, to_sig,
-                        "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
-                        from_sig, to_sig, fx,
-                    );
-                    // fn(&T) -> for<'l> fn(&'l T) is allowed
-                }
-                (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => {
-                    let from_traits = fx
-                        .tcx
-                        .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from_traits);
-                    let to_traits = fx
-                        .tcx
-                        .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_traits);
-                    assert_eq!(
-                        from_traits, to_traits,
-                        "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
-                        from_traits, to_traits, fx,
-                    );
-                    // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
-                }
-                _ => {
-                    assert_eq!(
-                        from_ty,
-                        to_ty,
-                        "Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
-                        from_ty,
-                        to_ty,
-                        fx,
-                    );
-                }
-            }
-        }
-
         assert_assignable(fx, from.layout().ty, self.layout().ty);
 
         self.write_cvalue_maybe_transmute(fx, from, "write_cvalue");
@@ -554,7 +500,9 @@ fn transmute_value<'tcx>(
                     // FIXME do something more efficient for transmutes between vectors and integers.
                     let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
                         kind: StackSlotKind::ExplicitSlot,
-                        size: src_ty.bytes(),
+                        // FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
+                        // specify stack slot alignment.
+                        size: (src_ty.bytes() + 15) / 16 * 16,
                         offset: None,
                     });
                     let ptr = Pointer::stack_slot(stack_slot);
@@ -792,3 +740,62 @@ pub(crate) fn downcast_variant(
         }
     }
 }
+
+#[track_caller]
+pub(crate) fn assert_assignable<'tcx>(
+    fx: &FunctionCx<'_, 'tcx, impl Module>,
+    from_ty: Ty<'tcx>,
+    to_ty: Ty<'tcx>,
+) {
+    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);
+        }
+        (ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
+        | (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
+            assert_assignable(fx, a, b);
+        }
+        (ty::FnPtr(_), ty::FnPtr(_)) => {
+            let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
+                ParamEnv::reveal_all(),
+                from_ty.fn_sig(fx.tcx),
+            );
+            let to_sig = fx
+                .tcx
+                .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_ty.fn_sig(fx.tcx));
+            assert_eq!(
+                from_sig, to_sig,
+                "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
+                from_sig, to_sig, fx,
+            );
+            // fn(&T) -> for<'l> fn(&'l T) is allowed
+        }
+        (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => {
+            for (from, to) in from_traits.iter().zip(to_traits) {
+                let from = fx
+                    .tcx
+                    .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from);
+                let to = fx
+                    .tcx
+                    .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to);
+                assert_eq!(
+                    from, to,
+                    "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
+                    from_traits, to_traits, fx,
+                );
+            }
+            // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
+        }
+        _ => {
+            assert_eq!(
+                from_ty, to_ty,
+                "Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
+                from_ty, to_ty, fx,
+            );
+        }
+    }
+}