]> git.lizzy.rs Git - rust.git/commitdiff
Don't ICE on malformed `rustc_args_required_const` attribute
authorTomasz Miąsko <tomasz.miasko@gmail.com>
Sun, 6 Dec 2020 00:00:00 +0000 (00:00 +0000)
committerTomasz Miąsko <tomasz.miasko@gmail.com>
Sun, 6 Dec 2020 00:00:00 +0000 (00:00 +0000)
compiler/rustc_passes/src/check_attr.rs
src/test/ui/invalid-rustc_args_required_const-arguments.rs
src/test/ui/invalid-rustc_args_required_const-arguments.stderr

index fc97ca035b9b4028e8475f89a3ba71c266d20c4c..73fb28e5c9aa68eafacd3ec875fb0638d4c23d88 100644 (file)
@@ -545,60 +545,68 @@ fn check_rustc_args_required_const(
         target: Target,
         item: Option<ItemLike<'_>>,
     ) -> bool {
-        if let Target::Fn | Target::Method(..) | Target::ForeignFn = target {
-            let mut invalid_args = vec![];
-            for meta in attr.meta_item_list().expect("no meta item list") {
-                if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
-                    if let Some(ItemLike::Item(Item {
-                        kind: ItemKind::Fn(FnSig { decl, .. }, ..),
-                        ..
-                    }))
-                    | Some(ItemLike::ForeignItem(ForeignItem {
-                        kind: ForeignItemKind::Fn(decl, ..),
-                        ..
-                    })) = item
-                    {
-                        let arg_count = decl.inputs.len() as u128;
-                        if *val >= arg_count {
-                            let span = meta.span();
-                            self.tcx
-                                .sess
-                                .struct_span_err(span, "index exceeds number of arguments")
-                                .span_label(
-                                    span,
-                                    format!(
-                                        "there {} only {} argument{}",
-                                        if arg_count != 1 { "are" } else { "is" },
-                                        arg_count,
-                                        pluralize!(arg_count)
-                                    ),
-                                )
-                                .emit();
-                            return false;
-                        }
-                    } else {
-                        bug!("should be a function item");
+        let is_function = matches!(target, Target::Fn | Target::Method(..) | Target::ForeignFn);
+        if !is_function {
+            self.tcx
+                .sess
+                .struct_span_err(attr.span, "attribute should be applied to a function")
+                .span_label(*span, "not a function")
+                .emit();
+            return false;
+        }
+
+        let list = match attr.meta_item_list() {
+            // The attribute form is validated on AST.
+            None => return false,
+            Some(it) => it,
+        };
+
+        let mut invalid_args = vec![];
+        for meta in list {
+            if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
+                if let Some(ItemLike::Item(Item {
+                    kind: ItemKind::Fn(FnSig { decl, .. }, ..),
+                    ..
+                }))
+                | Some(ItemLike::ForeignItem(ForeignItem {
+                    kind: ForeignItemKind::Fn(decl, ..),
+                    ..
+                })) = item
+                {
+                    let arg_count = decl.inputs.len() as u128;
+                    if *val >= arg_count {
+                        let span = meta.span();
+                        self.tcx
+                            .sess
+                            .struct_span_err(span, "index exceeds number of arguments")
+                            .span_label(
+                                span,
+                                format!(
+                                    "there {} only {} argument{}",
+                                    if arg_count != 1 { "are" } else { "is" },
+                                    arg_count,
+                                    pluralize!(arg_count)
+                                ),
+                            )
+                            .emit();
+                        return false;
                     }
                 } else {
-                    invalid_args.push(meta.span());
+                    bug!("should be a function item");
                 }
-            }
-            if !invalid_args.is_empty() {
-                self.tcx
-                    .sess
-                    .struct_span_err(invalid_args, "arguments should be non-negative integers")
-                    .emit();
-                false
             } else {
-                true
+                invalid_args.push(meta.span());
             }
-        } else {
+        }
+
+        if !invalid_args.is_empty() {
             self.tcx
                 .sess
-                .struct_span_err(attr.span, "attribute should be applied to a function")
-                .span_label(*span, "not a function")
+                .struct_span_err(invalid_args, "arguments should be non-negative integers")
                 .emit();
             false
+        } else {
+            true
         }
     }
 
index 76c01c21301388eae15812726845e0bcc4d81fd7..99508baeb0070b56d002896f8def14877ae83640 100644 (file)
@@ -23,4 +23,10 @@ fn foo6(_: u8) {}
     fn foo7(_: u8);
 }
 
+#[rustc_args_required_const] //~ ERROR malformed `rustc_args_required_const` attribute
+fn bar1() {}
+
+#[rustc_args_required_const = 1] //~ ERROR malformed `rustc_args_required_const` attribute
+fn bar2() {}
+
 fn main() {}
index 39d0462616873bfe72bfc34516a1bf92dbdb40f5..932344f0a33c5877fa1bfd357714e180bcc146ff 100644 (file)
@@ -6,6 +6,18 @@ LL | #[rustc_args_required_const(0usize)]
    |
    = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
 
+error: malformed `rustc_args_required_const` attribute input
+  --> $DIR/invalid-rustc_args_required_const-arguments.rs:26:1
+   |
+LL | #[rustc_args_required_const]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_args_required_const(N)]`
+
+error: malformed `rustc_args_required_const` attribute input
+  --> $DIR/invalid-rustc_args_required_const-arguments.rs:29:1
+   |
+LL | #[rustc_args_required_const = 1]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_args_required_const(N)]`
+
 error: index exceeds number of arguments
   --> $DIR/invalid-rustc_args_required_const-arguments.rs:3:29
    |
@@ -44,5 +56,5 @@ error: index exceeds number of arguments
 LL |     #[rustc_args_required_const(1)]
    |                                 ^ there is only 1 argument
 
-error: aborting due to 7 previous errors
+error: aborting due to 9 previous errors