Skip to content

Commit db85512

Browse files
committed
Auto merge of #79767 - tmiasko:malformed-required-const, r=matthewjasper
Don't ICE on malformed `rustc_args_required_const` attribute
2 parents 8080f54 + 50c6fd6 commit db85512

File tree

3 files changed

+72
-46
lines changed

3 files changed

+72
-46
lines changed

compiler/rustc_passes/src/check_attr.rs

+53-45
Original file line numberDiff line numberDiff line change
@@ -545,60 +545,68 @@ impl CheckAttrVisitor<'tcx> {
545545
target: Target,
546546
item: Option<ItemLike<'_>>,
547547
) -> bool {
548-
if let Target::Fn | Target::Method(..) | Target::ForeignFn = target {
549-
let mut invalid_args = vec![];
550-
for meta in attr.meta_item_list().expect("no meta item list") {
551-
if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
552-
if let Some(ItemLike::Item(Item {
553-
kind: ItemKind::Fn(FnSig { decl, .. }, ..),
554-
..
555-
}))
556-
| Some(ItemLike::ForeignItem(ForeignItem {
557-
kind: ForeignItemKind::Fn(decl, ..),
558-
..
559-
})) = item
560-
{
561-
let arg_count = decl.inputs.len() as u128;
562-
if *val >= arg_count {
563-
let span = meta.span();
564-
self.tcx
565-
.sess
566-
.struct_span_err(span, "index exceeds number of arguments")
567-
.span_label(
568-
span,
569-
format!(
570-
"there {} only {} argument{}",
571-
if arg_count != 1 { "are" } else { "is" },
572-
arg_count,
573-
pluralize!(arg_count)
574-
),
575-
)
576-
.emit();
577-
return false;
578-
}
579-
} else {
580-
bug!("should be a function item");
548+
let is_function = matches!(target, Target::Fn | Target::Method(..) | Target::ForeignFn);
549+
if !is_function {
550+
self.tcx
551+
.sess
552+
.struct_span_err(attr.span, "attribute should be applied to a function")
553+
.span_label(*span, "not a function")
554+
.emit();
555+
return false;
556+
}
557+
558+
let list = match attr.meta_item_list() {
559+
// The attribute form is validated on AST.
560+
None => return false,
561+
Some(it) => it,
562+
};
563+
564+
let mut invalid_args = vec![];
565+
for meta in list {
566+
if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
567+
if let Some(ItemLike::Item(Item {
568+
kind: ItemKind::Fn(FnSig { decl, .. }, ..),
569+
..
570+
}))
571+
| Some(ItemLike::ForeignItem(ForeignItem {
572+
kind: ForeignItemKind::Fn(decl, ..),
573+
..
574+
})) = item
575+
{
576+
let arg_count = decl.inputs.len() as u128;
577+
if *val >= arg_count {
578+
let span = meta.span();
579+
self.tcx
580+
.sess
581+
.struct_span_err(span, "index exceeds number of arguments")
582+
.span_label(
583+
span,
584+
format!(
585+
"there {} only {} argument{}",
586+
if arg_count != 1 { "are" } else { "is" },
587+
arg_count,
588+
pluralize!(arg_count)
589+
),
590+
)
591+
.emit();
592+
return false;
581593
}
582594
} else {
583-
invalid_args.push(meta.span());
595+
bug!("should be a function item");
584596
}
585-
}
586-
if !invalid_args.is_empty() {
587-
self.tcx
588-
.sess
589-
.struct_span_err(invalid_args, "arguments should be non-negative integers")
590-
.emit();
591-
false
592597
} else {
593-
true
598+
invalid_args.push(meta.span());
594599
}
595-
} else {
600+
}
601+
602+
if !invalid_args.is_empty() {
596603
self.tcx
597604
.sess
598-
.struct_span_err(attr.span, "attribute should be applied to a function")
599-
.span_label(*span, "not a function")
605+
.struct_span_err(invalid_args, "arguments should be non-negative integers")
600606
.emit();
601607
false
608+
} else {
609+
true
602610
}
603611
}
604612

src/test/ui/invalid-rustc_args_required_const-arguments.rs

+6
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,10 @@ extern {
2323
fn foo7(_: u8);
2424
}
2525

26+
#[rustc_args_required_const] //~ ERROR malformed `rustc_args_required_const` attribute
27+
fn bar1() {}
28+
29+
#[rustc_args_required_const = 1] //~ ERROR malformed `rustc_args_required_const` attribute
30+
fn bar2() {}
31+
2632
fn main() {}

src/test/ui/invalid-rustc_args_required_const-arguments.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ LL | #[rustc_args_required_const(0usize)]
66
|
77
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
88

9+
error: malformed `rustc_args_required_const` attribute input
10+
--> $DIR/invalid-rustc_args_required_const-arguments.rs:26:1
11+
|
12+
LL | #[rustc_args_required_const]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_args_required_const(N)]`
14+
15+
error: malformed `rustc_args_required_const` attribute input
16+
--> $DIR/invalid-rustc_args_required_const-arguments.rs:29:1
17+
|
18+
LL | #[rustc_args_required_const = 1]
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_args_required_const(N)]`
20+
921
error: index exceeds number of arguments
1022
--> $DIR/invalid-rustc_args_required_const-arguments.rs:3:29
1123
|
@@ -44,5 +56,5 @@ error: index exceeds number of arguments
4456
LL | #[rustc_args_required_const(1)]
4557
| ^ there is only 1 argument
4658

47-
error: aborting due to 7 previous errors
59+
error: aborting due to 9 previous errors
4860

0 commit comments

Comments
 (0)