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>, ) -> 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() {} #[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments fn foo3(_: u8) {} #[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers -fn foo4() {} +fn foo4() {} #[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers -fn foo5(_: u8, _: u8, _: u8) {} +fn foo5() {} #[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() {} 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(); //~ 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() {} | - 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(); + | -------------------------- not a function -error: aborting due to 11 previous errors +error[E0044]: foreign items may not have const parameters + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5 + | +LL | fn foo7(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters + | + = help: replace the const parameters with concrete consts +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0044`.