Skip to content

Commit 7ef31de

Browse files
Auto merge of #146667 - calebzulawski:simd-mono-lane-limit, r=<try>
Add an attribute to check the number of lanes in a SIMD vector after monomorphization try-job: x86_64-gnu-debug
2 parents ae12bc2 + 60548ff commit 7ef31de

36 files changed

+251
-82
lines changed

compiler/rustc_attr_parsing/src/attributes/crate_level.rs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,4 @@
1-
use std::num::IntErrorKind;
2-
3-
use rustc_hir::limit::Limit;
4-
51
use super::prelude::*;
6-
use crate::session_diagnostics::LimitInvalid;
7-
8-
impl<S: Stage> AcceptContext<'_, '_, S> {
9-
fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
10-
let Some(limit) = nv.value_as_str() else {
11-
self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
12-
return None;
13-
};
14-
15-
let error_str = match limit.as_str().parse() {
16-
Ok(i) => return Some(Limit::new(i)),
17-
Err(e) => match e.kind() {
18-
IntErrorKind::PosOverflow => "`limit` is too large",
19-
IntErrorKind::Empty => "`limit` must be a non-negative integer",
20-
IntErrorKind::InvalidDigit => "not a valid integer",
21-
IntErrorKind::NegOverflow => {
22-
panic!(
23-
"`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
24-
)
25-
}
26-
IntErrorKind::Zero => {
27-
panic!("zero is a valid `limit` so should have returned Ok() when parsing")
28-
}
29-
kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
30-
},
31-
};
32-
33-
self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
34-
35-
None
36-
}
37-
}
382

393
pub(crate) struct CrateNameParser;
404

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,21 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
4949
Some(AttributeKind::RustcObjectLifetimeDefault)
5050
}
5151
}
52+
53+
pub(crate) struct RustcSimdMonomorphizeLaneLimitParser;
54+
55+
impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser {
56+
const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit];
57+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
58+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
59+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
60+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
61+
62+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
63+
let ArgParser::NameValue(nv) = args else {
64+
cx.expected_name_value(cx.attr_span, None);
65+
return None;
66+
};
67+
Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?))
68+
}
69+
}

compiler/rustc_attr_parsing/src/attributes/util.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
use std::num::IntErrorKind;
2+
13
use rustc_ast::LitKind;
24
use rustc_ast::attr::AttributeExt;
35
use rustc_feature::is_builtin_attr_name;
46
use rustc_hir::RustcVersion;
7+
use rustc_hir::limit::Limit;
58
use rustc_span::{Symbol, sym};
69

710
use crate::context::{AcceptContext, Stage};
8-
use crate::parser::ArgParser;
11+
use crate::parser::{ArgParser, NameValueParser};
12+
use crate::session_diagnostics::LimitInvalid;
913

