about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/traits
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2025-06-11 02:50:28 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2025-06-17 18:59:22 -0700
commite4f196a7b43db0f35c9bea3956c2ed1ea1a751be (patch)
tree8f0b24c76c6436bab55c8b0235f7af1f510b6697 /compiler/rustc_codegen_ssa/src/traits
parente703dff8fe220b78195c53478e83fb2f68d8499c (diff)
downloadrust-e4f196a7b43db0f35c9bea3956c2ed1ea1a751be.tar.gz
rust-e4f196a7b43db0f35c9bea3956c2ed1ea1a751be.zip
CodeGen: rework Aggregate implemention for rvalue_creates_operand cases
Another refactor pulled out from 138759

The previous implementation I'd written here based on `index_by_increasing_offset` is complicated to follow and difficult to extend to non-structs.

This changes the implementation, without actually changing any codegen (thus no test changes either), to be more like the existing `extract_field` (<https://github.com/rust-lang/rust/blob/2b0274c71dba0e24370ebf65593da450e2e91868/compiler/rustc_codegen_ssa/src/mir/operand.rs#L345-L425>) in that it allows setting a particular field directly.

Notably I've found this one much easier to get right, in particular because having the `OperandRef<Result<V, Scalar>>` gives a really useful thing to include in ICE messages if something did happen to go wrong.

Diffstat (limited to 'compiler/rustc_codegen_ssa/src/traits')
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index c3fc21a9285..79d15a03972 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -1,4 +1,4 @@
-use rustc_abi::{AddressSpace, Float, Integer, Reg};
+use rustc_abi::{AddressSpace, Float, Integer, Primitive, Reg, Scalar};
 use rustc_middle::bug;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
@@ -84,6 +84,24 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
     fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
         ty.is_freeze(self.tcx(), self.typing_env())
     }
+
+    fn type_from_primitive(&self, p: Primitive) -> Self::Type {
+        use Primitive::*;
+        match p {
+            Int(i, _) => self.type_from_integer(i),
+            Float(f) => self.type_from_float(f),
+            Pointer(address_space) => self.type_ptr_ext(address_space),
+        }
+    }
+
+    fn type_from_scalar(&self, s: Scalar) -> Self::Type {
+        // `MaybeUninit` being `repr(transparent)` somewhat implies that the type
+        // of a scalar has to be the type of its primitive (which is true in LLVM,
+        // where noundef is a parameter attribute or metadata) but if we ever get
+        // a backend where that's no longer true, every use of this will need to
+        // to carefully scrutinized and re-evaluated.
+        self.type_from_primitive(s.primitive())
+    }
 }
 
 impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where