Add an attribute to check the number of lanes in a SIMD vector after monomorphization

Unify zero-length and oversized SIMD errors
This commit is contained in:
Caleb Zulawski 2025-09-16 02:23:24 -04:00
parent 9d82de19df
commit f5c6c9542e
35 changed files with 245 additions and 78 deletions

View file

@ -1,40 +1,4 @@
use std::num::IntErrorKind;
use rustc_hir::limit::Limit;
use super::prelude::*;
use crate::session_diagnostics::LimitInvalid;
impl<S: Stage> AcceptContext<'_, '_, S> {
fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
let Some(limit) = nv.value_as_str() else {
self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let error_str = match limit.as_str().parse() {
Ok(i) => return Some(Limit::new(i)),
Err(e) => match e.kind() {
IntErrorKind::PosOverflow => "`limit` is too large",
IntErrorKind::Empty => "`limit` must be a non-negative integer",
IntErrorKind::InvalidDigit => "not a valid integer",
IntErrorKind::NegOverflow => {
panic!(
"`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
)
}
IntErrorKind::Zero => {
panic!("zero is a valid `limit` so should have returned Ok() when parsing")
}
kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
},
};
self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
None
}
}
pub(crate) struct CrateNameParser;

View file

@ -49,3 +49,21 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
Some(AttributeKind::RustcObjectLifetimeDefault)
}
}
pub(crate) struct RustcSimdMonomorphizeLaneLimitParser;
impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser {
const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let ArgParser::NameValue(nv) = args else {
cx.expected_name_value(cx.attr_span, None);
return None;
};
Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?))
}
}

View file

@ -1,11 +1,15 @@
use std::num::IntErrorKind;
use rustc_ast::LitKind;
use rustc_ast::attr::AttributeExt;
use rustc_feature::is_builtin_attr_name;
use rustc_hir::RustcVersion;
use rustc_hir::limit::Limit;
use rustc_span::{Symbol, sym};
use crate::context::{AcceptContext, Stage};
use crate::parser::ArgParser;
use crate::parser::{ArgParser, NameValueParser};
use crate::session_diagnostics::LimitInvalid;
/// Parse a rustc version number written inside string literal in an attribute,
/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are
@ -85,3 +89,34 @@ pub(crate) fn parse_single_integer<S: Stage>(
};
Some(num.0)
}
impl<S: Stage> AcceptContext<'_, '_, S> {
pub(crate) fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
let Some(limit) = nv.value_as_str() else {
self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let error_str = match limit.as_str().parse() {
Ok(i) => return Some(Limit::new(i)),
Err(e) => match e.kind() {
IntErrorKind::PosOverflow => "`limit` is too large",
IntErrorKind::Empty => "`limit` must be a non-negative integer",
IntErrorKind::InvalidDigit => "not a valid integer",
IntErrorKind::NegOverflow => {
panic!(
"`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
)
}
IntErrorKind::Zero => {
panic!("zero is a valid `limit` so should have returned Ok() when parsing")
}
kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
},
};
self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
None
}
}

View file

