about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorXiretza <xiretza@xiretza.xyz>2022-08-31 13:20:59 +0200
committerXiretza <xiretza@xiretza.xyz>2022-09-27 20:29:19 +0200
commit21b5194a3a0ff5179d4afb6886fc8816243574f0 (patch)
tree6499d6fb1ff080f3c826fa392318453eebdfd2bc /compiler/rustc_parse/src/parser
parent4d0519a4e75e16afe08ca6da36c65c9b7dfe5cee (diff)
downloadrust-21b5194a3a0ff5179d4afb6886fc8816243574f0.tar.gz
rust-21b5194a3a0ff5179d4afb6886fc8816243574f0.zip
Rework "inner attribute not permitted" errors
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs107
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs9
2 files changed, 58 insertions, 58 deletions
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 297f4964116..ee3f7dbbc39 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -5,25 +5,23 @@ use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::token::{self, Delimiter, Nonterminal};
 use rustc_ast_pretty::pprust;
-use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
+use rustc_errors::{error_code, fluent, Diagnostic, IntoDiagnostic, PResult};
 use rustc_span::{sym, BytePos, Span};
 use std::convert::TryInto;
 
 // Public for rustfmt usage
 #[derive(Debug)]
-pub enum InnerAttrPolicy<'a> {
+pub enum InnerAttrPolicy {
     Permitted,
-    Forbidden { reason: &'a str, saw_doc_comment: bool, prev_outer_attr_sp: Option<Span> },
+    Forbidden(Option<InnerAttrForbiddenReason>),
 }
 
-const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
-                                                     permitted in this context";
-
-pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPolicy::Forbidden {
-    reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG,
-    saw_doc_comment: false,
-    prev_outer_attr_sp: None,
-};
+#[derive(Clone, Copy, Debug)]
+pub enum InnerAttrForbiddenReason {
+    InCodeBlock,
+    AfterOuterDocComment { prev_doc_comment_span: Span },
+    AfterOuterAttribute { prev_outer_attr_sp: Span },
+}
 
 enum OuterAttributeType {
     DocComment,
@@ -42,17 +40,15 @@ impl<'a> Parser<'a> {
                 let prev_outer_attr_sp = outer_attrs.last().map(|attr| attr.span);
 
                 let inner_error_reason = if just_parsed_doc_comment {
-                    "an inner attribute is not permitted following an outer doc comment"
-                } else if prev_outer_attr_sp.is_some() {
-                    "an inner attribute is not permitted following an outer attribute"
+                    Some(InnerAttrForbiddenReason::AfterOuterDocComment {
+                        prev_doc_comment_span: prev_outer_attr_sp.unwrap(),
+                    })
+                } else if let Some(prev_outer_attr_sp) = prev_outer_attr_sp {
+                    Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp })
                 } else {
-                    DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
-                };
-                let inner_parse_policy = InnerAttrPolicy::Forbidden {
-                    reason: inner_error_reason,
-                    saw_doc_comment: just_parsed_doc_comment,
-                    prev_outer_attr_sp,
+                    None
                 };
+                let inner_parse_policy = InnerAttrPolicy::Forbidden(inner_error_reason);
                 just_parsed_doc_comment = false;
                 Some(self.parse_attribute(inner_parse_policy)?)
             } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
