Skip to content

Commit

Permalink
Unrolled build for rust-lang#137852
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#137852 - moulins:layout-nonarray-simd-deadcode, r=workingjubilee

Remove layouting dead code for non-array SIMD types.

These aren't supported anymore, and are already rejected in type checking.
  • Loading branch information
rust-timer authored Mar 4, 2025
2 parents 2010bba + cbe32a7 commit b437d69
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 114 deletions.
2 changes: 0 additions & 2 deletions compiler/rustc_ty_utils/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ ty_utils_logical_op_not_supported = unsupported operation in generic constants,
ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants
ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with more than one array field
ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop
ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_ty_utils/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,6 @@ pub(crate) struct ZeroLengthSimdType<'tcx> {
pub ty: Ty<'tcx>,
}

#[derive(Diagnostic)]
#[diag(ty_utils_multiple_array_fields_simd_type)]
pub(crate) struct MultipleArrayFieldsSimdType<'tcx> {
pub ty: Ty<'tcx>,
}

#[derive(Diagnostic)]
#[diag(ty_utils_oversized_simd_type)]
pub(crate) struct OversizedSimdType<'tcx> {
Expand Down
89 changes: 19 additions & 70 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ use rustc_span::{Symbol, sym};
use tracing::{debug, instrument, trace};
use {rustc_abi as abi, rustc_hir as hir};

use crate::errors::{
MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType,
};
use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};

mod invariant;

Expand Down Expand Up @@ -450,71 +448,26 @@ fn layout_of_uncached<'tcx>(

// SIMD vector types.
ty::Adt(def, args) if def.repr().simd() => {
if !def.is_struct() {
// Should have yielded E0517 by now.
let guar = tcx
.dcx()
.delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
return Err(error(cx, LayoutError::ReferencesError(guar)));
}

let fields = &def.non_enum_variant().fields;

// Supported SIMD vectors are homogeneous ADTs with at least one field:
// Supported SIMD vectors are ADTs with a single array field:
//
// * #[repr(simd)] struct S(T, T, T, T);
// * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
// * #[repr(simd)] struct S([T; 4])
//
// where T is a primitive scalar (integer/float/pointer).

// SIMD vectors with zero fields are not supported.
// (should be caught by typeck)
if fields.is_empty() {
tcx.dcx().emit_fatal(ZeroLengthSimdType { ty })
}

// Type of the first ADT field:
let f0_ty = fields[FieldIdx::ZERO].ty(tcx, args);

// Heterogeneous SIMD vectors are not supported:
// (should be caught by typeck)
for fi in fields {
if fi.ty(tcx, args) != f0_ty {
let guar = tcx.dcx().delayed_bug(
"#[repr(simd)] was applied to an ADT with heterogeneous field type",
);
return Err(error(cx, LayoutError::ReferencesError(guar)));
}
}

// The element type and number of elements of the SIMD vector
// are obtained from:
//
// * the element type and length of the single array field, if
// the first field is of array type, or
//
// * the homogeneous field type and the number of fields.
let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() {
// First ADT field is an array:

// SIMD vectors with multiple array fields are not supported:
// Can't be caught by typeck with a generic simd type.
if def.non_enum_variant().fields.len() != 1 {
tcx.dcx().emit_fatal(MultipleArrayFieldsSimdType { ty });
}

// Extract the number of elements from the layout of the array field:
let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else {
return Err(error(cx, LayoutError::Unknown(ty)));
};

(*e_ty, *count, true)
} else {
// First ADT field is not an array:
(f0_ty, def.non_enum_variant().fields.len() as _, false)
let Some(ty::Array(e_ty, e_len)) = def
.is_struct()
.then(|| &def.variant(FIRST_VARIANT).fields)
.filter(|fields| fields.len() == 1)
.map(|fields| *fields[FieldIdx::ZERO].ty(tcx, args).kind())
else {
// Invalid SIMD types should have been caught by typeck by now.
let guar = tcx.dcx().delayed_bug("#[repr(simd)] was applied to an invalid ADT");
return Err(error(cx, LayoutError::ReferencesError(guar)));
};

let e_len = extract_const_value(cx, ty, e_len)?
.try_to_target_usize(tcx)
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;

// SIMD vectors of zero length are not supported.
// Additionally, lengths are capped at 2^16 as a fixed maximum backends must
// support.
Expand Down Expand Up @@ -559,16 +512,12 @@ fn layout_of_uncached<'tcx>(
};
let size = size.align_to(align.abi);

// Compute the placement of the vector fields:
let fields = if is_array {
FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
} else {
FieldsShape::Array { stride: e_ly.size, count: e_len }
};

tcx.mk_layout(LayoutData {
variants: Variants::Single { index: FIRST_VARIANT },
fields,
fields: FieldsShape::Arbitrary {
offsets: [Size::ZERO].into(),
memory_index: [0].into(),
},
backend_repr: abi,
largest_niche: e_ly.largest_niche,
uninhabited: false,
Expand Down
47 changes: 11 additions & 36 deletions src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,40 +133,22 @@ fn layout_of_simd_ty(
env: Arc<TraitEnvironment>,
dl: &TargetDataLayout,
) -> Result<Arc<Layout>, LayoutError> {
let fields = db.field_types(id.into());

// Supported SIMD vectors are homogeneous ADTs with at least one field:
// Supported SIMD vectors are homogeneous ADTs with exactly one array field:
//
// * #[repr(simd)] struct S(T, T, T, T);
// * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
// * #[repr(simd)] struct S([T; 4])
//
// where T is a primitive scalar (integer/float/pointer).

let f0_ty = match fields.iter().next() {
Some(it) => it.1.clone().substitute(Interner, subst),
None => return Err(LayoutError::InvalidSimdType),
let fields = db.field_types(id.into());
let mut fields = fields.iter();
let Some(TyKind::Array(e_ty, e_len)) = fields
.next()
.filter(|_| fields.next().is_none())
.map(|f| f.1.clone().substitute(Interner, subst).kind(Interner).clone())
else {
return Err(LayoutError::InvalidSimdType);
};

// The element type and number of elements of the SIMD vector
// are obtained from:
//
// * the element type and length of the single array field, if
// the first field is of array type, or
//
// * the homogeneous field type and the number of fields.
let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
// Extract the number of elements from the layout of the array field:
let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
else {
return Err(LayoutError::Unknown);
};

(e_ty.clone(), count, true)
} else {
// First ADT field is not an array:
(f0_ty, fields.iter().count() as u64, false)
};
let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64;

// Compute the ABI of the element type:
let e_ly = db.layout_of_ty(e_ty, env)?;
Expand All @@ -182,16 +164,9 @@ fn layout_of_simd_ty(
let align = dl.llvmlike_vector_align(size);
let size = size.align_to(align.abi);

// Compute the placement of the vector fields:
let fields = if is_array {
FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
} else {
FieldsShape::Array { stride: e_ly.size, count: e_len }
};

Ok(Arc::new(Layout {
variants: Variants::Single { index: struct_variant_idx() },
fields,
fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() },
backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len },
largest_niche: e_ly.largest_niche,
uninhabited: false,
Expand Down

0 comments on commit b437d69

Please sign in to comment.