Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pretty-print #[deprecated] attribute in HIR. #138019

Merged
merged 1 commit into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,80 @@ impl<'a> State<'a> {
));
self.hardbreak()
}
hir::Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => {
self.word("#[deprecated");

// There are three possible forms here:
// 1. a form with explicit components like
// `#[deprecated(since = "1.2.3", note = "some note", suggestion = "something")]`
// where each component may be present or absent.
// 2. `#[deprecated = "message"]`
// 3. `#[deprecated]`
//
// Let's figure out which we need.
// If there's a `since` or `suggestion` value, we're definitely in form 1.
if matches!(
deprecation.since,
rustc_attr_parsing::DeprecatedSince::RustcVersion(..)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated but it may be nice to import these directly, or at least via a shorter name like use rustc_attr_parsing as attr;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no opinion one way or the other, happy to make the change. My personal preference is also to import things, but I know some codebases are conservative with what gets imported so I was playing it safe :)

| rustc_attr_parsing::DeprecatedSince::Future
| rustc_attr_parsing::DeprecatedSince::NonStandard(..)
) || deprecation.suggestion.is_some()
{
self.word("(");
let mut use_comma = false;

match &deprecation.since {
rustc_attr_parsing::DeprecatedSince::RustcVersion(rustc_version) => {
self.word("since = \"");
self.word(format!(
"{}.{}.{}",
rustc_version.major, rustc_version.minor, rustc_version.patch
));
self.word("\"");
use_comma = true;
}
rustc_attr_parsing::DeprecatedSince::Future => {
self.word("since = \"future\"");
use_comma = true;
}
rustc_attr_parsing::DeprecatedSince::NonStandard(symbol) => {
self.word("since = \"");
self.word(symbol.to_ident_string());
self.word("\"");
use_comma = true;
}
_ => {}
}

if let Some(note) = &deprecation.note {
if use_comma {
self.word(", ");
}
self.word("note = \"");
self.word(note.to_ident_string());
self.word("\"");
use_comma = true;
}

if let Some(suggestion) = &deprecation.suggestion {
if use_comma {
self.word(", ");
}
self.word("suggestion = \"");
self.word(suggestion.to_ident_string());
self.word("\"");
}
} else if let Some(note) = &deprecation.note {
// We're in form 2: `#[deprecated = "message"]`.
self.word(" = \"");
self.word(note.to_ident_string());
self.word("\"");
} else {
// We're in form 3: `#[deprecated]`. Nothing to do here.
}

self.word("]");
}
hir::Attribute::Parsed(pa) => {
self.word("#[attr=\"");
pa.print_attribute(self);
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/unpretty/deprecated-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: -Zunpretty=hir
//@ check-pass

#[deprecated]
pub struct PlainDeprecated;

#[deprecated = "here's why this is deprecated"]
pub struct DirectNote;

#[deprecated(note = "here's why this is deprecated")]
pub struct ExplicitNote;

#[deprecated(since = "1.2.3", note = "here's why this is deprecated")]
pub struct SinceAndNote;

#[deprecated(note = "here's why this is deprecated", since = "1.2.3")]
pub struct FlippedOrder;
21 changes: 21 additions & 0 deletions tests/ui/unpretty/deprecated-attr.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
extern crate std;
//@ compile-flags: -Zunpretty=hir
//@ check-pass

#[deprecated]
struct PlainDeprecated;

#[deprecated = "here's why this is deprecated"]
struct DirectNote;

#[deprecated = "here's why this is deprecated"]
struct ExplicitNote;

#[deprecated(since = "1.2.3", note = "here's why this is deprecated"]
struct SinceAndNote;

#[deprecated(since = "1.2.3", note = "here's why this is deprecated"]
struct FlippedOrder;
13 changes: 13 additions & 0 deletions tests/ui/unpretty/diagnostic-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//@ compile-flags: -Zunpretty=hir
//@ check-pass

#[diagnostic::on_unimplemented(
message = "My Message for `ImportantTrait<{A}>` implemented for `{Self}`",
label = "My Label",
note = "Note 1",
note = "Note 2"
)]
pub trait ImportantTrait<A> {}

#[diagnostic::do_not_recommend]
impl<T> ImportantTrait<T> for T where T: Clone {}
16 changes: 16 additions & 0 deletions tests/ui/unpretty/diagnostic-attr.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
extern crate std;
//@ compile-flags: -Zunpretty=hir
//@ check-pass

#[diagnostic::on_unimplemented(message =
"My Message for `ImportantTrait<{A}>` implemented for `{Self}`", label =
"My Label", note = "Note 1", note = "Note 2")]
trait ImportantTrait<A> { }

#[diagnostic::do_not_recommend]
impl <T> ImportantTrait<T> for T where T: Clone
{#![diagnostic::do_not_recommend]
}
Loading