@@ -60,7 +56,7 @@ impl<'a> Parser<'a> {
                     let span = self.token.span;
                     let mut err = self.sess.span_diagnostic.struct_span_err_with_code(
                         span,
-                        "expected outer doc comment",
+                        fluent::parser::inner_doc_comment_not_permitted,
                         error_code!(E0753),
                     );
                     if let Some(replacement_span) = self.annotate_following_item_if_applicable(
@@ -71,13 +67,10 @@ impl<'a> Parser<'a> {
                             token::CommentKind::Block => OuterAttributeType::DocBlockComment,
                         },
                     ) {
-                        err.note(
-                            "inner doc comments like this (starting with `//!` or `/*!`) can \
-                            only appear before items",
-                        );
+                        err.note(fluent::parser::note);
                         err.span_suggestion_verbose(
                             replacement_span,
-                            "you might have meant to write a regular comment",
+                            fluent::parser::suggestion,
                             "",
                             rustc_errors::Applicability::MachineApplicable,
                         );
@@ -115,7 +108,7 @@ impl<'a> Parser<'a> {
     // Public for rustfmt usage.
     pub fn parse_attribute(
         &mut self,
-        inner_parse_policy: InnerAttrPolicy<'_>,
+        inner_parse_policy: InnerAttrPolicy,
     ) -> PResult<'a, ast::Attribute> {
         debug!(
             "parse_attribute: inner_parse_policy={:?} self.token={:?}",
@@ -179,21 +172,12 @@ impl<'a> Parser<'a> {
             ForceCollect::No,
         ) {
             Ok(Some(item)) => {
-                let attr_name = match attr_type {
-                    OuterAttributeType::Attribute => "attribute",
-                    _ => "doc comment",
-                };
-                err.span_label(
-                    item.span,
-                    &format!("the inner {} doesn't annotate this {}", attr_name, item.kind.descr()),
-                );
+                // FIXME(#100717)
+                err.set_arg("item", item.kind.descr());
+                err.span_label(item.span, fluent::parser::label_does_not_annotate_this);
                 err.span_suggestion_verbose(
                     replacement_span,
-                    &format!(
-                        "to annotate the {}, change the {} from inner to outer style",
-                        item.kind.descr(),
-                        attr_name
-                    ),
+                    fluent::parser::sugg_change_inner_to_outer,
                     match attr_type {
                         OuterAttributeType::Attribute => "",
                         OuterAttributeType::DocBlockComment => "*",
@@ -211,22 +195,33 @@ impl<'a> Parser<'a> {
         Some(replacement_span)
     }
 
-    pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) {
-        if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_outer_attr_sp } = policy {
-            let prev_outer_attr_note =
-                if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" };
-
-            let mut diag = self.struct_span_err(attr_sp, reason);
-
-            if let Some(prev_outer_attr_sp) = prev_outer_attr_sp {
-                diag.span_label(attr_sp, "not permitted following an outer attribute")
-                    .span_label(prev_outer_attr_sp, prev_outer_attr_note);
-            }
+    pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy) {
+        if let InnerAttrPolicy::Forbidden(reason) = policy {
+            let mut diag = match reason.as_ref().copied() {
+                Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span }) => {
+                    let mut diag = self.struct_span_err(
+                        attr_sp,
+                        fluent::parser::inner_attr_not_permitted_after_outer_doc_comment,
+                    );
+                    diag.span_label(attr_sp, fluent::parser::label_attr)
+                        .span_label(prev_doc_comment_span, fluent::parser::label_prev_doc_comment);
+                    diag
+                }
+                Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => {
+                    let mut diag = self.struct_span_err(
+                        attr_sp,
+                        fluent::parser::inner_attr_not_permitted_after_outer_attr,
+                    );
+                    diag.span_label(attr_sp, fluent::parser::label_attr)
+                        .span_label(prev_outer_attr_sp, fluent::parser::label_prev_attr);
+                    diag
+                }
+                Some(InnerAttrForbiddenReason::InCodeBlock) | None => {
+                    self.struct_span_err(attr_sp, fluent::parser::inner_attr_not_permitted)
+                }
+            };
 
-            diag.note(
-                "inner attributes, like `#![no_std]`, annotate the item enclosing them, and \
-                are usually found at the beginning of source files",
-            );
+            diag.note(fluent::parser::inner_attr_explanation);
             if self
                 .annotate_following_item_if_applicable(
                     &mut diag,
@@ -235,7 +230,7 @@ impl<'a> Parser<'a> {
                 )
                 .is_some()
             {
-                diag.note("outer attributes, like `#[test]`, annotate the item following them");
+                diag.note(fluent::parser::outer_attr_explanation);
             };
             diag.emit();
         }
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 155173f120c..a61e77b7c3b 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -1,4 +1,4 @@
-use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
+use super::attr::InnerAttrForbiddenReason;
 use super::diagnostics::AttemptLocalParseRecovery;
 use super::expr::LhsExpr;
 use super::pat::RecoverComma;
@@ -399,7 +399,12 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         let (attrs, block) = self.parse_inner_attrs_and_block()?;
         if let [.., last] = &*attrs {
-            self.error_on_forbidden_inner_attr(last.span, DEFAULT_INNER_ATTR_FORBIDDEN);
+            self.error_on_forbidden_inner_attr(
+                last.span,
+                super::attr::InnerAttrPolicy::Forbidden(Some(
+                    InnerAttrForbiddenReason::InCodeBlock,
+                )),
+            );
         }
         Ok(block)
     }