pretty print hir attributes

This commit is contained in:
Jana Dönszelmann 2025-02-09 22:50:03 +01:00
parent 309b46ad68
commit 95b52d51ea
No known key found for this signature in database
11 changed files with 335 additions and 21 deletions

View file

@ -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>),

View file

@ -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);

View file

@ -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,

View file

@ -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,