about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs41
1 files changed, 40 insertions, 1 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 34d9b048348..3e542771d58 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -1,4 +1,4 @@
-use rustc_attr_data_structures::{AttributeKind, OptimizeAttr, UsedBy};
+use rustc_attr_data_structures::{AttributeKind, CoverageStatus, OptimizeAttr, UsedBy};
 use rustc_feature::{AttributeTemplate, template};
 use rustc_session::parse::feature_err;
 use rustc_span::{Span, Symbol, sym};
@@ -52,6 +52,45 @@ impl<S: Stage> NoArgsAttributeParser<S> for ColdParser {
     const CREATE: fn(Span) -> AttributeKind = AttributeKind::Cold;
 }
 
+pub(crate) struct CoverageParser;
+
+impl<S: Stage> SingleAttributeParser<S> for CoverageParser {
+    const PATH: &[Symbol] = &[sym::coverage];
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
+    const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::off, sym::on]);
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        let Some(args) = args.list() else {
+            cx.expected_specific_argument_and_list(cx.attr_span, vec!["on", "off"]);
+            return None;
+        };
+
+        let Some(arg) = args.single() else {
+            cx.expected_single_argument(args.span);
+            return None;
+        };
+
+        let fail_incorrect_argument = |span| cx.expected_specific_argument(span, vec!["on", "off"]);
+
+        let Some(arg) = arg.meta_item() else {
+            fail_incorrect_argument(args.span);
+            return None;
+        };
+
+        let status = match arg.path().word_sym() {
+            Some(sym::off) => CoverageStatus::Off,
+            Some(sym::on) => CoverageStatus::On,
+            None | Some(_) => {
+                fail_incorrect_argument(arg.span());
+                return None;
+            }
+        };
+
+        Some(AttributeKind::Coverage(cx.attr_span, status))
+    }
+}
+
 pub(crate) struct ExportNameParser;
 
 impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {