1
1
use rustc_attr_data_structures:: { AttributeKind , DeprecatedSince , Deprecation } ;
2
+ use rustc_feature:: { AttributeTemplate , template} ;
2
3
use rustc_span:: { Span , Symbol , sym} ;
3
4
4
5
use super :: util:: parse_version;
5
6
use super :: { AttributeOrder , OnDuplicate , SingleAttributeParser } ;
6
7
use crate :: context:: { AcceptContext , Stage } ;
7
8
use crate :: parser:: ArgParser ;
8
9
use crate :: session_diagnostics;
9
- use crate :: session_diagnostics:: UnsupportedLiteralReason ;
10
10
11
11
pub ( crate ) struct DeprecationParser ;
12
12
@@ -18,25 +18,18 @@ fn get<S: Stage>(
18
18
item : & Option < Symbol > ,
19
19
) -> Option < Symbol > {
20
20
if item. is_some ( ) {
21
- cx. emit_err ( session_diagnostics :: MultipleItem { span : param_span, item : name. to_string ( ) } ) ;
21
+ cx. duplicate_key ( param_span, name) ;
22
22
return None ;
23
23
}
24
24
if let Some ( v) = arg. name_value ( ) {
25
25
if let Some ( value_str) = v. value_as_str ( ) {
26
26
Some ( value_str)
27
27
} else {
28
- let lit = v. value_as_lit ( ) ;
29
- cx. emit_err ( session_diagnostics:: UnsupportedLiteral {
30
- span : v. value_span ,
31
- reason : UnsupportedLiteralReason :: DeprecatedString ,
32
- is_bytestr : lit. kind . is_bytestr ( ) ,
33
- start_point_span : cx. sess ( ) . source_map ( ) . start_point ( lit. span ) ,
34
- } ) ;
28
+ cx. expected_string_literal ( v. value_span , Some ( & v. value_as_lit ( ) ) ) ;
35
29
None
36
30
}
37
31
} else {
38
- // FIXME(jdonszelmann): suggestion?
39
- cx. emit_err ( session_diagnostics:: IncorrectMetaItem { span : param_span, suggestion : None } ) ;
32
+ cx. expected_name_value ( param_span, Some ( name) ) ;
40
33
None
41
34
}
42
35
}
@@ -45,6 +38,11 @@ impl<S: Stage> SingleAttributeParser<S> for DeprecationParser {
45
38
const PATH : & [ Symbol ] = & [ sym:: deprecated] ;
46
39
const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepFirst ;
47
40
const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: Error ;
41
+ const TEMPLATE : AttributeTemplate = template ! (
42
+ Word ,
43
+ List : r#"/*opt*/ since = "version", /*opt*/ note = "reason""# ,
44
+ NameValueStr : "reason"
45
+ ) ;
48
46
49
47
fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
50
48
let features = cx. features ( ) ;
@@ -55,57 +53,60 @@ impl<S: Stage> SingleAttributeParser<S> for DeprecationParser {
55
53
56
54
let is_rustc = features. staged_api ( ) ;
57
55
58
- if let Some ( value) = args. name_value ( )
59
- && let Some ( value_str) = value. value_as_str ( )
60
- {
61
- note = Some ( value_str)
62
- } else if let Some ( list) = args. list ( ) {
63
- for param in list. mixed ( ) {
64
- let param_span = param. span ( ) ;
65
- let Some ( param) = param. meta_item ( ) else {
66
- cx. emit_err ( session_diagnostics:: UnsupportedLiteral {
67
- span : param_span,
68
- reason : UnsupportedLiteralReason :: DeprecatedKvPair ,
69
- is_bytestr : false ,
70
- start_point_span : cx. sess ( ) . source_map ( ) . start_point ( param_span) ,
71
- } ) ;
72
- return None ;
73
- } ;
56
+ match args {
57
+ ArgParser :: NoArgs => {
58
+ // ok
59
+ }
60
+ ArgParser :: List ( list) => {
61
+ for param in list. mixed ( ) {
62
+ let Some ( param) = param. meta_item ( ) else {
63
+ cx. unexpected_literal ( param. span ( ) ) ;
64
+ return None ;
65
+ } ;
74
66
75
- let ident_name = param. path ( ) . word_sym ( ) ;
67
+ let ident_name = param. path ( ) . word_sym ( ) ;
76
68
77
- match ident_name {
78
- Some ( name @ sym:: since) => {
79
- since = Some ( get ( cx, name, param_span, param. args ( ) , & since) ?) ;
80
- }
81
- Some ( name @ sym:: note) => {
82
- note = Some ( get ( cx, name, param_span, param. args ( ) , & note) ?) ;
83
- }
84
- Some ( name @ sym:: suggestion) => {
85
- if !features. deprecated_suggestion ( ) {
86
- cx. emit_err ( session_diagnostics:: DeprecatedItemSuggestion {
87
- span : param_span,
88
- is_nightly : cx. sess ( ) . is_nightly_build ( ) ,
89
- details : ( ) ,
90
- } ) ;
69
+ match ident_name {
70
+ Some ( name @ sym:: since) => {
71
+ since = Some ( get ( cx, name, param. span ( ) , param. args ( ) , & since) ?) ;
72
+ }
73
+ Some ( name @ sym:: note) => {
74
+ note = Some ( get ( cx, name, param. span ( ) , param. args ( ) , & note) ?) ;
91
75
}
76
+ Some ( name @ sym:: suggestion) => {
77
+ if !features. deprecated_suggestion ( ) {
78
+ cx. emit_err ( session_diagnostics:: DeprecatedItemSuggestion {
79
+ span : param. span ( ) ,
80
+ is_nightly : cx. sess ( ) . is_nightly_build ( ) ,
81
+ details : ( ) ,
82
+ } ) ;
83
+ }
92
84
93
- suggestion = Some ( get ( cx, name, param_span, param. args ( ) , & suggestion) ?) ;
94
- }
95
- _ => {
96
- cx. emit_err ( session_diagnostics:: UnknownMetaItem {
97
- span : param_span,
98
- item : param. path ( ) . to_string ( ) ,
99
- expected : if features. deprecated_suggestion ( ) {
100
- & [ "since" , "note" , "suggestion" ]
101
- } else {
102
- & [ "since" , "note" ]
103
- } ,
104
- } ) ;
105
- return None ;
85
+ suggestion =
86
+ Some ( get ( cx, name, param. span ( ) , param. args ( ) , & suggestion) ?) ;
87
+ }
88
+ _ => {
89
+ cx. unknown_key (
90
+ param. span ( ) ,
91
+ param. path ( ) . to_string ( ) ,
92
+ if features. deprecated_suggestion ( ) {
93
+ & [ "since" , "note" , "suggestion" ]
94
+ } else {
95
+ & [ "since" , "note" ]
96
+ } ,
97
+ ) ;
98
+ return None ;
99
+ }
106
100
}
107
101
}
108
102
}
103
+ ArgParser :: NameValue ( v) => {
104
+ let Some ( value) = v. value_as_str ( ) else {
105
+ cx. expected_string_literal ( v. value_span , Some ( v. value_as_lit ( ) ) ) ;
106
+ return None ;
107
+ } ;
108
+ note = Some ( value) ;
109
+ }
109
110
}
110
111
111
112
let since = if let Some ( since) = since {
0 commit comments