1014
/// Parse a rustc version number written inside string literal in an attribute,
1115
/// 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>(
8589
};
8690
Some(num.0)
8791
}
92+
93+
impl<S: Stage> AcceptContext<'_, '_, S> {
94+
pub(crate) fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
95+
let Some(limit) = nv.value_as_str() else {
96+
self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
97+
return None;
98+
};
99+
100+
let error_str = match limit.as_str().parse() {
101+
Ok(i) => return Some(Limit::new(i)),
102+
Err(e) => match e.kind() {
103+
IntErrorKind::PosOverflow => "`limit` is too large",
104+
IntErrorKind::Empty => "`limit` must be a non-negative integer",
105+
IntErrorKind::InvalidDigit => "not a valid integer",
106+
IntErrorKind::NegOverflow => {
107+
panic!(
108+
"`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
109+
)
110+
}
111+
IntErrorKind::Zero => {
112+
panic!("zero is a valid `limit` so should have returned Ok() when parsing")
113+
}
114+
kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
115+
},
116+
};
117+
118+
self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
119+
120+
None
121+
}
122+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use crate::attributes::prototype::CustomMirParser;
5353
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
5454
use crate::attributes::rustc_internal::{
5555
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
56-
RustcObjectLifetimeDefaultParser,
56+
RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
5757
};
5858
use crate::attributes::semantics::MayDangleParser;
5959
use crate::attributes::stability::{
@@ -198,6 +198,7 @@ attribute_parsers!(
198198
Single<RustcLayoutScalarValidRangeEnd>,
199199
Single<RustcLayoutScalarValidRangeStart>,
200200
Single<RustcObjectLifetimeDefaultParser>,
201+
Single<RustcSimdMonomorphizeLaneLimitParser>,
201202
Single<SanitizeParser>,
202203
Single<ShouldPanicParser>,
203204
Single<SkipDuringMethodDispatchParser>,

compiler/rustc_codegen_cranelift/src/common.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,10 @@ pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
439439
impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
440440
#[inline]
441441
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
442-
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
442+
if let LayoutError::SizeOverflow(_)
443+
| LayoutError::InvalidSimd { .. }
444+
| LayoutError::ReferencesError(_) = err
445+
{
443446
self.0.sess.dcx().span_fatal(span, err.to_string())
444447
} else {
445448
self.0
@@ -458,7 +461,9 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
458461
span: Span,
459462
fn_abi_request: FnAbiRequest<'tcx>,
460463
) -> ! {
461-
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
464+
if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
465+
err
466+
{
462467
self.0.sess.dcx().emit_fatal(Spanned { span, node: err })
463468
} else {
464469
match fn_abi_request {

compiler/rustc_codegen_cranelift/src/global_asm.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> {
4242
impl<'tcx> LayoutOfHelpers<'tcx> for GlobalAsmContext<'_, 'tcx> {
4343
#[inline]
4444
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
45-
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
45+
if let LayoutError::SizeOverflow(_)
46+
| LayoutError::InvalidSimd { .. }
47+
| LayoutError::ReferencesError(_) = err
48+
{
4649
self.tcx.sess.dcx().span_fatal(span, err.to_string())
4750
} else {
4851
self.tcx

compiler/rustc_codegen_gcc/src/context.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,10 @@ impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
529529
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
530530
#[inline]
531531
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
532-
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
532+
if let LayoutError::SizeOverflow(_)
533+
| LayoutError::InvalidSimd { .. }
534+
| LayoutError::ReferencesError(_) = err
535+
{
533536
self.tcx.dcx().emit_fatal(respan(span, err.into_diagnostic()))
534537
} else {
535538
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
@@ -545,7 +548,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
545548
span: Span,
546549
fn_abi_request: FnAbiRequest<'tcx>,
547550
) -> ! {
548-
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
551+
if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
552+
err
553+
{
549554
self.tcx.dcx().emit_fatal(respan(span, err))
550555
} else {
551556
match fn_abi_request {

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,10 @@ impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
10371037
impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
10381038
#[inline]
10391039
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
1040-
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
1040+
if let LayoutError::SizeOverflow(_)
1041+
| LayoutError::ReferencesError(_)
1042+
| LayoutError::InvalidSimd { .. } = err
1043+
{
10411044
self.tcx.dcx().emit_fatal(Spanned { span, node: err.into_diagnostic() })
10421045
} else {
10431046
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
@@ -1054,7 +1057,11 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
10541057
fn_abi_request: FnAbiRequest<'tcx>,
10551058
) -> ! {
10561059
match err {
1057-
FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::Cycle(_)) => {
1060+
FnAbiError::Layout(
1061+
LayoutError::SizeOverflow(_)
1062+
| LayoutError::Cycle(_)
1063+
| LayoutError::InvalidSimd { .. },
1064+
) => {
10581065
self.tcx.dcx().emit_fatal(Spanned { span, node: err });
10591066
}
10601067
_ => match fn_abi_request {

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
477477
ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id),
478478
ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
479479
ty::Adt(def, ..) => match def.adt_kind() {
480-
AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
481-
AdtKind::Union => build_union_type_di_node(cx, unique_type_id),
480+
AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id, span),
481+
AdtKind::Union => build_union_type_di_node(cx, unique_type_id, span),
482482
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span),
483483
},
484484
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
@@ -1076,14 +1076,15 @@ fn visibility_di_flags<'ll, 'tcx>(
10761076
fn build_struct_type_di_node<'ll, 'tcx>(
10771077
cx: &CodegenCx<'ll, 'tcx>,
10781078
unique_type_id: UniqueTypeId<'tcx>,
1079+
span: Span,
10791080
) -> DINodeCreationResult<'ll> {
10801081
let struct_type = unique_type_id.expect_ty();
10811082
let ty::Adt(adt_def, _) = struct_type.kind() else {
10821083
bug!("build_struct_type_di_node() called with non-struct-type: {:?}", struct_type);
10831084
};
10841085
assert!(adt_def.is_struct());
10851086
let containing_scope = get_namespace_for_item(cx, adt_def.did());
1086-
let struct_type_and_layout = cx.layout_of(struct_type);
1087+
let struct_type_and_layout = cx.spanned_layout_of(struct_type, span);
10871088
let variant_def = adt_def.non_enum_variant();
10881089
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
10891090
Some(file_metadata_from_def_id(cx, Some(adt_def.did())))
@@ -1276,14 +1277,15 @@ fn build_closure_env_di_node<'ll, 'tcx>(
12761277
fn build_union_type_di_node<'ll, 'tcx>(
12771278
cx: &CodegenCx<'ll, 'tcx>,
12781279
unique_type_id: UniqueTypeId<'tcx>,
1280+
span: Span,
12791281
) -> DINodeCreationResult<'ll> {
12801282
let union_type = unique_type_id.expect_ty();
12811283
let (union_def_id, variant_def) = match union_type.kind() {
12821284
ty::Adt(def, _) => (def.did(), def.non_enum_variant()),
12831285
_ => bug!("build_union_type_di_node on a non-ADT"),
12841286
};
12851287
let containing_scope = get_namespace_for_item(cx, union_def_id);
1286-
let union_ty_and_layout = cx.layout_of(union_type);
1288+
let union_ty_and_layout = cx.spanned_layout_of(union_type, span);
12871289
let type_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
12881290
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
12891291
Some(file_metadata_from_def_id(cx, Some(union_def_id)))

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
12111211
"the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
12121212
niche optimizations in the standard library",
12131213
),
1214+
rustc_attr!(
1215+
rustc_simd_monomorphize_lane_limit, Normal, template!(NameValueStr: "N"), ErrorFollowing,
1216+
EncodeCrossCrate::Yes,
1217+
"the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \
1218+
for better error messages",
1219+
),
12141220
rustc_attr!(
12151221
rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
12161222
EncodeCrossCrate::Yes,

0 commit comments

Comments
 (0)