Skip to content

Commit 113b7f7

Browse files
committed
allow shorthand syntax for deprecation reason
1 parent d30b99f commit 113b7f7

File tree

8 files changed

+117
-67
lines changed

8 files changed

+117
-67
lines changed

src/libsyntax/attr/builtin.rs

+65-60
Original file line numberDiff line numberDiff line change
@@ -592,81 +592,86 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
592592
let diagnostic = &sess.span_diagnostic;
593593

594594
'outer: for attr in attrs_iter {
595-
if attr.path != "deprecated" {
596-
continue
595+
if !attr.check_name("deprecated") {
596+
continue;
597597
}
598598

599-
mark_used(attr);
600-
601599
if depr.is_some() {
602600
span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes");
603601
break
604602
}
605603

606-
depr = if let Some(metas) = attr.meta_item_list() {
607-
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
608-
if item.is_some() {
609-
handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name()));
610-
return false
611-
}
612-
if let Some(v) = meta.value_str() {
613-
*item = Some(v);
614-
true
615-
} else {
616-
if let Some(lit) = meta.name_value_literal() {
617-
handle_errors(
618-
sess,
619-
lit.span,
620-
AttrError::UnsupportedLiteral(
621-
"literal in `deprecated` \
622-
value must be a string",
623-
lit.node.is_bytestr()
624-
),
625-
);
626-
} else {
627-
span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
604+
let meta = attr.meta().unwrap();
605+
depr = match &meta.node {
606+
MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
607+
MetaItemKind::NameValue(..) => {
608+
meta.value_str().map(|note| {
609+
Deprecation { since: None, note: Some(note) }
610+
})
611+
}
612+
MetaItemKind::List(list) => {
613+
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
614+
if item.is_some() {
615+
handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name()));
616+
return false
628617
}
618+
if let Some(v) = meta.value_str() {
619+
*item = Some(v);
620+
true
621+
} else {
622+
if let Some(lit) = meta.name_value_literal() {
623+
handle_errors(
624+
sess,
625+
lit.span,
626+
AttrError::UnsupportedLiteral(
627+
"literal in `deprecated` \
628+
value must be a string",
629+
lit.node.is_bytestr()
630+
),
631+
);
632+
} else {
633+
span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
634+
}
629635

630-
false
631-
}
632-
};
636+
false
637+
}
638+
};
633639

