diff options
| author | Amanieu d'Antras <amanieu@gmail.com> | 2021-02-25 09:04:43 +0000 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2021-02-25 09:04:43 +0000 |
| commit | 00afbe70f2f5cb0b6455036f4b97537ff77f2052 (patch) | |
| tree | 86d680d056e882c9515c5b781c470d5bfeb16621 /compiler/rustc_passes/src/check_attr.rs | |
| parent | 22184a0f5d0e83d07425d6058e7ad93c78160233 (diff) | |
| download | rust-00afbe70f2f5cb0b6455036f4b97537ff77f2052.tar.gz rust-00afbe70f2f5cb0b6455036f4b97537ff77f2052.zip | |
Improve checking for attribute
Diffstat (limited to 'compiler/rustc_passes/src/check_attr.rs')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 103 |
1 files changed, 56 insertions, 47 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()); |
