@@ -5,25 +5,23 @@ use rustc_ast as ast;
5
5
use rustc_ast:: attr;
6
6
use rustc_ast:: token:: { self , Delimiter , Nonterminal } ;
7
7
use rustc_ast_pretty:: pprust;
8
- use rustc_errors:: { error_code, Diagnostic , IntoDiagnostic , PResult } ;
8
+ use rustc_errors:: { error_code, fluent , Diagnostic , IntoDiagnostic , PResult } ;
9
9
use rustc_span:: { sym, BytePos , Span } ;
10
10
use std:: convert:: TryInto ;
11
11
12
12
// Public for rustfmt usage
13
13
#[ derive( Debug ) ]
14
- pub enum InnerAttrPolicy < ' a > {
14
+ pub enum InnerAttrPolicy {
15
15
Permitted ,
16
- Forbidden { reason : & ' a str , saw_doc_comment : bool , prev_outer_attr_sp : Option < Span > } ,
16
+ Forbidden ( Option < InnerAttrForbiddenReason > ) ,
17
17
}
18
18
19
- const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG : & str = "an inner attribute is not \
20
- permitted in this context";
21
-
22
- pub ( super ) const DEFAULT_INNER_ATTR_FORBIDDEN : InnerAttrPolicy < ' _ > = InnerAttrPolicy :: Forbidden {
23
- reason : DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG ,
24
- saw_doc_comment : false ,
25
- prev_outer_attr_sp : None ,
26
- } ;
19
+ #[ derive( Clone , Copy , Debug ) ]
20
+ pub enum InnerAttrForbiddenReason {
21
+ InCodeBlock ,
22
+ AfterOuterDocComment { prev_doc_comment_span : Span } ,
23
+ AfterOuterAttribute { prev_outer_attr_sp : Span } ,
24
+ }
27
25
28
26
enum OuterAttributeType {
29
27
DocComment ,
@@ -42,25 +40,23 @@ impl<'a> Parser<'a> {
42
40
let prev_outer_attr_sp = outer_attrs. last ( ) . map ( |attr| attr. span ) ;
43
41
44
42
let inner_error_reason = if just_parsed_doc_comment {
45
- "an inner attribute is not permitted following an outer doc comment"
46
- } else if prev_outer_attr_sp. is_some ( ) {
47
- "an inner attribute is not permitted following an outer attribute"
43
+ Some ( InnerAttrForbiddenReason :: AfterOuterDocComment {
44
+ prev_doc_comment_span : prev_outer_attr_sp. unwrap ( ) ,
45
+ } )
46
+ } else if let Some ( prev_outer_attr_sp) = prev_outer_attr_sp {
47
+ Some ( InnerAttrForbiddenReason :: AfterOuterAttribute { prev_outer_attr_sp } )
48
48
} else {
49
- DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
50
- } ;
51
- let inner_parse_policy = InnerAttrPolicy :: Forbidden {
52
- reason : inner_error_reason,
53
- saw_doc_comment : just_parsed_doc_comment,
54
- prev_outer_attr_sp,
49
+ None
55
50
} ;
51
+ let inner_parse_policy = InnerAttrPolicy :: Forbidden ( inner_error_reason) ;
56
52
just_parsed_doc_comment = false ;
57
53
Some ( self . parse_attribute ( inner_parse_policy) ?)
58
54
} else if let token:: DocComment ( comment_kind, attr_style, data) = self . token . kind {
59
55
if attr_style != ast:: AttrStyle :: Outer {
60
56
let span = self . token . span ;
61
57
let mut err = self . sess . span_diagnostic . struct_span_err_with_code (
62
58
span,
63
- "expected outer doc comment" ,
59
+ fluent :: parser :: inner_doc_comment_not_permitted ,
64
60
error_code ! ( E0753 ) ,
65
61
) ;
66
62
if let Some ( replacement_span) = self . annotate_following_item_if_applicable (
@@ -71,13 +67,10 @@ impl<'a> Parser<'a> {
71
67
token:: CommentKind :: Block => OuterAttributeType :: DocBlockComment ,
72
68
} ,
73
69
) {
74
- err. note (
75
- "inner doc comments like this (starting with `//!` or `/*!`) can \
76
- only appear before items",
77
- ) ;
70
+ err. note ( fluent:: parser:: note) ;
78
71
err. span_suggestion_verbose (
79
72
replacement_span,
80
- "you might have meant to write a regular comment" ,
73
+ fluent :: parser :: suggestion ,
81
74
"" ,
82
75
rustc_errors:: Applicability :: MachineApplicable ,
83
76
) ;
@@ -115,7 +108,7 @@ impl<'a> Parser<'a> {
115
108
// Public for rustfmt usage.
116
109
pub fn parse_attribute (
117
110
& mut self ,
118
- inner_parse_policy : InnerAttrPolicy < ' _ > ,
111
+ inner_parse_policy : InnerAttrPolicy ,
119
112
) -> PResult < ' a , ast:: Attribute > {
120
113
debug ! (
121
114
"parse_attribute: inner_parse_policy={:?} self.token={:?}" ,
@@ -179,21 +172,12 @@ impl<'a> Parser<'a> {
179
172
ForceCollect :: No ,
180
173
) {
181
174
Ok ( Some ( item) ) => {
182
- let attr_name = match attr_type {
183
- OuterAttributeType :: Attribute => "attribute" ,
184
- _ => "doc comment" ,
185
- } ;
186
- err. span_label (
187
- item. span ,
188
- & format ! ( "the inner {} doesn't annotate this {}" , attr_name, item. kind. descr( ) ) ,
189
- ) ;
175
+ // FIXME(#100717)
176
+ err. set_arg ( "item" , item. kind . descr ( ) ) ;
177
+ err. span_label ( item. span , fluent:: parser:: label_does_not_annotate_this) ;
190
178
err. span_suggestion_verbose (
191
179
replacement_span,
192
- & format ! (
193
- "to annotate the {}, change the {} from inner to outer style" ,
194
- item. kind. descr( ) ,
195
- attr_name
196
- ) ,
180
+ fluent:: parser:: sugg_change_inner_to_outer,
197
181
match attr_type {
198
182
OuterAttributeType :: Attribute => "" ,
199
183
OuterAttributeType :: DocBlockComment => "*" ,
@@ -211,22 +195,33 @@ impl<'a> Parser<'a> {
211
195
Some ( replacement_span)
212
196
}
213
197
214
- pub ( super ) fn error_on_forbidden_inner_attr ( & self , attr_sp : Span , policy : InnerAttrPolicy < ' _ > ) {
215
- if let InnerAttrPolicy :: Forbidden { reason, saw_doc_comment, prev_outer_attr_sp } = policy {
216
- let prev_outer_attr_note =
217
- if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" } ;
218
-
219
- let mut diag = self . struct_span_err ( attr_sp, reason) ;
220
-
221
- if let Some ( prev_outer_attr_sp) = prev_outer_attr_sp {
222
- diag. span_label ( attr_sp, "not permitted following an outer attribute" )
223
- . span_label ( prev_outer_attr_sp, prev_outer_attr_note) ;
224
- }
198
+ pub ( super ) fn error_on_forbidden_inner_attr ( & self , attr_sp : Span , policy : InnerAttrPolicy ) {
199
+ if let InnerAttrPolicy :: Forbidden ( reason) = policy {
200
+ let mut diag = match reason. as_ref ( ) . copied ( ) {
201
+ Some ( InnerAttrForbiddenReason :: AfterOuterDocComment { prev_doc_comment_span } ) => {
202
+ let mut diag = self . struct_span_err (
203
+ attr_sp,
204
+ fluent:: parser:: inner_attr_not_permitted_after_outer_doc_comment,
205
+ ) ;
206
+ diag. span_label ( attr_sp, fluent:: parser:: label_attr)
207
+ . span_label ( prev_doc_comment_span, fluent:: parser:: label_prev_doc_comment) ;
208
+ diag
209
+ }
210
+ Some ( InnerAttrForbiddenReason :: AfterOuterAttribute { prev_outer_attr_sp } ) => {
211
+ let mut diag = self . struct_span_err (
212
+ attr_sp,
213
+ fluent:: parser:: inner_attr_not_permitted_after_outer_attr,
214
+ ) ;
215
+ diag. span_label ( attr_sp, fluent:: parser:: label_attr)
216
+ . span_label ( prev_outer_attr_sp, fluent:: parser:: label_prev_attr) ;
217
+ diag
218
+ }
219
+ Some ( InnerAttrForbiddenReason :: InCodeBlock ) | None => {
220
+ self . struct_span_err ( attr_sp, fluent:: parser:: inner_attr_not_permitted)
221
+ }
222
+ } ;
225
223
226
- diag. note (
227
- "inner attributes, like `#![no_std]`, annotate the item enclosing them, and \
228
- are usually found at the beginning of source files",
229
- ) ;
224
+ diag. note ( fluent:: parser:: inner_attr_explanation) ;
230
225
if self
231
226
. annotate_following_item_if_applicable (
232
227
& mut diag,
@@ -235,7 +230,7 @@ impl<'a> Parser<'a> {
235
230
)
236
231
. is_some ( )
237
232
{
238
- diag. note ( "outer attributes, like `#[test]`, annotate the item following them" ) ;
233
+ diag. note ( fluent :: parser :: outer_attr_explanation ) ;
239
234
} ;
240
235
diag. emit ( ) ;
241
236
}
0 commit comments