634-
let mut since = None;
635-
let mut note = None;
636-
for meta in metas {
637-
match &meta.node {
638-
NestedMetaItemKind::MetaItem(mi) => {
639-
match &*mi.name().as_str() {
640-
"since" => if !get(mi, &mut since) { continue 'outer },
641-
"note" => if !get(mi, &mut note) { continue 'outer },
642-
_ => {
643-
handle_errors(
644-
sess,
645-
meta.span,
646-
AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
647-
);
648-
continue 'outer
640+
let mut since = None;
641+
let mut note = None;
642+
for meta in list {
643+
match &meta.node {
644+
NestedMetaItemKind::MetaItem(mi) => {
645+
match &*mi.name().as_str() {
646+
"since" => if !get(mi, &mut since) { continue 'outer },
647+
"note" => if !get(mi, &mut note) { continue 'outer },
648+
_ => {
649+
handle_errors(
650+
sess,
651+
meta.span,
652+
AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
653+
);
654+
continue 'outer
655+
}
649656
}
650657
}
651-
}
652-
NestedMetaItemKind::Literal(lit) => {
653-
handle_errors(
654-
sess,
655-
lit.span,
656-
AttrError::UnsupportedLiteral(
657-
"item in `deprecated` must be a key/value pair",
658-
false,
659-
),
660-
);
661-
continue 'outer
658+
NestedMetaItemKind::Literal(lit) => {
659+
handle_errors(
660+
sess,
661+
lit.span,
662+
AttrError::UnsupportedLiteral(
663+
"item in `deprecated` must be a key/value pair",
664+
false,
665+
),
666+
);
667+
continue 'outer
668+
}
662669
}
663670
}
664-
}
665671

666-
Some(Deprecation {since: since, note: note})
667-
} else {
668-
Some(Deprecation{since: None, note: None})
669-
}
672+
Some(Deprecation { since, note })
673+
}
674+
};
670675
}
671676

672677
depr

src/libsyntax/attr/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ fn name_from_path(path: &Path) -> Name {
161161
}
162162

163163
impl Attribute {
164+
/// Returns `true` if the attribute's path matches the argument. If it matches, then the
165+
/// attribute is marked as used.
166+
///
167+
/// To check the attribute name without marking it used, use the `path` field directly.
164168
pub fn check_name(&self, name: &str) -> bool {
165169
let matches = self.path == name;
166170
if matches {

src/libsyntax/feature_gate.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1176,9 +1176,15 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
11761176
("stable", Whitelisted, template!(List: r#"feature = "name", since = "version""#), Ungated),
11771177
("unstable", Whitelisted, template!(List: r#"feature = "name", reason = "...", issue = "N""#),
11781178
Ungated),
1179-
("deprecated", Normal, template!(Word, List: r#"/*opt*/ since = "version",
1180-
/*opt*/ note = "reason"#,
1181-
NameValueStr: "reason"), Ungated),
1179+
("deprecated",
1180+
Normal,
1181+
template!(
1182+
Word,
1183+
List: r#"/*opt*/ since = "version", /*opt*/ note = "reason"#,
1184+
NameValueStr: "reason"
1185+
),
1186+
Ungated
1187+
),
11821188

11831189
("rustc_paren_sugar", Normal, template!(Word), Gated(Stability::Unstable,
11841190
"unboxed_closures",

src/test/rustdoc/deprecated.rs

+5
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ pub struct V;
2626
// 'Deprecated$'
2727
#[deprecated]
2828
pub struct W;
29+
30+
// @matches deprecated/struct.X.html '//*[@class="stab deprecated"]' \
31+
// 'Deprecated: shorthand reason$'
32+
#[deprecated = "shorthand reason"]
33+
pub struct X;

src/test/ui/deprecation/deprecation-sanity.rs

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ mod bogus_attribute_types_1 {
1515

1616
#[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
1717
fn f6() { }
18+
19+
#[deprecated(note = b"test")] //~ ERROR literal in `deprecated` value must be a string
20+
fn f7() { }
21+
22+
#[deprecated("test")] //~ ERROR item in `deprecated` must be a key/value pair
23+
fn f8() { }
1824
}
1925

2026
#[deprecated(since = "a", note = "b")]

src/test/ui/deprecation/deprecation-sanity.stderr

+16-4
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,31 @@ error[E0551]: incorrect meta item
2828
LL | #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
2929
| ^^^^^^^^
3030

31+
error[E0565]: literal in `deprecated` value must be a string
32+
--> $DIR/deprecation-sanity.rs:19:25
33+
|
34+
LL | #[deprecated(note = b"test")] //~ ERROR literal in `deprecated` value must be a string
35+
| ^^^^^^^ help: consider removing the prefix: `"test"`
36+
37+
error[E0565]: item in `deprecated` must be a key/value pair
38+
--> $DIR/deprecation-sanity.rs:22:18
39+
|
40+
LL | #[deprecated("test")] //~ ERROR item in `deprecated` must be a key/value pair
41+
| ^^^^^^
42+
3143
error[E0550]: multiple deprecated attributes
32-
--> $DIR/deprecation-sanity.rs:22:1
44+
--> $DIR/deprecation-sanity.rs:28:1
3345
|
3446
LL | fn multiple1() { } //~ ERROR multiple deprecated attributes
3547
| ^^^^^^^^^^^^^^^^^^
3648

3749
error[E0538]: multiple 'since' items
38-
--> $DIR/deprecation-sanity.rs:24:27
50+
--> $DIR/deprecation-sanity.rs:30:27
3951
|
4052
LL | #[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
4153
| ^^^^^^^^^^^
4254

43-
error: aborting due to 7 previous errors
55+
error: aborting due to 9 previous errors
4456

45-
Some errors occurred: E0538, E0541, E0550, E0551.
57+
Some errors occurred: E0538, E0541, E0550, E0551, E0565.
4658
For more information about an error, try `rustc --explain E0538`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[deprecated = b"test"] //~ ERROR attribute must be of the form
2+
fn foo() {}
3+
4+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: attribute must be of the form `#[deprecated]` or `#[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason)]` or `#[deprecated = "reason"]`
2+
--> $DIR/invalid-literal.rs:1:1
3+
|
4+
LL | #[deprecated = b"test"] //~ ERROR attribute must be of the form
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)