diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2020-12-06 00:00:00 +0000 |
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2020-12-06 00:00:00 +0000 |
| commit | 50c6fd6dd52b97334d8b3628cf2f66985b25acc4 (patch) | |
| tree | 714747eec6c5a35511aff018c7ced8dfd353774d /compiler | |
| parent | a68864b68859e5848865bd392ce6d892b16f5cdd (diff) | |
| download | rust-50c6fd6dd52b97334d8b3628cf2f66985b25acc4.tar.gz rust-50c6fd6dd52b97334d8b3628cf2f66985b25acc4.zip | |
Don't ICE on malformed `rustc_args_required_const` attribute
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 98 |
1 files changed, 53 insertions, 45 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index fc97ca035b9..73fb28e5c9a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -545,60 +545,68 @@ impl CheckAttrVisitor<'tcx> { 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 } } |