@ -53,7 +53,7 @@ use crate::attributes::prototype::CustomMirParser;
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
use crate::attributes::rustc_internal::{
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
RustcObjectLifetimeDefaultParser,
RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
};
use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
@ -195,6 +195,7 @@ attribute_parsers!(
Single<RustcLayoutScalarValidRangeEnd>,
Single<RustcLayoutScalarValidRangeStart>,
Single<RustcObjectLifetimeDefaultParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<SanitizeParser>,
Single<ShouldPanicParser>,
Single<SkipDuringMethodDispatchParser>,

View file

@ -439,7 +439,10 @@ pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
if let LayoutError::SizeOverflow(_)
| LayoutError::InvalidSimd { .. }
| LayoutError::ReferencesError(_) = err
{
self.0.sess.dcx().span_fatal(span, err.to_string())
} else {
self.0
@ -458,7 +461,9 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
span: Span,
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
err
{
self.0.sess.dcx().emit_fatal(Spanned { span, node: err })
} else {
match fn_abi_request {

View file

@ -42,7 +42,10 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> {
impl<'tcx> LayoutOfHelpers<'tcx> for GlobalAsmContext<'_, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
if let LayoutError::SizeOverflow(_)
| LayoutError::InvalidSimd { .. }
| LayoutError::ReferencesError(_) = err
{
self.tcx.sess.dcx().span_fatal(span, err.to_string())
} else {
self.tcx

View file

@ -529,7 +529,10 @@ impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
if let LayoutError::SizeOverflow(_)
| LayoutError::InvalidSimd { .. }
| LayoutError::ReferencesError(_) = err
{
self.tcx.dcx().emit_fatal(respan(span, err.into_diagnostic()))
} else {
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
@ -545,7 +548,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
span: Span,
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
err
{
self.tcx.dcx().emit_fatal(respan(span, err))
} else {
match fn_abi_request {

View file

@ -991,7 +991,10 @@ impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
if let LayoutError::SizeOverflow(_)
| LayoutError::ReferencesError(_)
| LayoutError::InvalidSimd { .. } = err
{
self.tcx.dcx().emit_fatal(Spanned { span, node: err.into_diagnostic() })
} else {
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
@ -1008,7 +1011,11 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
match err {
FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::Cycle(_)) => {
FnAbiError::Layout(
LayoutError::SizeOverflow(_)
| LayoutError::Cycle(_)
| LayoutError::InvalidSimd { .. },
) => {
self.tcx.dcx().emit_fatal(Spanned { span, node: err });
}
_ => match fn_abi_request {

View file

@ -1203,6 +1203,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
niche optimizations in the standard library",
),
rustc_attr!(
rustc_simd_monomorphize_lane_limit, Normal, template!(NameValueStr: "N"), ErrorFollowing,
EncodeCrossCrate::Yes,
"the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \
for better error messages",
),
rustc_attr!(
rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes,

View file

@ -642,6 +642,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_object_lifetime_default]`.
RustcObjectLifetimeDefault,
/// Represents `#[rustc_simd_monomorphize_lane_limit = "N"]`.
RustcSimdMonomorphizeLaneLimit(Limit),
/// Represents `#[sanitize]`
///
/// the on set and off set are distjoint since there's a third option: unset.

View file

@ -85,6 +85,7 @@ impl AttributeKind {
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
RustcObjectLifetimeDefault => No,
RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate
Sanitize { .. } => No,
ShouldPanic { .. } => No,
SkipDuringMethodDispatch { .. } => No,

View file

@ -213,6 +213,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
}
Unknown(..)
| SizeOverflow(..)
| InvalidSimd { .. }
| NormalizationFailure(..)
| ReferencesError(..)
| Cycle(..) => {

View file

@ -98,6 +98,12 @@ middle_layout_references_error =
middle_layout_size_overflow =
values of the type `{$ty}` are too big for the target architecture
middle_layout_simd_too_many =
the SIMD type `{$ty}` has more elements than the limit {$max_lanes}
middle_layout_simd_zero_length =
the SIMD type `{$ty}` has zero elements
middle_layout_too_generic = the type `{$ty}` does not have a fixed layout
middle_layout_unknown =

View file

@ -141,6 +141,12 @@ pub enum LayoutError<'tcx> {
#[diag(middle_layout_size_overflow)]
Overflow { ty: Ty<'tcx> },
#[diag(middle_layout_simd_too_many)]
SimdTooManyLanes { ty: Ty<'tcx>, max_lanes: u64 },
#[diag(middle_layout_simd_zero_length)]
SimdZeroLength { ty: Ty<'tcx> },
#[diag(middle_layout_normalization_failure)]
NormalizationFailure { ty: Ty<'tcx>, failure_ty: String },

View file

@ -217,6 +217,15 @@ impl fmt::Display for ValidityRequirement {
}
}
#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
pub enum SimdLayoutError {
/// The vector has 0 lanes.
ZeroLength,
/// The vector has more lanes than supported or permitted by
/// #\[rustc_simd_monomorphize_lane_limit\].
TooManyLanes(u64),
}
#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
pub enum LayoutError<'tcx> {
/// A type doesn't have a sensible layout.
@ -229,6 +238,8 @@ pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
/// The size of a type exceeds [`TargetDataLayout::obj_size_bound`].
SizeOverflow(Ty<'tcx>),
/// A SIMD vector has invalid layout, such as zero-length or too many lanes.
InvalidSimd { ty: Ty<'tcx>, kind: SimdLayoutError },
/// The layout can vary due to a generic parameter.
///
/// Unlike `Unknown`, this variant is a "soft" error and indicates that the layout
@ -256,6 +267,10 @@ impl<'tcx> LayoutError<'tcx> {
match self {
Unknown(_) => middle_layout_unknown,
SizeOverflow(_) => middle_layout_size_overflow,
InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
middle_layout_simd_too_many
}
InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => middle_layout_simd_zero_length,
TooGeneric(_) => middle_layout_too_generic,
NormalizationFailure(_, _) => middle_layout_normalization_failure,
Cycle(_) => middle_layout_cycle,
@ -270,6 +285,10 @@ impl<'tcx> LayoutError<'tcx> {
match self {
Unknown(ty) => E::Unknown { ty },
SizeOverflow(ty) => E::Overflow { ty },
InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) } => {
E::SimdTooManyLanes { ty, max_lanes }
}
InvalidSimd { ty, kind: SimdLayoutError::ZeroLength } => E::SimdZeroLength { ty },
TooGeneric(ty) => E::TooGeneric { ty },
NormalizationFailure(ty, e) => {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
@ -292,6 +311,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
LayoutError::SizeOverflow(ty) => {
write!(f, "values of the type `{ty}` are too big for the target architecture")
}
LayoutError::InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) } => {
write!(f, "the SIMD type `{ty}` has more elements than the limit {max_lanes}")
}
LayoutError::InvalidSimd { ty, kind: SimdLayoutError::ZeroLength } => {
write!(f, "the SIMD type `{ty}` has zero elements")
}
LayoutError::NormalizationFailure(t, e) => write!(
f,
"unable to determine layout for `{}` because `{}` cannot be normalized",
@ -373,6 +398,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
e @ LayoutError::Cycle(_)
| e @ LayoutError::Unknown(_)
| e @ LayoutError::SizeOverflow(_)
| e @ LayoutError::InvalidSimd { .. }
| e @ LayoutError::NormalizationFailure(..)
| e @ LayoutError::ReferencesError(_),
) => return Err(e),

View file

@ -254,6 +254,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::MacroEscape( .. )
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
| AttributeKind::ExportStable
| AttributeKind::FfiConst(..)
| AttributeKind::UnstableFeatureBound(..)

View file

@ -1937,6 +1937,7 @@ symbols! {
rustc_regions,
rustc_reservation_impl,
rustc_serialize,
rustc_simd_monomorphize_lane_limit,
rustc_skip_during_method_dispatch,
rustc_specialization_trait,
rustc_std_internal_symbol,

View file

@ -279,6 +279,7 @@ pub(crate) mod rustc {
LayoutError::Unknown(..)
| LayoutError::ReferencesError(..)
| LayoutError::TooGeneric(..)
| LayoutError::InvalidSimd { .. }
| LayoutError::NormalizationFailure(..) => Self::UnknownLayout,
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
LayoutError::Cycle(err) => Self::TypeError(*err),

View file

@ -78,19 +78,6 @@ pub(crate) struct UnexpectedFnPtrAssociatedItem {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ty_utils_zero_length_simd_type)]
pub(crate) struct ZeroLengthSimdType<'tcx> {
pub ty: Ty<'tcx>,
}
#[derive(Diagnostic)]
#[diag(ty_utils_oversized_simd_type)]
pub(crate) struct OversizedSimdType<'tcx> {
pub ty: Ty<'tcx>,
pub max_lanes: u64,
}
#[derive(Diagnostic)]
#[diag(ty_utils_non_primitive_simd_type)]
pub(crate) struct NonPrimitiveSimdType<'tcx> {

View file

@ -7,11 +7,13 @@ use rustc_abi::{
VariantIdx, Variants, WrappingRange,
};
use rustc_hashes::Hash64;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::find_attr;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{
FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout,
FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, SimdLayoutError, TyAndLayout,
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{
@ -22,7 +24,7 @@ use rustc_span::{Symbol, sym};
use tracing::{debug, instrument};
use {rustc_abi as abi, rustc_hir as hir};
use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};
use crate::errors::NonPrimitiveSimdType;
mod invariant;
@ -120,11 +122,11 @@ fn map_error<'tcx>(
}
LayoutCalculatorError::ZeroLengthSimdType => {
// Can't be caught in typeck if the array length is generic.
cx.tcx().dcx().emit_fatal(ZeroLengthSimdType { ty })
LayoutError::InvalidSimd { ty, kind: SimdLayoutError::ZeroLength }
}
LayoutCalculatorError::OversizedSimdType { max_lanes } => {
// Can't be caught in typeck if the array length is generic.
cx.tcx().dcx().emit_fatal(OversizedSimdType { ty, max_lanes })
LayoutError::InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) }
}
LayoutCalculatorError::NonPrimitiveSimdType(field) => {
// This error isn't caught in typeck, e.g., if
@ -561,6 +563,22 @@ fn layout_of_uncached<'tcx>(
let e_ly = cx.layout_of(e_ty)?;
// Check for the rustc_simd_monomorphize_lane_limit attribute and check the lane limit
if let Some(limit) = find_attr!(
tcx.get_all_attrs(def.did()),
AttributeKind::RustcSimdMonomorphizeLaneLimit(limit) => limit
) {
if !limit.value_within_limit(e_len as usize) {
return Err(map_error(
&cx,
ty,
rustc_abi::LayoutCalculatorError::OversizedSimdType {
max_lanes: limit.0 as u64,
},
));
}
}
map_layout(cx.calc.simd_type(e_ly, e_len, def.repr().packed()))?
}

View file

@ -65,5 +65,10 @@
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type's layout depended on the type's layout itself. {# #}
</p>
{% when Err(LayoutError::InvalidSimd {..}) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the vector type had zero elements or too many elements. {# #}
</p>
{% endmatch %}
</div> {# #}

View file

@ -0,0 +1,5 @@
#![feature(rustc_attrs, repr_simd)]
#[repr(simd, packed)]
#[rustc_simd_monomorphize_lane_limit = "8"]
pub struct Simd<T, const N: usize>(pub [T; N]);

View file

@ -6,7 +6,5 @@
struct Simd<T, const N: usize>([T; N]);
fn main() {
let _too_big = Simd([1_u16; 54321]);
let _too_big = Simd([1_u16; 54321]); //~ ERROR the SIMD type `Simd<u16, 54321>` has more elements than the limit 32768
}
//~? ERROR monomorphising SIMD type `Simd<u16, 54321>` of length greater than 32768

View file

@ -1,4 +1,8 @@
error: monomorphising SIMD type `Simd<u16, 54321>` of length greater than 32768
error: the SIMD type `Simd<u16, 54321>` has more elements than the limit 32768
--> $DIR/monomorphize-too-long.rs:9:9
|
LL | let _too_big = Simd([1_u16; 54321]);
| ^^^^^^^^
error: aborting due to 1 previous error

View file

@ -6,7 +6,5 @@
struct Simd<T, const N: usize>([T; N]);
fn main() {
let _empty = Simd([1.0; 0]);
let _empty = Simd([1.0; 0]); //~ ERROR the SIMD type `Simd<f64, 0>` has zero elements
}
//~? ERROR monomorphising SIMD type `Simd<f64, 0>` of zero length

View file

@ -1,4 +1,8 @@
error: monomorphising SIMD type `Simd<f64, 0>` of zero length
error: the SIMD type `Simd<f64, 0>` has zero elements
--> $DIR/monomorphize-zero-length.rs:9:9
|
LL | let _empty = Simd([1.0; 0]);
| ^^^^^^
error: aborting due to 1 previous error

View file

@ -0,0 +1,12 @@
//@ build-fail
//@ aux-crate:simd=simd-lane-limit.rs
extern crate simd;
use simd::Simd;
fn main() {
// test non-power-of-two, since #[repr(simd, packed)] has unusual layout
let _x: Simd<i32, 24> = Simd([0; 24]);
//~^ ERROR the SIMD type `simd::Simd<i32, 24>` has more elements than the limit 8
}

View file

@ -0,0 +1,8 @@
error: the SIMD type `simd::Simd<i32, 24>` has more elements than the limit 8
--> $DIR/simd-lane-limit-err-npow2.rs:10:9
|
LL | let _x: Simd<i32, 24> = Simd([0; 24]);
| ^^
error: aborting due to 1 previous error

View file

@ -0,0 +1,11 @@
//@ build-fail
//@ aux-crate:simd=simd-lane-limit.rs
extern crate simd;
use simd::Simd;
fn main() {
let _x: Simd<i32, 16> = Simd([0; 16]);
//~^ ERROR the SIMD type `simd::Simd<i32, 16>` has more elements than the limit 8
}

View file

@ -0,0 +1,8 @@
error: the SIMD type `simd::Simd<i32, 16>` has more elements than the limit 8
--> $DIR/simd-lane-limit-err.rs:9:9
|
LL | let _x: Simd<i32, 16> = Simd([0; 16]);
| ^^
error: aborting due to 1 previous error

View file

@ -0,0 +1,14 @@
//@ build-pass
//@ aux-crate:simd=simd-lane-limit.rs
extern crate simd;
use simd::Simd;
fn main() {
let _x: Simd<i32, 4> = Simd([0; 4]);
let _y: Simd<i32, 8> = Simd([0; 8]);
// test non-power-of-two, since #[repr(simd, packed)] has unusual layout
let _z: Simd<i32, 6> = Simd([0; 6]);
}

View file

@ -6,7 +6,5 @@
struct Simd<const N: usize>([f32; N]);
fn main() {
let _ = Simd::<0>([]);
let _empty = Simd::<0>([]); //~ ERROR the SIMD type `Simd<0>` has zero elements
}
//~? ERROR monomorphising SIMD type `Simd<0>` of zero length

View file

@ -1,4 +1,8 @@
error: monomorphising SIMD type `Simd<0>` of zero length
error: the SIMD type `Simd<0>` has zero elements
--> $DIR/type-generic-monomorphisation-empty.rs:9:9
|
LL | let _empty = Simd::<0>([]);
| ^^^^^^
error: aborting due to 1 previous error

View file

@ -6,7 +6,6 @@
struct Simd<const N: usize>([f32; N]);
fn main() {
let _ = Simd::<65536>([0.; 65536]);
let _x = Simd::<65536>([0.; 65536]);
//~^ ERROR the SIMD type `Simd<65536>` has more elements than the limit 32768
}
//~? ERROR monomorphising SIMD type `Simd<65536>` of length greater than 32768

View file

@ -1,4 +1,8 @@
error: monomorphising SIMD type `Simd<65536>` of length greater than 32768
error: the SIMD type `Simd<65536>` has more elements than the limit 32768
--> $DIR/type-generic-monomorphisation-oversized.rs:9:9
|
LL | let _x = Simd::<65536>([0.; 65536]);
| ^^
error: aborting due to 1 previous error