rustc_attr_parsing/attributes/
debugger.rs1use 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 = 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<'c>(
20 cx: &'c mut AcceptContext<'_, '_, S>,
21 args: &'c ArgParser<'_>,
22 ) -> impl IntoIterator<Item = Self::Item> + 'c {
23 let Some(l) = args.list() else {
24 cx.expected_list(args.span().unwrap_or(cx.attr_span));
25 return None;
26 };
27 let Some(single) = l.single() else {
28 cx.expected_single_argument(l.span);
29 return None;
30 };
31 let Some(mi) = single.meta_item() else {
32 cx.expected_name_value(single.span(), None);
33 return None;
34 };
35 let path = mi.path().word_sym();
36 let visualizer_type = match path {
37 Some(sym::natvis_file) => DebuggerVisualizerType::Natvis,
38 Some(sym::gdb_script_file) => DebuggerVisualizerType::GdbPrettyPrinter,
39 _ => {
40 cx.expected_specific_argument(
41 mi.path().span(),
42 &[sym::natvis_file, sym::gdb_script_file],
43 );
44 return None;
45 }
46 };
47
48 let Some(path) = mi.args().name_value() else {
49 cx.expected_name_value(single.span(), path);
50 return None;
51 };
52
53 let Some(path) = path.value_as_str() else {
54 cx.expected_string_literal(path.value_span, Some(path.value_as_lit()));
55 return None;
56 };
57
58 Some(DebugVisualizer { span: mi.span(), visualizer_type, path })
59 }
60}