Rollup merge of #138063 - compiler-errors:improve-attr-unpretty, r=jdonszelmann
Improve `-Zunpretty=hir` for parsed attrs 0. Rename `print_something` to `should_render` to make it distinct from `print_attribute` in that it doesn't print anything, it's just a way to probe if a type renders anything. 1. Fixes a few bugs in the `PrintAttribute` derive. Namely, the `__printed_anything` variable was entangled with the `should_render` call, leading us to always render field names but never render commas. 2. Remove the outermost `""` from the attr. 3. Debug print `Symbol`s. I know that this is redundant for some parsed attributes, but there's no good way to distinguish symbols that are ident-like and symbols which are cooked string literals. We could perhaps *conditionally* to fall back to a debug printing if the symbol doesn't match an ident? But seems like overkill. Based on #138060, only review the commits not in that one.
This commit is contained in:
commit
c054bac89a
8 changed files with 60 additions and 52 deletions
|
@ -35,13 +35,17 @@ pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStabl
|
|||
/// 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;
|
||||
/// Whether or not this will render as something meaningful, or if it's skipped
|
||||
/// (which will force the containing struct to also skip printing a comma
|
||||
/// and the field name).
|
||||
fn should_render(&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 should_render(&self) -> bool {
|
||||
T::should_render(self)
|
||||
}
|
||||
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
|
@ -49,9 +53,10 @@ impl<T: PrintAttribute> PrintAttribute for &T {
|
|||
}
|
||||
}
|
||||
impl<T: PrintAttribute> PrintAttribute for Option<T> {
|
||||
fn print_something(&self) -> bool {
|
||||
self.as_ref().is_some_and(|x| x.print_something())
|
||||
fn should_render(&self) -> bool {
|
||||
self.as_ref().is_some_and(|x| x.should_render())
|
||||
}
|
||||
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
if let Some(i) = self {
|
||||
T::print_attribute(i, p)
|
||||
|
@ -59,9 +64,10 @@ impl<T: PrintAttribute> PrintAttribute for Option<T> {
|
|||
}
|
||||
}
|
||||
impl<T: PrintAttribute> PrintAttribute for ThinVec<T> {
|
||||
fn print_something(&self) -> bool {
|
||||
self.is_empty() || self[0].print_something()
|
||||
fn should_render(&self) -> bool {
|
||||
self.is_empty() || self[0].should_render()
|
||||
}
|
||||
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
let mut last_printed = false;
|
||||
p.word("[");
|
||||
|
@ -70,7 +76,7 @@ impl<T: PrintAttribute> PrintAttribute for ThinVec<T> {
|
|||
p.word_space(",");
|
||||
}
|
||||
i.print_attribute(p);
|
||||
last_printed = i.print_something();
|
||||
last_printed = i.should_render();
|
||||
}
|
||||
p.word("]");
|
||||
}
|
||||
|
@ -78,7 +84,7 @@ impl<T: PrintAttribute> PrintAttribute for ThinVec<T> {
|
|||
macro_rules! print_skip {
|
||||
($($t: ty),* $(,)?) => {$(
|
||||
impl PrintAttribute for $t {
|
||||
fn print_something(&self) -> bool { false }
|
||||
fn should_render(&self) -> bool { false }
|
||||
fn print_attribute(&self, _: &mut Printer) { }
|
||||
})*
|
||||
};
|
||||
|
@ -87,7 +93,7 @@ macro_rules! print_skip {
|
|||
macro_rules! print_disp {
|
||||
($($t: ty),* $(,)?) => {$(
|
||||
impl PrintAttribute for $t {
|
||||
fn print_something(&self) -> bool { true }
|
||||
fn should_render(&self) -> bool { true }
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
p.word(format!("{}", self));
|
||||
}
|
||||
|
@ -97,7 +103,7 @@ macro_rules! print_disp {
|
|||
macro_rules! print_debug {
|
||||
($($t: ty),* $(,)?) => {$(
|
||||
impl PrintAttribute for $t {
|
||||
fn print_something(&self) -> bool { true }
|
||||
fn should_render(&self) -> bool { true }
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
p.word(format!("{:?}", self));
|
||||
}
|
||||
|
@ -106,37 +112,39 @@ macro_rules! print_debug {
|
|||
}
|
||||
|
||||
macro_rules! print_tup {
|
||||
(num_print_something $($ts: ident)*) => { 0 $(+ $ts.print_something() as usize)* };
|
||||
(num_should_render $($ts: ident)*) => { 0 $(+ $ts.should_render() 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 {
|
||||
fn should_render(&self) -> bool {
|
||||
let ($t, $($ts),*) = self;
|
||||
print_tup!(num_print_something $t $($ts)*) != 0
|
||||
print_tup!(num_should_render $t $($ts)*) != 0
|
||||
}
|
||||
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
let ($t, $($ts),*) = self;
|
||||
let parens = print_tup!(num_print_something $t $($ts)*) > 1;
|
||||
let parens = print_tup!(num_should_render $t $($ts)*) > 1;
|
||||
if parens {
|
||||
p.word("(");
|
||||
p.popen();
|
||||
}
|
||||
|
||||
let mut printed_anything = $t.print_something();
|
||||
let mut printed_anything = $t.should_render();
|
||||
|
||||
$t.print_attribute(p);
|
||||
|
||||
$(
|
||||
if printed_anything && $ts.print_something() {
|
||||
if $ts.should_render() {
|
||||
if printed_anything {
|
||||
p.word_space(",");
|
||||
}
|
||||
printed_anything = true;
|
||||
}
|
||||
$ts.print_attribute(p);
|
||||
)*
|
||||
|
||||
if parens {
|
||||
p.word(")");
|
||||
p.pclose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,8 +155,8 @@ macro_rules! print_tup {
|
|||
|
||||
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);
|
||||
print_disp!(u16, bool, NonZero<u32>);
|
||||
print_debug!(Symbol, UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
|
||||
|
||||
/// Finds attributes in sequences of attributes by pattern matching.
|
||||
///
|
||||
|
|
|
@ -118,9 +118,9 @@ impl<'a> State<'a> {
|
|||
self.hardbreak()
|
||||
}
|
||||
hir::Attribute::Parsed(pa) => {
|
||||
self.word("#[attr=\"");
|
||||
self.word("#[attr = ");
|
||||
pa.print_attribute(self);
|
||||
self.word("\")]");
|
||||
self.word("]");
|
||||
self.hardbreak()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok
|
|||
let name = field.ident.as_ref().unwrap();
|
||||
let string_name = name.to_string();
|
||||
disps.push(quote! {
|
||||
if __printed_anything && #name.print_something() {
|
||||
if #name.should_render() {
|
||||
if __printed_anything {
|
||||
__p.word_space(",");
|
||||
__printed_anything = true;
|
||||
}
|
||||
__p.word(#string_name);
|
||||
__p.word_space(":");
|
||||
__printed_anything = true;
|
||||
}
|
||||
#name.print_attribute(__p);
|
||||
});
|
||||
field_names.push(name);
|
||||
|
@ -31,10 +33,11 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok
|
|||
quote! { {#(#field_names),*} },
|
||||
quote! {
|
||||
__p.word(#string_name);
|
||||
if true #(&& !#field_names.print_something())* {
|
||||
if true #(&& !#field_names.should_render())* {
|
||||
return;
|
||||
}
|
||||
|
||||
__p.nbsp();
|
||||
__p.word("{");
|
||||
#(#disps)*
|
||||
__p.word("}");
|
||||
|
@ -48,8 +51,10 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok
|
|||
for idx in 0..fields_unnamed.unnamed.len() {
|
||||
let name = format_ident!("f{idx}");
|
||||
disps.push(quote! {
|
||||
if __printed_anything && #name.print_something() {
|
||||
if #name.should_render() {
|
||||
if __printed_anything {
|
||||
__p.word_space(",");
|
||||
}
|
||||
__printed_anything = true;
|
||||
}
|
||||
#name.print_attribute(__p);
|
||||
|
@ -62,13 +67,13 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok
|
|||
quote! {
|
||||
__p.word(#string_name);
|
||||
|
||||
if true #(&& !#field_names.print_something())* {
|
||||
if true #(&& !#field_names.should_render())* {
|
||||
return;
|
||||
}
|
||||
|
||||
__p.word("(");
|
||||
__p.popen();
|
||||
#(#disps)*
|
||||
__p.word(")");
|
||||
__p.pclose();
|
||||
},
|
||||
quote! { true },
|
||||
)
|
||||
|
@ -138,7 +143,7 @@ pub(crate) fn print_attribute(input: Structure<'_>) -> TokenStream {
|
|||
input.gen_impl(quote! {
|
||||
#[allow(unused)]
|
||||
gen impl PrintAttribute for @Self {
|
||||
fn print_something(&self) -> bool { #printed }
|
||||
fn should_render(&self) -> bool { #printed }
|
||||
fn print_attribute(&self, __p: &mut rustc_ast_pretty::pp::Printer) { #code }
|
||||
}
|
||||
})
|
||||
|
|
|
@ -6,6 +6,6 @@ extern crate std;
|
|||
//@ pretty-mode:hir
|
||||
//@ pp-exact:hir-pretty-attr.pp
|
||||
|
||||
#[attr="Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])")]
|
||||
#[attr = Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])]
|
||||
struct Example {
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[repr(i32)]
|
||||
//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(SignedInt(I32))])\")]\n"]'
|
||||
//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
|
||||
pub enum Foo {
|
||||
//@ is "$.index[*][?(@.name=='Struct')].inner.variant.discriminant" null
|
||||
//@ count "$.index[*][?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[repr(u32)]
|
||||
//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(UnsignedInt(U32))])\")]\n"]'
|
||||
//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(U32))])]\n"]'
|
||||
pub enum Foo {
|
||||
//@ is "$.index[*][?(@.name=='Tuple')].inner.variant.discriminant" null
|
||||
//@ count "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ compile-flags: -Zunpretty=hir
|
||||
//@ check-pass
|
||||
|
||||
// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is
|
||||
// slightly broken.
|
||||
#[deprecated]
|
||||
pub struct PlainDeprecated;
|
||||
|
||||
|
|
|
@ -5,24 +5,21 @@ extern crate std;
|
|||
//@ compile-flags: -Zunpretty=hir
|
||||
//@ check-pass
|
||||
|
||||
// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is
|
||||
// slightly broken.
|
||||
#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote:
|
||||
suggestion: }span: }")]
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
|
||||
struct PlainDeprecated;
|
||||
|
||||
#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote:
|
||||
here's why this is deprecatedsuggestion: }span: }")]
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note:
|
||||
"here's why this is deprecated"}}]
|
||||
struct DirectNote;
|
||||
|
||||
#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote:
|
||||
here's why this is deprecatedsuggestion: }span: }")]
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note:
|
||||
"here's why this is deprecated"}}]
|
||||
struct ExplicitNote;
|
||||
|
||||
#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note:
|
||||
here's why this is deprecatedsuggestion: }span: }")]
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"),
|
||||
note: "here's why this is deprecated"}}]
|
||||
struct SinceAndNote;
|
||||
|
||||
#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note:
|
||||
here's why this is deprecatedsuggestion: }span: }")]
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"),
|
||||
note: "here's why this is deprecated"}}]
|
||||
struct FlippedOrder;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue