]> git.lizzy.rs Git - rust.git/commitdiff
migrate naked_functions.rs to translateable diagnostics
authorNathan Stocks <cleancut@github.com>
Tue, 27 Sep 2022 15:44:56 +0000 (09:44 -0600)
committerNathan Stocks <cleancut@github.com>
Fri, 7 Oct 2022 19:19:27 +0000 (13:19 -0600)
compiler/rustc_error_messages/locales/en-US/passes.ftl
compiler/rustc_passes/src/errors.rs
compiler/rustc_passes/src/naked_functions.rs

index 3dc4204f986a436fb412cd7ad11f6202ca1817be..ddc8f149d134c02aa81ee991b62b1ccec31b53fc 100644 (file)
@@ -467,3 +467,31 @@ passes_unlabeled_in_labeled_block =
 passes_unlabeled_cf_in_while_condition =
     `break` or `continue` with no label in the condition of a `while` loop
     .label = unlabeled `{$cf_type}` in the condition of a `while` loop
+
+passes_cannot_inline_naked_function =
+    naked functions cannot be inlined
+
+passes_undefined_naked_function_abi =
+    Rust ABI is unsupported in naked functions
+
+passes_no_patterns =
+    patterns not allowed in naked function parameters
+
+passes_params_not_allowed =
+    referencing function parameters is not allowed in naked functions
+    .help = follow the calling convention in asm block to use parameters
+
+passes_naked_functions_asm_block =
+    naked functions must contain a single asm block
+    .label_multiple_asm = multiple asm blocks are unsupported in naked functions
+    .label_non_asm = non-asm is unsupported in naked functions
+
+passes_naked_functions_operands =
+    only `const` and `sym` operands are supported in naked functions
+
+passes_naked_functions_asm_options =
+    asm options unsupported in naked functions: {$unsupported_options}
+
+passes_naked_functions_must_use_noreturn =
+    asm in naked functions must use `noreturn` option
+    .suggestion = consider specifying that the asm block is responsible for returning from the function
index fcbcc298bd5b7fa05efe8ba3213d5928ded8f66c..fd79c54cdd7b0526f211ed31fd4b839d2402b438 100644 (file)
@@ -987,3 +987,79 @@ pub struct UnlabeledCfInWhileCondition<'a> {
     pub span: Span,
     pub cf_type: &'a str,
 }
+
+#[derive(Diagnostic)]
+#[diag(passes::cannot_inline_naked_function)]
+pub struct CannotInlineNakedFunction {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(passes::undefined_naked_function_abi)]
+pub struct UndefinedNakedFunctionAbi;
+
+#[derive(Diagnostic)]
+#[diag(passes::no_patterns)]
+pub struct NoPatterns {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(passes::params_not_allowed)]
+#[help]
+pub struct ParamsNotAllowed {
+    #[primary_span]
+    pub span: Span,
+}
+
+pub struct NakedFunctionsAsmBlock {
+    pub span: Span,
+    pub multiple_asms: Vec<Span>,
+    pub non_asms: Vec<Span>,
+}
+
+impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock {
+    fn into_diagnostic(
+        self,
+        handler: &rustc_errors::Handler,
+    ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+        let mut diag = handler.struct_span_err_with_code(
+            self.span,
+            rustc_errors::fluent::passes::naked_functions_asm_block,
+            error_code!(E0787),
+        );
+        for span in self.multiple_asms.iter() {
+            diag.span_label(*span, rustc_errors::fluent::passes::label_multiple_asm);
+        }
+        for span in self.non_asms.iter() {
+            diag.span_label(*span, rustc_errors::fluent::passes::label_non_asm);
+        }
+        diag
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(passes::naked_functions_operands, code = "E0787")]
+pub struct NakedFunctionsOperands {
+    #[primary_span]
+    pub unsupported_operands: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(passes::naked_functions_asm_options, code = "E0787")]
+pub struct NakedFunctionsAsmOptions {
+    #[primary_span]
+    pub span: Span,
+    pub unsupported_options: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(passes::naked_functions_must_use_noreturn, code = "E0787")]
+pub struct NakedFunctionsMustUseNoreturn {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = ", options(noreturn)", applicability = "machine-applicable")]
+    pub last_span: Span,
+}
index 2690be66c21e5ae8456dfad9330dfda967c574d7..acc54e7e11006885c3eee899c05fba4a44252295 100644 (file)
@@ -1,7 +1,6 @@
 //! Checks validity of naked functions.
 
 use rustc_ast::InlineAsmOptions;
-use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
+use crate::errors::{
+    CannotInlineNakedFunction, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
+    NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
+    UndefinedNakedFunctionAbi,
+};
+
 pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_naked_functions, ..*providers };
 }
@@ -56,7 +61,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
 fn check_inline(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     let attrs = tcx.get_attrs(def_id.to_def_id(), sym::inline);
     for attr in attrs {
-        tcx.sess.struct_span_err(attr.span, "naked functions cannot be inlined").emit();
+        tcx.sess.emit_err(CannotInlineNakedFunction { span: attr.span });
     }
 }
 
@@ -65,12 +70,11 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) {
     if abi == Abi::Rust {
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
         let span = tcx.def_span(def_id);
-        tcx.struct_span_lint_hir(
+        tcx.emit_spanned_lint(
             UNDEFINED_NAKED_FUNCTION_ABI,
             hir_id,
             span,
-            "Rust ABI is unsupported in naked functions",
-            |lint| lint,
+            UndefinedNakedFunctionAbi,
         );
     }
 }
@@ -82,12 +86,7 @@ fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
             hir::PatKind::Wild
             | hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, _, None) => {}
             _ => {
-                tcx.sess
-                    .struct_span_err(
-                        param.pat.span,
-                        "patterns not allowed in naked function parameters",
-                    )
-                    .emit();
+                tcx.sess.emit_err(NoPatterns { span: param.pat.span });
             }
         }
     }
@@ -117,14 +116,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         )) = expr.kind
         {
             if self.params.contains(var_hir_id) {
-                self.tcx
-                    .sess
-                    .struct_span_err(
-                        expr.span,
-                        "referencing function parameters is not allowed in naked functions",
-                    )
-                    .help("follow the calling convention in asm block to use parameters")
-                    .emit();
+                self.tcx.sess.emit_err(ParamsNotAllowed { span: expr.span });
                 return;
             }
         }
@@ -139,26 +131,21 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<
     if let [(ItemKind::Asm | ItemKind::Err, _)] = this.items[..] {
         // Ok.
     } else {
-        let mut diag = struct_span_err!(
-            tcx.sess,
-            tcx.def_span(def_id),
-            E0787,
-            "naked functions must contain a single asm block"
-        );
-
         let mut must_show_error = false;
         let mut has_asm = false;
         let mut has_err = false;
+        let mut multiple_asms = vec![];
+        let mut non_asms = vec![];
         for &(kind, span) in &this.items {
             match kind {
                 ItemKind::Asm if has_asm => {
                     must_show_error = true;
-                    diag.span_label(span, "multiple asm blocks are unsupported in naked functions");
+                    multiple_asms.push(span);
                 }
                 ItemKind::Asm => has_asm = true,
                 ItemKind::NonAsm => {
                     must_show_error = true;
-                    diag.span_label(span, "non-asm is unsupported in naked functions");
+                    non_asms.push(span);
                 }
                 ItemKind::Err => has_err = true,
             }
@@ -168,9 +155,11 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<
         // errors, then don't show an additional error. This allows for appending/prepending
         // `compile_error!("...")` statements and reduces error noise.
         if must_show_error || !has_err {
-            diag.emit();
-        } else {
-            diag.cancel();
+            tcx.sess.emit_err(NakedFunctionsAsmBlock {
+                span: tcx.def_span(def_id),
+                multiple_asms,
+                non_asms,
+            });
         }
     }
 }
@@ -251,13 +240,7 @@ fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
             })
             .collect();
         if !unsupported_operands.is_empty() {
-            struct_span_err!(
-                self.tcx.sess,
-                unsupported_operands,
-                E0787,
-                "only `const` and `sym` operands are supported in naked functions",
-            )
-            .emit();
+            self.tcx.sess.emit_err(NakedFunctionsOperands { unsupported_operands });
         }
 
         let unsupported_options: Vec<&'static str> = [
@@ -273,14 +256,10 @@ fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
         .collect();
 
         if !unsupported_options.is_empty() {
-            struct_span_err!(
-                self.tcx.sess,
+            self.tcx.sess.emit_err(NakedFunctionsAsmOptions {
                 span,
-                E0787,
-                "asm options unsupported in naked functions: {}",
-                unsupported_options.join(", ")
-            )
-            .emit();
+                unsupported_options: unsupported_options.join(", "),
+            });
         }
 
         if !asm.options.contains(InlineAsmOptions::NORETURN) {
@@ -290,20 +269,7 @@ fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
                 .map_or_else(|| asm.template_strs.last().unwrap().2, |op| op.1)
                 .shrink_to_hi();
 
-            struct_span_err!(
-                self.tcx.sess,
-                span,
-                E0787,
-                "asm in naked functions must use `noreturn` option"
-            )
-            .span_suggestion(
-                last_span,
-                "consider specifying that the asm block is responsible \
-                for returning from the function",
-                ", options(noreturn)",
-                Applicability::MachineApplicable,
-            )
-            .emit();
+            self.tcx.sess.emit_err(NakedFunctionsMustUseNoreturn { span, last_span });
         }
     }
 }