about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2022-05-29 01:12:30 +0200
committerGitHub <noreply@github.com>2022-05-29 01:12:30 +0200
commit239287f013b21d18c8ddd5bf5419629d43dca484 (patch)
tree8370d6dac6dfdae06b82d23e097b46472e026673 /compiler/rustc_passes/src
parent376163a77cda823c4e1bdedd48039609069e6b58 (diff)
parent7ac62ce75cef963017245287f0a7b140e09589d7 (diff)
downloadrust-239287f013b21d18c8ddd5bf5419629d43dca484.tar.gz
rust-239287f013b21d18c8ddd5bf5419629d43dca484.zip
Rollup merge of #97028 - ridwanabdillahi:pretty-printer, r=michaelwoerister
Add support for embedding pretty printers via `#[debugger_visualizer]` attribute

Initial support for [RFC 3191](https://github.com/rust-lang/rfcs/pull/3191) in PR https://github.com/rust-lang/rust/pull/91779 was scoped to supporting embedding NatVis files using a new attribute. This PR implements the pretty printer support as stated in the RFC mentioned above.

This change includes embedding pretty printers in the `.debug_gdb_scripts` just as the pretty printers for rustc are embedded today. Also added additional tests for embedded pretty printers. Additionally cleaned up error checking so all error checking is done up front regardless of the current target.

RFC: https://github.com/rust-lang/rfcs/pull/3191
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/check_attr.rs56
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs61
2 files changed, 61 insertions, 56 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 3d5da114ecf..3d38ff00eab 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -8,6 +8,7 @@ use rustc_ast::tokenstream::DelimSpan;
 use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MacArgs, MetaItemKind, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
+use rustc_expand::base::resolve_path;
 use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir as hir;
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
@@ -1982,49 +1983,64 @@ impl CheckAttrVisitor<'_> {
             }
         }
 
-        let hints = match attr.meta_item_list() {
-            Some(meta_item_list) => meta_item_list,
-            None => {
-                self.emit_debugger_visualizer_err(attr);
-                return false;
-            }
+        let Some(hints) = attr.meta_item_list() else {
+            self.emit_debugger_visualizer_err(attr.span);
+            return false;
         };
 
         let hint = match hints.len() {
             1 => &hints[0],
             _ => {
-                self.emit_debugger_visualizer_err(attr);
+                self.emit_debugger_visualizer_err(attr.span);
                 return false;
             }
         };
 
-        if !hint.has_name(sym::natvis_file) {
-            self.emit_debugger_visualizer_err(attr);
+        let Some(meta_item) = hint.meta_item() else {
+            self.emit_debugger_visualizer_err(attr.span);
             return false;
-        }
+        };
 
-        let meta_item = match hint.meta_item() {
-            Some(meta_item) => meta_item,
-            None => {
-                self.emit_debugger_visualizer_err(attr);
+        let visualizer_path = match (meta_item.name_or_empty(), meta_item.value_str()) {
+            (sym::natvis_file, Some(value)) => value,
+            (sym::gdb_script_file, Some(value)) => value,
+            (_, _) => {
+                self.emit_debugger_visualizer_err(meta_item.span);
                 return false;
             }
         };
 
-        match (meta_item.name_or_empty(), meta_item.value_str()) {
-            (sym::natvis_file, Some(_)) => true,
-            (_, _) => {
-                self.emit_debugger_visualizer_err(attr);
+        let file =
+            match resolve_path(&self.tcx.sess.parse_sess, visualizer_path.as_str(), attr.span) {
+                Ok(file) => file,
+                Err(mut err) => {
+                    err.emit();
+                    return false;
+                }
+            };
+
+        match std::fs::File::open(&file) {
+            Ok(_) => true,
+            Err(err) => {
+                self.tcx
+                    .sess
+                    .struct_span_err(
+                        meta_item.span,
+                        &format!("couldn't read {}: {}", file.display(), err),
+                    )
+                    .emit();
                 false
             }
         }
     }
 
-    fn emit_debugger_visualizer_err(&self, attr: &Attribute) {
+    fn emit_debugger_visualizer_err(&self, span: Span) {
         self.tcx
             .sess
-            .struct_span_err(attr.span, "invalid argument")
+            .struct_span_err(span, "invalid argument")
             .note(r#"expected: `natvis_file = "..."`"#)
+            .note(r#"OR"#)
+            .note(r#"expected: `gdb_script_file = "..."`"#)
             .emit();
     }
 
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index 8305830bc98..e08683fe23b 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -21,9 +21,8 @@ fn check_for_debugger_visualizer<'tcx>(
     let attrs = tcx.hir().attrs(hir_id);
     for attr in attrs {
         if attr.has_name(sym::debugger_visualizer) {
-            let list = match attr.meta_item_list() {
-                Some(list) => list,
-                _ => continue,
+            let Some(list) = attr.meta_item_list() else {
+                continue
             };
 
             let meta_item = match list.len() {
@@ -34,45 +33,35 @@ fn check_for_debugger_visualizer<'tcx>(
                 _ => continue,
             };
 
-            let file = match (meta_item.name_or_empty(), meta_item.value_str()) {
-                (sym::natvis_file, Some(value)) => {
+            let visualizer_type = match meta_item.name_or_empty() {
+                sym::natvis_file => DebuggerVisualizerType::Natvis,
+                sym::gdb_script_file => DebuggerVisualizerType::GdbPrettyPrinter,
+                _ => continue,
+            };
+
+            let file = match meta_item.value_str() {
+                Some(value) => {
                     match resolve_path(&tcx.sess.parse_sess, value.as_str(), attr.span) {
                         Ok(file) => file,
-                        Err(mut err) => {
-                            err.emit();
-                            continue;
-                        }
+                        _ => continue,
                     }
                 }
-                (_, _) => continue,
+                None => continue,
             };
 
-            if file.is_file() {
-                let contents = match std::fs::read(&file) {
-                    Ok(contents) => contents,
-                    Err(err) => {
-                        tcx.sess
-                            .struct_span_err(
-                                attr.span,
-                                &format!(
-                                    "Unable to read contents of file `{}`. {}",
-                                    file.display(),
-                                    err
-                                ),
-                            )
-                            .emit();
-                        continue;
-                    }
-                };
-
-                debugger_visualizers.insert(DebuggerVisualizerFile::new(
-                    Arc::from(contents),
-                    DebuggerVisualizerType::Natvis,
-                ));
-            } else {
-                tcx.sess
-                    .struct_span_err(attr.span, &format!("{} is not a valid file", file.display()))
-                    .emit();
+            match std::fs::read(&file) {
+                Ok(contents) => {
+                    debugger_visualizers
+                        .insert(DebuggerVisualizerFile::new(Arc::from(contents), visualizer_type));
+                }
+                Err(err) => {
+                    tcx.sess
+                        .struct_span_err(
+                            meta_item.span,
+                            &format!("couldn't read {}: {}", file.display(), err),
+                        )
+                        .emit();
+                }
             }
         }
     }