about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_passes/src/check_attr.rs103
-rw-r--r--src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs14
-rw-r--r--src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr31
3 files changed, 85 insertions, 63 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 022f1858878..cf08881cd47 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -760,7 +760,7 @@ impl CheckAttrVisitor<'tcx> {
         target: Target,
         item: Option<ItemLike<'_>>,
     ) -> bool {
-        let is_function = matches!(target, Target::Fn | Target::Method(..) | Target::ForeignFn);
+        let is_function = matches!(target, Target::Fn | Target::Method(..));
         if !is_function {
             self.tcx
                 .sess
@@ -776,55 +776,64 @@ impl CheckAttrVisitor<'tcx> {
             Some(it) => it,
         };
 
+        let (decl, generics) = match item {
+            Some(ItemLike::Item(Item {
+                kind: ItemKind::Fn(FnSig { decl, .. }, generics, _),
+                ..
+            })) => (decl, generics),
+            _ => bug!("should be a function item"),
+        };
+
+        for param in generics.params {
+            match param.kind {
+                hir::GenericParamKind::Const { .. } => {}
+                _ => {
+                    self.tcx
+                        .sess
+                        .struct_span_err(
+                            attr.span,
+                            "#[rustc_legacy_const_generics] functions must \
+                             only have const generics",
+                        )
+                        .span_label(param.span, "non-const generic parameter")
+                        .emit();
+                    return false;
+                }
+            }
+        }
+
+        if list.len() != generics.params.len() {
+            self.tcx
+                .sess
+                .struct_span_err(
+                    attr.span,
+                    "#[rustc_legacy_const_generics] must have one index for each generic parameter",
+                )
+                .span_label(generics.span, "generic parameters")
+                .emit();
+            return false;
+        }
+
+        let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
         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, .. }, generics, _),
-                    ..
-                }))
-                | Some(ItemLike::ForeignItem(ForeignItem {
-                    kind: ForeignItemKind::Fn(decl, _, generics),
-                    ..
-                })) = item
-                {
-                    let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
-                    for param in generics.params {
-                        match param.kind {
-                            hir::GenericParamKind::Const { .. } => {}
-                            _ => {
-                                self.tcx
-                                    .sess
-                                    .struct_span_err(
-                                        meta.span(),
-                                        "#[rustc_legacy_const_generics] functions must \
-                                         only have const generics",
-                                    )
-                                    .span_label(param.span, "non-const generic parameter")
-                                    .emit();
-                                break;
-                            }
-                        }
-                    }
-                    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");
+                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());
diff --git a/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs b/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs
index bf3f80807e6..3d8478f06db 100644
--- a/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs
+++ b/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs
@@ -1,29 +1,29 @@
 #![feature(rustc_attrs)]
 
-#[rustc_legacy_const_generics(0)] //~ ERROR index exceeds number of arguments
+#[rustc_legacy_const_generics(0)] //~ ERROR #[rustc_legacy_const_generics] must have one index for
 fn foo1() {}
 
 #[rustc_legacy_const_generics(1)] //~ ERROR index exceeds number of arguments
-fn foo2(_: u8) {}
+fn foo2<const X: usize>() {}
 
 #[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments
 fn foo3<const X: usize>(_: u8) {}
 
 #[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers
-fn foo4() {}
+fn foo4<const X: usize>() {}
 
 #[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers
-fn foo5(_: u8, _: u8, _: u8) {}
+fn foo5<const X: usize, const Y: usize, const Z: usize, const W: usize>() {}
 
 #[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function
 struct S;
 
 #[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes
-fn foo6(_: u8) {}
+fn foo6<const X: usize>() {}
 
 extern {
-    #[rustc_legacy_const_generics(1)] //~ ERROR index exceeds number of arguments
-    fn foo7(_: u8);
+    #[rustc_legacy_const_generics(1)] //~ ERROR attribute should be applied to a function
+    fn foo7<const X: usize>(); //~ ERROR foreign items may not have const parameters
 }
 
 #[rustc_legacy_const_generics(0)] //~ ERROR #[rustc_legacy_const_generics] functions must only have
diff --git a/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr b/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr
index 0d9960a663e..1f55a8e72d2 100644
--- a/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr
+++ b/src/test/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr
@@ -18,11 +18,13 @@ error: malformed `rustc_legacy_const_generics` attribute input
 LL | #[rustc_legacy_const_generics = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]`
 
-error: index exceeds number of arguments
-  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:31
+error: #[rustc_legacy_const_generics] must have one index for each generic parameter
+  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:1
    |
 LL | #[rustc_legacy_const_generics(0)]
-   |                               ^ there are only 0 arguments
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn foo1() {}
+   |        - generic parameters
 
 error: index exceeds number of arguments
   --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:6:31
@@ -57,18 +59,29 @@ LL | struct S;
    | --------- not a function
 
 error: #[rustc_legacy_const_generics] functions must only have const generics
-  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:31
+  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:1
    |
 LL | #[rustc_legacy_const_generics(0)]
-   |                               ^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL | fn foo8<X>() {}
    |         - non-const generic parameter
 
-error: index exceeds number of arguments
-  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:35
+error: attribute should be applied to a function
+  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:5
    |
 LL |     #[rustc_legacy_const_generics(1)]
-   |                                   ^ there is only 1 argument
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn foo7<const X: usize>();
+   |     -------------------------- not a function
+
+error[E0044]: foreign items may not have const parameters
+  --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5
+   |
+LL |     fn foo7<const X: usize>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
+   |
+   = help: replace the const parameters with concrete consts
 
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
 
+For more information about this error, try `rustc --explain E0044`.