about summary refs log tree commit diff
path: root/compiler/rustc_attr_data_structures
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_attr_data_structures')
-rw-r--r--compiler/rustc_attr_data_structures/Cargo.toml1
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs16
-rw-r--r--compiler/rustc_attr_data_structures/src/lib.rs131
-rw-r--r--compiler/rustc_attr_data_structures/src/stability.rs18
-rw-r--r--compiler/rustc_attr_data_structures/src/version.rs8
5 files changed, 155 insertions, 19 deletions
diff --git a/compiler/rustc_attr_data_structures/Cargo.toml b/compiler/rustc_attr_data_structures/Cargo.toml
index ff2212b8df2..b18923c337f 100644
--- a/compiler/rustc_attr_data_structures/Cargo.toml
+++ b/compiler/rustc_attr_data_structures/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2024"
 # tidy-alphabetical-start
 rustc_abi = {path = "../rustc_abi"}
 rustc_ast = {path = "../rustc_ast"}
+rustc_ast_pretty = {path = "../rustc_ast_pretty"}
 rustc_data_structures = {path = "../rustc_data_structures"}
 rustc_macros = {path = "../rustc_macros"}
 rustc_serialize = {path = "../rustc_serialize"}
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index 3f1edacf9a7..9ac8de0227d 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -1,12 +1,12 @@
 use rustc_abi::Align;
 use rustc_ast::token::CommentKind;
 use rustc_ast::{self as ast, AttrStyle};
-use rustc_macros::{Decodable, Encodable, HashStable_Generic};
+use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
 use rustc_span::hygiene::Transparency;
 use rustc_span::{Span, Symbol};
 use thin_vec::ThinVec;
 
-use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability};
+use crate::{DefaultBodyStability, PartialConstStability, PrintAttribute, RustcVersion, Stability};
 
 #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum InlineAttr {
@@ -57,7 +57,7 @@ impl OptimizeAttr {
     }
 }
 
