@@ -5,25 +5,23 @@ use rustc_ast as ast;
55use rustc_ast:: attr;
66use rustc_ast:: token:: { self , Delimiter , Nonterminal } ;
77use rustc_ast_pretty:: pprust;
8- use rustc_errors:: { error_code, Diagnostic , IntoDiagnostic , PResult } ;
8+ use rustc_errors:: { error_code, fluent , Diagnostic , IntoDiagnostic , PResult } ;
99use rustc_span:: { sym, BytePos , Span } ;
1010use std:: convert:: TryInto ;
1111
1212// Public for rustfmt usage
1313#[ derive( Debug ) ]
14- pub enum InnerAttrPolicy < ' a > {
14+ pub enum InnerAttrPolicy {
1515 Permitted ,
16- Forbidden { reason : & ' a str , saw_doc_comment : bool , prev_outer_attr_sp : Option < Span > } ,
16+ Forbidden ( Option < InnerAttrForbiddenReason > ) ,
1717}
1818
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+ }
2725
2826enum OuterAttributeType {
2927 DocComment ,
@@ -42,25 +40,23 @@ impl<'a> Parser<'a> {
4240 let prev_outer_attr_sp = outer_attrs. last ( ) . map ( |attr| attr. span ) ;
4341
4442 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 } )
4848 } 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
5550 } ;
51+ let inner_parse_policy = InnerAttrPolicy :: Forbidden ( inner_error_reason) ;
5652 just_parsed_doc_comment = false ;
5753 Some ( self . parse_attribute ( inner_parse_policy) ?)
5854 } else if let token:: DocComment ( comment_kind, attr_style, data) = self . token . kind {
5955 if attr_style != ast:: AttrStyle :: Outer {
6056 let span = self . token . span ;
6157 let mut err = self . sess . span_diagnostic . struct_span_err_with_code (
6258 span,
63- "expected outer doc comment" ,
59+ fluent :: parser :: inner_doc_comment_not_permitted ,
6460 error_code ! ( E0753 ) ,
6561 ) ;
6662 if let Some ( replacement_span) = self . annotate_following_item_if_applicable (
@@ -71,13 +67,10 @@ impl<'a> Parser<'a> {
7167 token:: CommentKind :: Block => OuterAttributeType :: DocBlockComment ,
7268 } ,
7369 ) {
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) ;
7871 err. span_suggestion_verbose (
7972 replacement_span,
80- "you might have meant to write a regular comment" ,
73+ fluent :: parser :: suggestion ,
8174 "" ,
8275 rustc_errors:: Applicability :: MachineApplicable ,
8376 ) ;
@@ -115,7 +108,7 @@ impl<'a> Parser<'a> {
115108 // Public for rustfmt usage.
116109 pub fn parse_attribute (
117110 & mut self ,
118- inner_parse_policy : InnerAttrPolicy < ' _ > ,
111+ inner_parse_policy : InnerAttrPolicy ,
119112 ) -> PResult < ' a , ast:: Attribute > {
120113 debug ! (
121114 "parse_attribute: inner_parse_policy={:?} self.token={:?}" ,
@@ -179,21 +172,12 @@ impl<'a> Parser<'a> {
179172 ForceCollect :: No ,
180173 ) {
181174 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) ;
190178 err. span_suggestion_verbose (
191179 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,
197181 match attr_type {
198182 OuterAttributeType :: Attribute => "" ,
199183 OuterAttributeType :: DocBlockComment => "*" ,
@@ -211,22 +195,33 @@ impl<'a> Parser<'a> {
211195 Some ( replacement_span)
212196 }
213197
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+ } ;
225223
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) ;
230225 if self
231226 . annotate_following_item_if_applicable (
232227 & mut diag,
@@ -235,7 +230,7 @@ impl<'a> Parser<'a> {
235230 )
236231 . is_some ( )
237232 {
238- diag. note ( "outer attributes, like `#[test]`, annotate the item following them" ) ;
233+ diag. note ( fluent :: parser :: outer_attr_explanation ) ;
239234 } ;
240235 diag. emit ( ) ;
241236 }
0 commit comments