Skip to main content

rustc_attr_parsing/attributes/
debugger.rs

1use rustc_hir::attrs::{DebugVisualizer, DebuggerVisualizerType};
2
3use super::prelude::*;
4
5pub(crate) struct DebuggerViualizerParser;
6
7impl<S: Stage> CombineAttributeParser<S> for DebuggerViualizerParser {
8    const PATH: &[Symbol] = &[sym::debugger_visualizer];
9    const ALLOWED_TARGETS: AllowedTargets =
10        AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]);
11    const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
    word: false,
    list: Some(&[r#"natvis_file = "...", gdb_script_file = "...""#]),
    one_of: &[],
    name_value_str: None,
    docs: Some("https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute"),
}template!(
12        List: &[r#"natvis_file = "...", gdb_script_file = "...""#],
13        "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute"
14    );
15
16    type Item = DebugVisualizer;
17    const CONVERT: ConvertFn<Self::Item> = |v, _| AttributeKind::DebuggerVisualizer(v);
18
19    fn extend(
20        cx: &mut AcceptContext<'_, '_, S>,
21        args: &ArgParser,
22    ) -> impl IntoIterator<Item = Self::Item> {
23        let single = cx.single_element_list(args, cx.attr_span)?;
24        let Some(mi) = single.meta_item() else {
25            cx.adcx().expected_name_value(single.span(), None);
26            return None;
27        };
28        let path = mi.path().word_sym();
29        let visualizer_type = match path {
30            Some(sym::natvis_file) => DebuggerVisualizerType::Natvis,
31            Some(sym::gdb_script_file) => DebuggerVisualizerType::GdbPrettyPrinter,
32            _ => {
33                cx.adcx().expected_specific_argument(
34                    mi.path().span(),
35                    &[sym::natvis_file, sym::gdb_script_file],
36                );
37                return None;
38            }
39        };
40
41        let Some(path) = mi.args().name_value() else {
42            cx.adcx().expected_name_value(single.span(), path);
43            return None;
44        };
45
46        let Some(path) = path.value_as_str() else {
47            cx.adcx().expected_string_literal(path.value_span, Some(path.value_as_lit()));
48            return None;
49        };
50
51        Some(DebugVisualizer { span: mi.span(), visualizer_type, path })
52    }
53}