Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?))
}
}
37 changes: 36 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/util.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -195,6 +195,7 @@ attribute_parsers!(
Single<RustcLayoutScalarValidRangeEnd>,
Single<RustcLayoutScalarValidRangeStart>,
Single<RustcObjectLifetimeDefaultParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<SanitizeParser>,
Single<ShouldPanicParser>,
Single<SkipDuringMethodDispatchParser>,
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand All @@ -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 {
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand All @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
}
Unknown(..)
| SizeOverflow(..)
| InvalidSimd { .. }
| NormalizationFailure(..)
| ReferencesError(..)
| Cycle(..) => {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 },

Expand Down
26 changes: 26 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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() }
Expand All @@ -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",
Expand Down Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::MacroEscape( .. )
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
| AttributeKind::ExportStable
| AttributeKind::FfiConst(..)
| AttributeKind::UnstableFeatureBound(..)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_transmute/src/layout/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
13 changes: 0 additions & 13 deletions compiler/rustc_ty_utils/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
Loading
Loading