-#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
+#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic, PrintAttribute)]
 pub enum DiagnosticAttribute {
     // tidy-alphabetical-start
     DoNotRecommend,
@@ -65,7 +65,7 @@ pub enum DiagnosticAttribute {
     // tidy-alphabetical-end
 }
 
-#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic)]
+#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)]
 pub enum ReprAttr {
     ReprInt(IntType),
     ReprRust,
@@ -85,13 +85,13 @@ pub enum TransparencyError {
 }
 
 #[derive(Eq, PartialEq, Debug, Copy, Clone)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic, PrintAttribute)]
 pub enum IntType {
     SignedInt(ast::IntTy),
     UnsignedInt(ast::UintTy),
 }
 
-#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
+#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
 pub struct Deprecation {
     pub since: DeprecatedSince,
     /// The note to issue a reason.
@@ -103,7 +103,7 @@ pub struct Deprecation {
 }
 
 /// Release in which an API is deprecated.
-#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
+#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
 pub enum DeprecatedSince {
     RustcVersion(RustcVersion),
     /// Deprecated in the future ("to be determined").
@@ -154,7 +154,7 @@ impl Deprecation {
 /// happen.
 ///
 /// For more docs, look in [`rustc_attr`](https://doc.rust-lang.org/stable/nightly-rustc/rustc_attr/index.html)
-#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
+#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
 pub enum AttributeKind {
     // tidy-alphabetical-start
     AllowConstFnUnstable(ThinVec<Symbol>),
diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs
index 93d4aa7ddf3..e4bb459e6df 100644
--- a/compiler/rustc_attr_data_structures/src/lib.rs
+++ b/compiler/rustc_attr_data_structures/src/lib.rs
@@ -10,11 +10,142 @@ mod attributes;
 mod stability;
 mod version;
 
+use std::num::NonZero;
+
 pub use attributes::*;
+use rustc_abi::Align;
+use rustc_ast::token::CommentKind;
+use rustc_ast::{AttrStyle, IntTy, UintTy};
+use rustc_ast_pretty::pp::Printer;
+use rustc_span::hygiene::Transparency;
+use rustc_span::{Span, Symbol};
 pub use stability::*;
+use thin_vec::ThinVec;
 pub use version::*;
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
 /// instead of implementing everything in `rustc_middle`.
 pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext {}
+
+/// This trait is used to print attributes in `rustc_hir_pretty`.
+///
+/// For structs and enums it can be derived using [`rustc_macros::PrintAttribute`].
+/// The output will look a lot like a `Debug` implementation, but fields of several types
+/// like [`Span`]s and empty tuples, are gracefully skipped so they don't clutter the
+/// representation much.
+pub trait PrintAttribute {
+    fn print_something(&self) -> bool;
+    fn print_attribute(&self, p: &mut Printer);
+}
+
+impl<T: PrintAttribute> PrintAttribute for &T {
+    fn print_something(&self) -> bool {
+        T::print_something(self)
+    }
+
+    fn print_attribute(&self, p: &mut Printer) {
+        T::print_attribute(self, p)
+    }
+}
+impl<T: PrintAttribute> PrintAttribute for Option<T> {
+    fn print_something(&self) -> bool {
+        self.as_ref().is_some_and(|x| x.print_something())
+    }
+    fn print_attribute(&self, p: &mut Printer) {
+        if let Some(i) = self {
+            T::print_attribute(i, p)
+        }
+    }
+}
+impl<T: PrintAttribute> PrintAttribute for ThinVec<T> {
+    fn print_something(&self) -> bool {
+        self.is_empty() || self[0].print_something()
+    }
+    fn print_attribute(&self, p: &mut Printer) {
+        let mut last_printed = false;
+        p.word("[");
+        for i in self {
+            if last_printed {
+                p.word_space(",");
+            }
+            i.print_attribute(p);
+            last_printed = i.print_something();
+        }
+        p.word("]");
+    }
+}
+macro_rules! print_skip {
+    ($($t: ty),* $(,)?) => {$(
+        impl PrintAttribute for $t {
+            fn print_something(&self) -> bool { false }
+            fn print_attribute(&self, _: &mut Printer) { }
+        })*
+    };
+}
+
+macro_rules! print_disp {
+    ($($t: ty),* $(,)?) => {$(
+        impl PrintAttribute for $t {
+            fn print_something(&self) -> bool { true }
+            fn print_attribute(&self, p: &mut Printer) {
+                p.word(format!("{}", self));
+            }
+        }
+    )*};
+}
+macro_rules! print_debug {
+    ($($t: ty),* $(,)?) => {$(
+        impl PrintAttribute for $t {
+            fn print_something(&self) -> bool { true }
+            fn print_attribute(&self, p: &mut Printer) {
+                p.word(format!("{:?}", self));
+            }
+        }
+    )*};
+}
+
+macro_rules! print_tup {
+    (num_print_something $($ts: ident)*) => { 0 $(+ $ts.print_something() as usize)* };
+    () => {};
+    ($t: ident $($ts: ident)*) => {
+        #[allow(non_snake_case, unused)]
+        impl<$t: PrintAttribute, $($ts: PrintAttribute),*> PrintAttribute for ($t, $($ts),*) {
+            fn print_something(&self) -> bool {
+                let ($t, $($ts),*) = self;
+                print_tup!(num_print_something $t $($ts)*) != 0
+            }
+
+            fn print_attribute(&self, p: &mut Printer) {
+                let ($t, $($ts),*) = self;
+                let parens = print_tup!(num_print_something $t $($ts)*) > 1;
+                if parens {
+                    p.word("(");
+                }
+
+                let mut printed_anything = $t.print_something();
+
+                $t.print_attribute(p);
+
+                $(
+                    if printed_anything && $ts.print_something() {
+                        p.word_space(",");
+                        printed_anything = true;
+                    }
+                    $ts.print_attribute(p);
+                )*
+
+                if parens {
+                    p.word(")");
+                }
+            }
+        }
+
+        print_tup!($($ts)*);
+    };
+}
+
+print_tup!(A B C D E F G H);
+print_skip!(Span, ());
+print_disp!(Symbol, u16, bool, NonZero<u32>);
+print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
diff --git a/compiler/rustc_attr_data_structures/src/stability.rs b/compiler/rustc_attr_data_structures/src/stability.rs
index c2213fc9ed8..c0ca08a60f8 100644
--- a/compiler/rustc_attr_data_structures/src/stability.rs
+++ b/compiler/rustc_attr_data_structures/src/stability.rs
@@ -1,9 +1,9 @@
 use std::num::NonZero;
 
-use rustc_macros::{Decodable, Encodable, HashStable_Generic};
+use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
 use rustc_span::{Symbol, sym};
 
-use crate::RustcVersion;
+use crate::{PrintAttribute, RustcVersion};
 
 /// The version placeholder that recently stabilized features contain inside the
 /// `since` field of the `#[stable]` attribute.
@@ -21,7 +21,7 @@ pub const VERSION_PLACEHOLDER: &str = concat!("CURRENT_RUSTC_VERSIO", "N");
 /// - `#[stable]`
 /// - `#[unstable]`
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub struct Stability {
     pub level: StabilityLevel,
     pub feature: Symbol,
@@ -43,7 +43,7 @@ impl Stability {
 
 /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub struct ConstStability {
     pub level: StabilityLevel,
     pub feature: Symbol,
@@ -83,7 +83,7 @@ impl ConstStability {
 /// Excludes `const_stable_indirect`. This is necessary because when `-Zforce-unstable-if-unmarked`
 /// is set, we need to encode standalone `#[rustc_const_stable_indirect]` attributes
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub struct PartialConstStability {
     pub level: StabilityLevel,
     pub feature: Symbol,
@@ -103,7 +103,7 @@ impl PartialConstStability {
 
 /// The available stability levels.
 #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub enum StabilityLevel {
     /// `#[unstable]`
     Unstable {
@@ -145,7 +145,7 @@ pub enum StabilityLevel {
 
 /// Rust release in which a feature is stabilized.
 #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub enum StableSince {
     /// also stores the original symbol for printing
     Version(RustcVersion),
@@ -171,7 +171,7 @@ impl StabilityLevel {
 }
 
 #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub enum UnstableReason {
     None,
     Default,
@@ -180,7 +180,7 @@ pub enum UnstableReason {
 
 /// Represents the `#[rustc_default_body_unstable]` attribute.
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub struct DefaultBodyStability {
     pub level: StabilityLevel,
     pub feature: Symbol,
diff --git a/compiler/rustc_attr_data_structures/src/version.rs b/compiler/rustc_attr_data_structures/src/version.rs
index 6be875ad4be..69b0e041d81 100644
--- a/compiler/rustc_attr_data_structures/src/version.rs
+++ b/compiler/rustc_attr_data_structures/src/version.rs
@@ -1,9 +1,13 @@
 use std::fmt::{self, Display};
 
-use rustc_macros::{Decodable, Encodable, HashStable_Generic, current_rustc_version};
+use rustc_macros::{
+    Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
+};
+
+use crate::PrintAttribute;
 
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, PrintAttribute)]
 pub struct RustcVersion {
     pub major: u16,
     pub minor: u16,